From: Alexander Sidorov Date: Fri, 17 Jan 2014 06:26:04 +0000 (-0800) Subject: folly json bug fix: overflow for -1LL<<63 X-Git-Tag: v0.22.0~731 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=325517b966a67d52e9db98cd66d6aa0714b2ad7b;p=folly.git folly json bug fix: overflow for -1LL<<63 Summary: -1LL<<63 was passed to folly::to() without '-' so it overflowed. Fixed that Test Plan: tried this: int main() { stringstream s; s << "{\"int\":" << -1LL<<63 << "}"; string str = s.str(); cout << "string to parse: " << endl << str << endl; int64_t sample = folly::parseJson(str.c_str())["int"].asInt(); LOG(INFO) << "test result = " << sample; return 0; } it returns right value. Also tried it with "-Infinity" and double type for sample. In works fine as well. Reviewed By: andrei.alexandrescu@fb.com FB internal diff: D1130155 --- diff --git a/folly/json.cpp b/folly/json.cpp index 3b954ef4..f248ef8e 100644 --- a/folly/json.cpp +++ b/folly/json.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2013 Facebook, Inc. + * Copyright 2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -308,6 +308,15 @@ struct Input { return skipWhile([] (char c) { return c >= '0' && c <= '9'; }); } + StringPiece skipMinusAndDigits() { + bool firstChar = true; + return skipWhile([&firstChar] (char c) { + bool result = (c >= '0' && c <= '9') || (firstChar && c == '-'); + firstChar = false; + return result; + }); + } + void skipWhitespace() { // Spaces other than ' ' characters are less common but should be // checked. This configuration where we loop on the ' ' @@ -469,22 +478,19 @@ dynamic parseArray(Input& in) { dynamic parseNumber(Input& in) { bool const negative = (*in == '-'); if (negative) { - ++in; - if (in.consume("Infinity")) { + if (in.consume("-Infinity")) { return -std::numeric_limits::infinity(); } } - auto integral = in.skipDigits(); - if (integral.empty()) { + auto integral = in.skipMinusAndDigits(); + if (negative && integral.size() < 2) { in.error("expected digits after `-'"); } + auto const wasE = *in == 'e' || *in == 'E'; if (*in != '.' && !wasE) { auto val = to(integral); - if (negative) { - val = -val; - } in.skipWhitespace(); return val; } @@ -501,9 +507,6 @@ dynamic parseNumber(Input& in) { auto fullNum = makeRange(integral.begin(), end); auto val = to(fullNum); - if (negative) { - val *= -1; - } return val; }