From e50672cf37d4e071a9ab012b4d72a3dc62f1f817 Mon Sep 17 00:00:00 2001
From: Arseny Kapoulkine <arseny.kapoulkine@gmail.com>
Date: Fri, 16 Mar 2018 21:25:12 -0700
Subject: [PATCH] ubsan: Fix undefined behavior for signed left shift in
 compact mode

We were using << compact_alignment_log2 instead of * compact_alignment
for symmetry with the encoding where >> is crucial to keep code fast and
round to negative infinity.

For decoding, the results are the same and any reasonable compiler
should convert *4 into <<2 so just use a multiplication - that doesn't
trigger UB on negative numbers.
---
 src/pugixml.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index f4c1af12..bf3346b7 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -852,7 +852,7 @@ PUGI__NS_BEGIN
 				{
 					uintptr_t base = reinterpret_cast<uintptr_t>(this) & ~(compact_alignment - 1);
 
-					return reinterpret_cast<T*>(base + ((_data - 1 + start) << compact_alignment_log2));
+					return reinterpret_cast<T*>(base + (_data - 1 + start) * compact_alignment);
 				}
 				else
 					return compact_get_value<header_offset, T>(this);
@@ -930,7 +930,7 @@ PUGI__NS_BEGIN
 				{
 					uintptr_t base = reinterpret_cast<uintptr_t>(this) & ~(compact_alignment - 1);
 
-					return reinterpret_cast<T*>(base + ((_data - 1 - 65533) << compact_alignment_log2));
+					return reinterpret_cast<T*>(base + (_data - 1 - 65533) * compact_alignment);
 				}
 				else if (_data == 65534)
 					return static_cast<T*>(compact_get_page(this, header_offset)->compact_shared_parent);
-- 
GitLab