)]}'
{
  "commit": "5eb190f00005b8dd1aa4f7ab2db9f01a39e3c76d",
  "tree": "532ad02fd41fba41587e6a919c12c913a9d570b5",
  "parents": [
    "f58d5768f1fd0df9f71aa6ae5f63645e2637c31f"
  ],
  "author": {
    "name": "Artyom Palvelev",
    "email": "15948033+artyompal@users.noreply.github.com",
    "time": "Fri Nov 06 23:15:33 2026"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Fri Nov 06 23:15:33 2026"
  },
  "message": "rust: fix 64-bit scalar wire-format alignment on 32-bit targets in Push::alignment (#9465)\n\nIn the FlatBuffers binary wire format specification, every scalar field is\naligned to its own byte size (`1`, `2`, `4`, or `8` bytes), regardless of the\nhost CPU architecture. Both the `flatc` schema compiler (when computing table\n`max_align` and struct field offsets) and the C++ `FlatBufferBuilder::Align` /\n`PushElement` implementation align 64-bit scalars (`u64`, `i64`, `f64`) to 8\nbytes on all architectures.\n\nHowever, in the Rust `flatbuffers` crate (`rust/flatbuffers/src/push.rs`), the\n`Push` trait provides a default implementation:\n\n```rust\nfn alignment() -\u003e PushAlignment {\n    PushAlignment::new(align_of::\u003cSelf::Output\u003e())\n}\n```\n\nAnd `impl_push_for_endian_scalar!` did not override `Push::alignment()`,\ninheriting `core::mem::align_of::\u003cT\u003e()` for all primitive scalar types (`bool`,\n`u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `f32`, `f64`).\n\nOn 64-bit targets (`x86_64`, `aarch64`) and 32-bit ARM (`armv7`),\n`align_of::\u003cu64\u003e() \u003d\u003d 8`, so `align_of::\u003cT\u003e()` happens to equal `size_of::\u003cT\u003e()`.\nOn 32-bit x86 (`i686`, System V i386 ABI), however, the host ABI alignment of\n64-bit scalars (`u64`, `i64`, `f64`) is **4 bytes** (`align_of::\u003cu64\u003e() \u003d\u003d 4`),\nwhile their FlatBuffer wire-format size and required wire alignment is **8\nbytes** (`size_of::\u003cu64\u003e() \u003d\u003d 8`).\n\nAs a consequence, on 32-bit x86 (`i686`):\n1. `FlatBufferBuilder::push::\u003cu64 / i64 / f64\u003e` only aligns the builder\u0027s cursor\n   and tracks `min_align` to 4 bytes instead of 8 bytes when writing 64-bit\n   table fields or vectors of 64-bit scalars.\n2. When a table containing a 64-bit scalar field (`uint64`, `int64`, `double`)\n   is serialized on `i686`, the field can be placed at a buffer offset that is\n   4-byte aligned but not 8-byte aligned.\n3. When the resulting FlatBuffer is verified by C++ `flatbuffers::Verifier`\n   (which checks `VerifyField\u003cuint64_t\u003e` with `sizeof(uint64_t) \u003d\u003d 8` alignment\n   when `FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE` / alignment checks are active)\n   or transferred to a 64-bit reader, verification fails or unaligned 64-bit\n   reads occur.\n\nFix `impl_push_for_endian_scalar!` to explicitly implement `Push::alignment()`\nusing `size_of::\u003c$ty\u003e()` so that all endian scalar types always use their\nwire-format byte size as their FlatBuffer alignment across all target\narchitectures.",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "20bacd8e2e5c58d80d54424818c5bd50c976d7cb",
      "old_mode": 33188,
      "old_path": "rust/flatbuffers/src/push.rs",
      "new_id": "59d16bea693c0d9d234b823106a3d98d4ca69b37",
      "new_mode": 33188,
      "new_path": "rust/flatbuffers/src/push.rs"
    }
  ]
}
