mirror of
https://github.com/boostorg/json.git
synced 2025-05-11 13:44:06 +00:00
handle bias overflow
This commit is contained in:
parent
dd5494b202
commit
3d751ad9e5
@ -19,7 +19,7 @@ def main(ctx):
|
||||
linux_cxx("Clang 12 arm64", "clang++-12", packages="clang-12 libstdc++-9-dev", llvm_os="focal", llvm_ver="12", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'clang-12', 'B2_CXXSTD': '17,20', 'DRONE_JOB_UUID': '7719a1c783m'}, arch="arm64", globalenv=globalenv),
|
||||
linux_cxx("gcc 11 arm64", "g++-11", packages="g++-11", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={'B2_TOOLSET': 'gcc-11', 'B2_CXXSTD': '17,2a', 'DRONE_JOB_UUID': '0716d9708dm'}, arch="arm64", globalenv=globalenv),
|
||||
linux_cxx("docs", "g++", packages="docbook docbook-xml docbook-xsl xsltproc libsaxonhe-java default-jre-headless flex libfl-dev bison unzip rsync", buildtype="docs", buildscript="drone", image="cppalliance/droneubuntu1804:1", environment={'COMMENT': 'docs', 'DRONE_JOB_UUID': 'b6589fc6ab'}, globalenv=globalenv),
|
||||
linux_cxx("codecov", "g++-8", packages="g++-8", buildtype="codecov", buildscript="drone", image=linuxglobalimage, environment={'COMMENT': 'codecov.io', 'LCOV_BRANCH_COVERAGE': '0', 'B2_CXXSTD': '11', 'B2_TOOLSET': 'gcc-8', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', 'CODECOV_TOKEN': {'from_secret': 'codecov_token'}, 'DRONE_JOB_UUID': '356a192b79'}, globalenv=globalenv),
|
||||
linux_cxx("codecov", "g++-8", packages="g++-8", buildtype="codecov", buildscript="drone", image=linuxglobalimage, environment={'COMMENT': 'codecov.io', 'LCOV_BRANCH_COVERAGE': '0', 'B2_CXXSTD': '11', 'B2_TOOLSET': 'gcc-8', 'B2_DEFINES': 'BOOST_JSON_EXPENSIVE_TESTS BOOST_NO_STRESS_TEST=1', 'CODECOV_TOKEN': {'from_secret': 'codecov_token'}, 'DRONE_JOB_UUID': '356a192b79'}, globalenv=globalenv),
|
||||
linux_cxx("Valgrind", "clang++-14", packages="clang-14 libc6-dbg libc++-dev libstdc++-9-dev", llvm_os="jammy", llvm_ver="14", buildscript="drone", buildtype="valgrind", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'valgrind', 'B2_TOOLSET': 'clang-14', 'B2_CXXSTD': '11,14,17', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', 'B2_VARIANT': 'debug', 'B2_TESTFLAGS': 'testing.launcher=valgrind', 'VALGRIND_OPTS': '--error-exitcode=1'}, globalenv=globalenv),
|
||||
linux_cxx("ASan GCC", "g++-12", packages="g++-12", buildscript="drone", buildtype="boost", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'asan', 'B2_VARIANT': 'debug', 'B2_TOOLSET': 'gcc-12', 'B2_CXXSTD': '11,14,17', 'B2_ASAN': '1', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', 'DRONE_EXTRA_PRIVILEGED': 'True'}, globalenv=globalenv, privileged=True),
|
||||
linux_cxx("ASan Clang", "clang++-14", packages="clang-14 libstdc++-10-dev", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2204:1", environment={'COMMENT': 'asan', 'B2_VARIANT': 'debug', 'B2_TOOLSET': 'clang-14', 'B2_CXXSTD': '11,14,17', 'B2_ASAN': '1', 'B2_DEFINES': 'define=BOOST_NO_STRESS_TEST=1'}, globalenv=globalenv),
|
||||
|
@ -2336,8 +2336,13 @@ do_num3:
|
||||
if(BOOST_JSON_UNLIKELY(
|
||||
c >= '0' && c <= '9'))
|
||||
{
|
||||
if(BOOST_JSON_UNLIKELY( num.bias + 1 == INT_MAX ))
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc
|
||||
= BOOST_CURRENT_LOCATION;
|
||||
return fail(cs.begin(), error::exponent_overflow, &loc);
|
||||
}
|
||||
++cs;
|
||||
// VFALCO check overflow
|
||||
++num.bias;
|
||||
}
|
||||
else if(BOOST_JSON_LIKELY(
|
||||
@ -2541,6 +2546,12 @@ do_num8:
|
||||
if(!no_parsing && BOOST_JSON_LIKELY(
|
||||
num.mant <= 9007199254740991)) // 2^53-1
|
||||
{
|
||||
if(BOOST_JSON_UNLIKELY( num.bias - 1 == INT_MIN ))
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc
|
||||
= BOOST_CURRENT_LOCATION;
|
||||
return fail(cs.begin(), error::exponent_overflow, &loc);
|
||||
}
|
||||
--num.bias;
|
||||
num.mant = 10 * num.mant + ( c - '0' );
|
||||
}
|
||||
@ -2668,14 +2679,42 @@ do_exp3:
|
||||
BOOST_ASSERT(num.exp >= 0);
|
||||
if ( num.frac )
|
||||
{
|
||||
if (BOOST_JSON_UNLIKELY( num.bias < (INT_MIN + num.exp) ))
|
||||
if(BOOST_JSON_UNLIKELY( num.bias < (INT_MIN + num.exp) ))
|
||||
{
|
||||
// if exponent overflowed, bias is a very large negative
|
||||
// number, and mantissa isn't zero, then we cannot parse the
|
||||
// number correctly
|
||||
if(BOOST_JSON_UNLIKELY(
|
||||
(num.exp == INT_MAX) &&
|
||||
(num.bias < 0) &&
|
||||
(num.exp + num.bias < 308) &&
|
||||
num.mant ))
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc
|
||||
= BOOST_CURRENT_LOCATION;
|
||||
return fail(cs.begin(), error::exponent_overflow, &loc);
|
||||
}
|
||||
|
||||
num.bias = 0;
|
||||
num.exp = INT_MAX;
|
||||
}
|
||||
}
|
||||
else if (BOOST_JSON_UNLIKELY( num.bias > (INT_MAX - num.exp) ))
|
||||
{
|
||||
// if exponent overflowed, bias is a very large positive number,
|
||||
// and mantissa isn't zero, then we cannot parse the
|
||||
// number correctly
|
||||
if(BOOST_JSON_UNLIKELY(
|
||||
(num.exp == INT_MAX) &&
|
||||
(num.bias > 0) &&
|
||||
(num.exp - num.bias < 308) &&
|
||||
num.mant ))
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR source_location loc
|
||||
= BOOST_CURRENT_LOCATION;
|
||||
return fail(cs.begin(), error::exponent_overflow, &loc);
|
||||
}
|
||||
|
||||
num.bias = 0;
|
||||
num.exp = INT_MAX;
|
||||
}
|
||||
|
@ -1295,6 +1295,86 @@ R"xx({
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
void
|
||||
testLongNumberOverlfow()
|
||||
{
|
||||
#ifdef BOOST_JSON_EXPENSIVE_TESTS
|
||||
std::array<char, 1000> zeroes;
|
||||
zeroes.fill('0');
|
||||
|
||||
stream_parser p;
|
||||
{
|
||||
p.write("1", 1);
|
||||
|
||||
std::size_t count = 0;
|
||||
while( static_cast<std::size_t>( INT_MAX - zeroes.size() ) > count )
|
||||
count += p.write( zeroes.data(), zeroes.size() );
|
||||
|
||||
error_code ec;
|
||||
p.write(zeroes.data(), zeroes.size(), ec);
|
||||
BOOST_TEST( ec == error::exponent_overflow );
|
||||
}
|
||||
|
||||
p.reset();
|
||||
{
|
||||
p.write("0.", 2);
|
||||
|
||||
std::size_t count = 0;
|
||||
while( static_cast<std::size_t>( INT_MAX - zeroes.size() ) > count )
|
||||
count += p.write( zeroes.data(), zeroes.size() );
|
||||
|
||||
error_code ec;
|
||||
p.write(zeroes.data(), zeroes.size(), ec);
|
||||
BOOST_TEST( ec == error::exponent_overflow );
|
||||
}
|
||||
|
||||
p.reset();
|
||||
{
|
||||
p.write("0.", 2);
|
||||
|
||||
int count = INT_MIN;
|
||||
while( static_cast<int>( count + zeroes.size() ) < 0 )
|
||||
count += static_cast<int>(
|
||||
p.write( zeroes.data(), zeroes.size() ));
|
||||
|
||||
p.write(zeroes.data(), -2 - count);
|
||||
p.write("1e", 2);
|
||||
// at this point we've filled bias to the brim
|
||||
|
||||
std::string const int_min = std::to_string(INT_MIN);
|
||||
p.write( int_min.data(), int_min.size() );
|
||||
|
||||
error_code ec;
|
||||
p.finish(ec);
|
||||
BOOST_TEST( ec == error::exponent_overflow );
|
||||
}
|
||||
|
||||
p.reset();
|
||||
{
|
||||
std::string const uint64_max
|
||||
= std::to_string(18446744073709551615U);
|
||||
p.write( uint64_max.data(), uint64_max.size() );
|
||||
|
||||
std::size_t count = INT_MAX;
|
||||
while( static_cast<int>( count - zeroes.size() ) > 0 )
|
||||
count -= p.write( zeroes.data(), zeroes.size() );
|
||||
|
||||
p.write(zeroes.data(), count - 1);
|
||||
// at this point we've filled bias to the brim
|
||||
|
||||
p.write("e", 1);
|
||||
std::string const int_max = std::to_string(INT_MAX);
|
||||
p.write( int_max.data(), int_max.size() );
|
||||
|
||||
error_code ec;
|
||||
p.finish(ec);
|
||||
BOOST_TEST( ec == error::exponent_overflow );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
@ -1319,6 +1399,7 @@ R"xx({
|
||||
testIssue876();
|
||||
testSentinelOverlap();
|
||||
testSpecialNumbers();
|
||||
testLongNumberOverlfow();
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user