Repository navigation
Fix int overflow in serialization size counting - #235
Open
zhouyunding wants to merge 1 commit into
Open
zhouyunding wants to merge 1 commit into
zhouyunding wants to merge 1 commit into
Conversation
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #234
Summary
json_serialization_size()/json_serialization_size_pretty()and the matching serialize functions counted bytes in a signedintinternally. For documents whose serialized form exceeds 2^31 bytes the accumulator wraps (signed overflow is UB in C), producing a size of 0 or a small wrapped value. Callers trusting the reported size then either silently lose data (size 0 → serialize returns NULL) or allocate a too-small buffer and crash with a heap buffer overflow while serializing (observed SIGSEGV).Root cause
Static
json_serialize_to_buffer_r()accumulated intoint written_totaland returnedint. Past 2^31 the value wraps to negative / small positive, and the public wrappers translate that into 0/NULL or a bogus small size.Fix
size_tand add an explicit pre-addition overflow guard (written_total >= (size_t)-1 - written), failing through the existing(size_t)-1sentinel → the public wrappers keep returning 0 / NULL / JSONFailure on failure, exactly as documented.parson.his untouched.Behavior change
json_serialize_to_file()still materializes the whole string in memory (peak ≈ 2× payload); this PR does not add streaming output.Reproducer (before → after, gcc 16.2.0, Windows/UCRT64)
size = 0→ serialize returns NULL; after size = 2,165,047,295 and the written buffer satisfies strlen+1 == size.Testing
test_serialization_size_overflowin tests.c (fails on unpatched code, passes after).make all(gcc-std=c89 -pedantic-errors, g++, and-DPARSON_FORCE_HASH_COLLISIONSbuilds): 365/365 passing, zero warnings.Note: CI on this PR will show "action required" until a maintainer approves the workflow run (first-time contributor); all results above are from local builds using the same compile flags as CI.
AI assistance disclosure: this patch was developed with AI-assisted tooling (implementation, tests, and independent review rounds); I have reviewed and understand every changed line and take full responsibility for the change.