🚑 fix to address #389
This commit is contained in:
parent
447e01427d
commit
79fa8b2f41
3 changed files with 49 additions and 2 deletions
17
src/json.hpp
17
src/json.hpp
|
@ -10643,7 +10643,22 @@ basic_json_parser_66:
|
||||||
}
|
}
|
||||||
else if (type == value_t::number_integer)
|
else if (type == value_t::number_integer)
|
||||||
{
|
{
|
||||||
result.m_value.number_integer = -static_cast<number_integer_t>(value);
|
// invariant: if we parsed a '-', the absolute value is between
|
||||||
|
// 0 (we allow -0) and max == -INT64_MIN
|
||||||
|
assert(value >= 0);
|
||||||
|
assert(value <= max);
|
||||||
|
|
||||||
|
if (value == max)
|
||||||
|
{
|
||||||
|
// we cannot simply negate value (== max == -INT64_MIN),
|
||||||
|
// see https://github.com/nlohmann/json/issues/389
|
||||||
|
result.m_value.number_integer = INT64_MIN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// all other values can be negated safely
|
||||||
|
result.m_value.number_integer = -static_cast<number_integer_t>(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -9793,7 +9793,22 @@ class basic_json
|
||||||
}
|
}
|
||||||
else if (type == value_t::number_integer)
|
else if (type == value_t::number_integer)
|
||||||
{
|
{
|
||||||
result.m_value.number_integer = -static_cast<number_integer_t>(value);
|
// invariant: if we parsed a '-', the absolute value is between
|
||||||
|
// 0 (we allow -0) and max == -INT64_MIN
|
||||||
|
assert(value >= 0);
|
||||||
|
assert(value <= max);
|
||||||
|
|
||||||
|
if (value == max)
|
||||||
|
{
|
||||||
|
// we cannot simply negate value (== max == -INT64_MIN),
|
||||||
|
// see https://github.com/nlohmann/json/issues/389
|
||||||
|
result.m_value.number_integer = INT64_MIN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// all other values can be negated safely
|
||||||
|
result.m_value.number_integer = -static_cast<number_integer_t>(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -516,4 +516,21 @@ TEST_CASE("regression tests")
|
||||||
CHECK_THROWS_AS(j << ss, std::invalid_argument);
|
CHECK_THROWS_AS(j << ss, std::invalid_argument);
|
||||||
CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input");
|
CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("issue #389 - Integer-overflow (OSS-Fuzz issue 267)")
|
||||||
|
{
|
||||||
|
// original test case
|
||||||
|
json j1 = json::parse("-9223372036854775808");
|
||||||
|
CHECK(j1.is_number_integer());
|
||||||
|
CHECK(j1.get<json::number_integer_t>() == INT64_MIN);
|
||||||
|
|
||||||
|
// edge case (+1; still an integer)
|
||||||
|
json j2 = json::parse("-9223372036854775807");
|
||||||
|
CHECK(j2.is_number_integer());
|
||||||
|
CHECK(j2.get<json::number_integer_t>() == INT64_MIN + 1);
|
||||||
|
|
||||||
|
// edge case (-1; overflow -> floats)
|
||||||
|
json j3 = json::parse("-9223372036854775809");
|
||||||
|
CHECK(j3.is_number_float());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue