Skip to content

Afonsojanu fix/ext32 uint32 max length overflow - #1185

Merged
redboltz merged 3 commits into
msgpack:c_masterfrom
redboltz:afonsojanu-fix/ext32-uint32-max-length-overflow
Sep 5, 2026
Merged

Afonsojanu fix/ext32 uint32 max length overflow#1185
redboltz merged 3 commits into
msgpack:c_masterfrom
redboltz:afonsojanu-fix/ext32-uint32-max-length-overflow

Conversation

@redboltz

@redboltz redboltz commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

No description provided.

afonsojanu and others added 3 commits September 3, 2026 18:56
The C unpacker's internal "trail" bookkeeping combines an ext value's
type byte with its data into a single byte count by adding 1 to the
length read off the wire. For ext8/ext16 that addition stays well
inside a 32-bit range, but ext32's length field can legitimately be
the full UINT32_MAX, and tmp + 1 done in 32-bit arithmetic wraps
around to 0. The parser then treats the object as a zero-length ext
and immediately errors out through template_callback_ext's l == 0
check, so any ext exactly at the wire format's own maximum size fails
to unpack with MSGPACK_UNPACK_PARSE_ERROR even though it's a
perfectly valid encoding.

Widened the trail field (and the str/bin/ext callback length
parameter that ends up receiving it) from unsigned int to size_t, and
cast the ext32 length to size_t before adding 1 so the addition
itself doesn't wrap on a 64-bit build. On a 32-bit build the same
edge case is still out of reach, but that matches the existing
intentional limitation on the C++ side and a 32-bit process can't
address a buffer that size anyway.

Added a regression test that packs and unpacks an ext with exactly
UINT32_MAX bytes of data; it skips itself if the host can't spare the
roughly 8GB of memory the test needs rather than failing outright.

Fixes msgpack#1086
- Build the test only for 64-bit targets (#if SIZE_MAX > UINT32_MAX):
  gcc -m32 -Werror rejects calloc/memcmp with UINT32_MAX, and ASan on
  32-bit aborts on the allocation instead of returning NULL.
- Replace GTEST_SKIP() with return, since the coverage job builds
  against googletest 1.7.0 which does not provide it.
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 57.47%. Comparing base (ecc3a9b) to head (eabfe29).
⚠️ Report is 3 commits behind head on c_master.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@             Coverage Diff              @@
##           c_master    #1185      +/-   ##
============================================
+ Coverage     55.35%   57.47%   +2.11%     
============================================
  Files            10       10              
  Lines          1120     1124       +4     
  Branches        127      129       +2     
============================================
+ Hits            620      646      +26     
+ Misses          500      478      -22     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@redboltz
redboltz merged commit dbc7bfb into msgpack:c_master Sep 5, 2026
19 checks passed
@redboltz
redboltz deleted the afonsojanu-fix/ext32-uint32-max-length-overflow branch September 5, 2026 07:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants