From 47aab7823387b777dfd0e9393fc81b05a288b18f Mon Sep 17 00:00:00 2001
From: Evan Wallace <evan.exe@gmail.com>
Date: Thu, 2 Jul 2015 14:05:45 -0700
Subject: [PATCH] Round up allocation size to avoid misalignment (issue #226)

Before this change, requesting a large initial allocation could cause the
backing store to grow to an unaligned size. Since memory inside vector_downward
is relative to the end of the buffer, this then caused all memory in the buffer
to be misaligned and also misaligns any further loads and stores. Misaligned
loads and stores are undefined behavior and don't work in environments such as
emscripten (a JavaScript to C++ compiler).
---
 include/flatbuffers/flatbuffers.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h
index 0ae297b3..0b9cf585 100644
--- a/include/flatbuffers/flatbuffers.h
+++ b/include/flatbuffers/flatbuffers.h
@@ -416,7 +416,10 @@ class vector_downward {
   uint8_t *make_space(size_t len) {
     if (len > static_cast<size_t>(cur_ - buf_)) {
       auto old_size = size();
+      auto largest_align = AlignOf<largest_scalar_t>();
       reserved_ += std::max(len, growth_policy(reserved_));
+      // Round up to avoid undefined behavior from unaligned loads and stores.
+      reserved_ = (reserved_ + (largest_align - 1)) & ~(largest_align - 1);
       auto new_buf = allocator_.allocate(reserved_);
       auto new_cur = new_buf + reserved_ - old_size;
       memcpy(new_cur, cur_, old_size);
-- 
GitLab