fix overflow check in parse_number_token#1171
Conversation
|
An automated preview of the documentation is available at https://1171.json.prtest2.cppalliance.org/libs/json/doc/html/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-07-17 10:18:50 UTC |
|
GCOVR code coverage report https://1171.json.prtest2.cppalliance.org/gcovr/index.html Build time: 2026-07-17 10:32:06 UTC |
|
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1171 +/- ##
========================================
Coverage 93.91% 93.91%
========================================
Files 91 91
Lines 9265 9268 +3
========================================
+ Hits 8701 8704 +3
Misses 564 564
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
| // guard against std::size_t overflow in result * 10 + d | ||
| if( result > (std::size_t(-1) - d) / 10 ) | ||
| { | ||
| BOOST_JSON_FAIL(ec, error::token_overflow); | ||
| return {}; | ||
| } | ||
|
|
||
| result = new_result; | ||
| result = result * 10 + d; |
There was a problem hiding this comment.
How about something like this?
if( result > UINT64_MAX / 10 )
{
BOOST_JSON_FAIL(ec, error::token_overflow);
return {};
}
result *= 10;
if( result > UINT64_MAX - d )
{
BOOST_JSON_FAIL(ec, error::token_overflow);
return {};
}
result += d;
I've checked on Godbolt and produces less code.
There was a problem hiding this comment.
Done, pushed the two-step guard. One adjustment: result is std::size_t, so I used std::size_t(-1) as the bound rather than UINT64_MAX, which would never fire on 32-bit targets. Pointer suite still passes, 185 total, including the max()+'9' regression.
|
|


parse_number_token flags
std::size_toverflow withnew_result < result, theaddition-overflow idiom, but the accumulation is
result * 10 + d. Onceresult * 10wraps, the wrapped value plusdcan land at or aboveresult,so a pointer token an order of magnitude past
max()slips through and resolvesto a bogus (out-of-range) index, reporting
error::not_foundrather thanerror::token_overflow. Replaced with the pre-checkresult > (std::size_t(-1) - d) / 10.The regression test appends a digit to
max()and expectstoken_overflow; itfails before the change and passes after. The existing overflow test only covers
max() + 1, which happens to wrap belowresultand so was already caught.