Commit 6dbd5d06 authored by Bo You's avatar Bo You Committed by Facebook Github Bot 8

Folly parseJson doesn't handle minInt properly

Summary:
Right now in ##parseNumber## in ##folly/json.cpp##, when a negative number is provided, both the minus sign and the digits are stored in the variable ##integral##: https://fburl.com/362938516.

This causes problem when the exact min int is provided (-9223372036854775808). Because now ##integral.size()## equals 20 (including the minus sign), which is greater than ##maxIntLen## (which is 19). We need to handle negatives separately to get the correct result.

Reviewed By: yfeldblum

Differential Revision: D3479054

fbshipit-source-id: 15c782962a5f5ee845a2a18f2145c7695ec2d546
parent 1ce31b9a
...@@ -512,9 +512,9 @@ dynamic parseNumber(Input& in) { ...@@ -512,9 +512,9 @@ dynamic parseNumber(Input& in) {
auto const wasE = *in == 'e' || *in == 'E'; auto const wasE = *in == 'e' || *in == 'E';
constexpr const char* maxInt = "9223372036854775807"; constexpr const char* maxInt = "9223372036854775807";
constexpr const char* minInt = "9223372036854775808"; constexpr const char* minInt = "-9223372036854775808";
constexpr auto maxIntLen = constexpr_strlen(maxInt); constexpr auto maxIntLen = constexpr_strlen(maxInt);
constexpr auto minIntLen = constexpr_strlen(minInt);
if (*in != '.' && !wasE && in.getOpts().parse_numbers_as_strings) { if (*in != '.' && !wasE && in.getOpts().parse_numbers_as_strings) {
return integral; return integral;
...@@ -522,8 +522,8 @@ dynamic parseNumber(Input& in) { ...@@ -522,8 +522,8 @@ dynamic parseNumber(Input& in) {
if (*in != '.' && !wasE) { if (*in != '.' && !wasE) {
if (LIKELY(!in.getOpts().double_fallback || integral.size() < maxIntLen) || if (LIKELY(!in.getOpts().double_fallback || integral.size() < maxIntLen) ||
(integral.size() == maxIntLen && (!negative && integral.size() == maxIntLen && integral <= maxInt) ||
(integral <= maxInt || (integral == minInt && negative)))) { (negative && integral.size() == minIntLen && integral <= minInt)) {
auto val = to<int64_t>(integral); auto val = to<int64_t>(integral);
in.skipWhitespace(); in.skipWhitespace();
return val; return val;
......
...@@ -395,6 +395,9 @@ TEST(Json, ParseDoubleFallback) { ...@@ -395,6 +395,9 @@ TEST(Json, ParseDoubleFallback) {
EXPECT_EQ(847605071342477612345678900000.0, EXPECT_EQ(847605071342477612345678900000.0,
parseJson("{\"a\":847605071342477612345678912345}", parseJson("{\"a\":847605071342477612345678912345}",
opts).items().begin()->second.asDouble()); opts).items().begin()->second.asDouble());
EXPECT_EQ(
toJson(parseJson(R"({"a":-9223372036854775808})", opts)),
R"({"a":-9223372036854775808})");
} }
TEST(Json, ParseNumbersAsStrings) { TEST(Json, ParseNumbersAsStrings) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment