From 6dbd5d0641f727d50995921e2dd188b67caf2bd0 Mon Sep 17 00:00:00 2001 From: Bo You Date: Mon, 27 Jun 2016 09:17:21 -0700 Subject: [PATCH] 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 --- folly/json.cpp | 8 ++++---- folly/test/JsonTest.cpp | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/folly/json.cpp b/folly/json.cpp index 86600fd5..f4607efd 100644 --- a/folly/json.cpp +++ b/folly/json.cpp @@ -512,9 +512,9 @@ dynamic parseNumber(Input& in) { auto const wasE = *in == 'e' || *in == 'E'; constexpr const char* maxInt = "9223372036854775807"; - constexpr const char* minInt = "9223372036854775808"; + constexpr const char* minInt = "-9223372036854775808"; constexpr auto maxIntLen = constexpr_strlen(maxInt); - + constexpr auto minIntLen = constexpr_strlen(minInt); if (*in != '.' && !wasE && in.getOpts().parse_numbers_as_strings) { return integral; @@ -522,8 +522,8 @@ dynamic parseNumber(Input& in) { if (*in != '.' && !wasE) { if (LIKELY(!in.getOpts().double_fallback || integral.size() < maxIntLen) || - (integral.size() == maxIntLen && - (integral <= maxInt || (integral == minInt && negative)))) { + (!negative && integral.size() == maxIntLen && integral <= maxInt) || + (negative && integral.size() == minIntLen && integral <= minInt)) { auto val = to(integral); in.skipWhitespace(); return val; diff --git a/folly/test/JsonTest.cpp b/folly/test/JsonTest.cpp index a9bca3ba..e6820f7f 100644 --- a/folly/test/JsonTest.cpp +++ b/folly/test/JsonTest.cpp @@ -395,6 +395,9 @@ TEST(Json, ParseDoubleFallback) { EXPECT_EQ(847605071342477612345678900000.0, parseJson("{\"a\":847605071342477612345678912345}", opts).items().begin()->second.asDouble()); + EXPECT_EQ( + toJson(parseJson(R"({"a":-9223372036854775808})", opts)), + R"({"a":-9223372036854775808})"); } TEST(Json, ParseNumbersAsStrings) { -- 2.34.1