Fix negative integer parsing with JSON_NO_INT64 - #1718
Open
fzlzjerry wants to merge 2 commits into
Open
Conversation
|
| Filename | Overview |
|---|---|
| src/lib_json/json_reader.cpp | Preserves signed arithmetic while reconstructing negative integers, including the minimum configured signed value. |
| src/lib_json/json_value.cpp | Excludes the unavailable UInt64-specific conversion overload when 64-bit integer support is disabled. |
| src/test_lib_json/main.cpp | Makes unit tests configuration-aware and adds comprehensive negative-integer and numeric-boundary regressions. |
| test/runjsontests.py | Validates the executable’s integer configuration and selects matching expected corpus output. |
| .github/workflows/cmake.yml | Adds a hardened CI job that builds and runs the complete no-int64 CTest suite. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A["JSON numeric token"] --> B["OurReader::decodeNumber"]
B --> C{"Within configured integer range?"}
C -->|Negative| D["Signed LargestInt reconstruction"]
C -->|Non-negative| E["Signed or unsigned Value"]
C -->|Out of range| F["Floating-point fallback"]
D --> G["Json::Value tree"]
E --> G
F --> G
G --> H["Unit and corpus round-trip tests"]
Reviews (2): Last reviewed commit: "Pin checkout and limit permissions in th..." | Re-trigger Greptile
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 #1341.
OurReader::decodeNumber()subtracts aValue::UIntlast digit from aLargestIntexpression. WithJSON_NO_INT64, both have the same width, so the usual arithmetic conversions make the subtraction unsigned. For example,-1becomes auintValuecontaining4294967295; even-0gets the wrong stored type.Keep the last digit signed. The existing quotient/remainder calculation still handles the minimum signed value without negating it directly.
Making the affected configuration testable
Current master first fails to compile with
JSON_NO_INT64on GCC/Clang because the privateintegerToDouble(Json::UInt64)overload refers to a disabled type. The patch guards that overload, along with 64-bit-only test helpers and API checks. The existing no-int64 floating-point assertions are updated to the current 17-digit formatting.The reader/writer fixtures that contain 64-bit limits still run. The test driver reads the executable's existing
--json-configoutput and selects explicit floating-point expectations for those three inputs when integer storage is limited to 32 bits. All other expectations, and all default-configuration expectations, stay unchanged; no fixture is skipped. Invalid configuration output fails the test run.Added regression tests cover negative zero, digit boundaries, signed limits, scalar/array/object contexts, unsigned limits, and the existing out-of-range floating-point fallback. A separate Linux CMake job exercises the complete no-int64 CTest suite so the configuration stays covered. It pins checkout to a full commit, limits permissions to read-only contents, and disables persisted checkout credentials.
There are no public-header changes. This does not add sign-only-token validation; that is covered separately by #1703. The verified reproduction is a Linux build with the library and consumer both compiled with
JSON_NO_INT64, rather than a reproduction of the original MSVC 2015 environment.Validation
CharReaderconsumer cases fail while the 8 legacyReadercontrols pass. Both readers pass all 16 cases after the fix.werror=true: all 3 test suites pass in both configurations.src,includeandexample, actionlint, andgit diff --checkpass.An additional warnings-as-errors stress run encounters pre-existing GCC C++20 implicit-
thiscapture and Clang C++17/20 signed-size warnings. Those failures were reproduced on pristine master; the unrelated source lines are unchanged.