Skip to content

MapBufferBuilder: fix size_t→int32 partial-write in putString/putMapBuffer length encoding#56525

Closed
meta-yaohway wants to merge 1 commit intofacebook:mainfrom
meta-yaohway:export-D100376322
Closed

MapBufferBuilder: fix size_t→int32 partial-write in putString/putMapBuffer length encoding#56525
meta-yaohway wants to merge 1 commit intofacebook:mainfrom
meta-yaohway:export-D100376322

Conversation

@meta-yaohway
Copy link
Copy Markdown
Contributor

Summary:
The MapBuffer wire format encodes lengths and offsets as int32_t (MapBuffer::getString / getMapBuffer read them as *reinterpret_cast<const int32_t*>(...)). But in putString and putMapBuffer:

auto strSize = value.size();                               // size_t — 8 bytes on 64-bit
memcpy(dynamicData_.data() + offset, &strSize, INT_SIZE);  // copies first 4 of 8 bytes

auto deduces size_t from .size(), and memcpy(&size_t_var, ..., 4) writes only the first 4 bytes of an 8-byte object:

  • little-endian: writes the low 4 bytes — silent truncation if size > UINT32_MAX
  • big-endian: writes the high 4 bytes — encodes zero for normal sizes, producing a corrupt buffer the reader then trusts

putMapBufferList already had the correct pattern: auto offset = static_cast<int32_t>(dynamicData_.size()). This diff applies that same explicit static_cast<int32_t> to putString (strSize, offset) and putMapBuffer (mapBufferSize, offset) so the value being memcpy'd is exactly INT_SIZE bytes wide.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D100376322

…uffer length encoding

Summary:
The MapBuffer wire format encodes lengths and offsets as `int32_t` (`MapBuffer::getString` / `getMapBuffer` read them as `*reinterpret_cast<const int32_t*>(...)`). But in `putString` and `putMapBuffer`:

```cpp
auto strSize = value.size();                               // size_t — 8 bytes on 64-bit
memcpy(dynamicData_.data() + offset, &strSize, INT_SIZE);  // copies first 4 of 8 bytes
```

`auto` deduces `size_t` from `.size()`, and `memcpy(&size_t_var, ..., 4)` writes only the **first 4 bytes** of an 8-byte object:
- **little-endian:** writes the low 4 bytes — silent truncation if size > UINT32_MAX
- **big-endian:** writes the high 4 bytes — encodes **zero** for normal sizes, producing a corrupt buffer the reader then trusts

`putMapBufferList` already had the correct pattern: `auto offset = static_cast<int32_t>(dynamicData_.size())`. This diff applies that same explicit `static_cast<int32_t>` to `putString` (`strSize`, `offset`) and `putMapBuffer` (`mapBufferSize`, `offset`) so the value being `memcpy`'d is exactly `INT_SIZE` bytes wide.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D100376322
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Apr 21, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented Apr 21, 2026

@meta-yaohway has exported this pull request. If you are a Meta employee, you can view the originating Diff in D100376322.

@react-native-bot
Copy link
Copy Markdown
Collaborator

This pull request was successfully merged by @meta-yaohway in b111c0e

When will my fix make it into a release? | How to file a pick request?

@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented Apr 21, 2026

This pull request has been merged in b111c0e.

@facebook-github-tools facebook-github-tools Bot added the Merged This PR has been merged. label Apr 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged This PR has been merged. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants