summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2018-03-15 23:08:18 -0700
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2018-03-15 23:10:10 -0700
commit9540016f6d9e56bc02cc98218c930e00efd3f67c (patch)
tree271d302a5d2521fe61796a18eda326b76498b657
parent15fdb838c7361bad786098a05745edcd61c47de2 (diff)
ubsan: Fix type mismatch for xml_extra_buffer in compact mode
We were using allocate_memory to allocate struct xml_extra_buffer that contains pointers; with compact mode, this allocation can be misaligned by 4b with 8b pointers; fix this by manually realigning the pointer.
-rw-r--r--src/pugixml.cpp8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 94dca48..f4c1af1 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -6076,11 +6076,17 @@ namespace pugi
// get extra buffer element (we'll store the document fragment buffer there so that we can deallocate it later)
impl::xml_memory_page* page = 0;
- impl::xml_extra_buffer* extra = static_cast<impl::xml_extra_buffer*>(doc->allocate_memory(sizeof(impl::xml_extra_buffer), page));
+ impl::xml_extra_buffer* extra = static_cast<impl::xml_extra_buffer*>(doc->allocate_memory(sizeof(impl::xml_extra_buffer) + sizeof(void*), page));
(void)page;
if (!extra) return impl::make_parse_result(status_out_of_memory);
+ #ifdef PUGIXML_COMPACT
+ // align the memory block to a pointer boundary; this is required for compact mode where memory allocations are only 4b aligned
+ // note that this requires up to sizeof(void*)-1 additional memory, which the allocation above takes into account
+ extra = reinterpret_cast<impl::xml_extra_buffer*>((reinterpret_cast<uintptr_t>(extra) + (sizeof(void*) - 1)) & ~(sizeof(void*) - 1));
+ #endif
+
// add extra buffer to the list
extra->buffer = 0;
extra->next = doc->extra_buffers;