Commit 325517b9 authored by Alexander Sidorov's avatar Alexander Sidorov Committed by Jordan DeLong

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
parent 52ba96ed
/* /*
* Copyright 2013 Facebook, Inc. * Copyright 2014 Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -308,6 +308,15 @@ struct Input { ...@@ -308,6 +308,15 @@ struct Input {
return skipWhile([] (char c) { return c >= '0' && c <= '9'; }); 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() { void skipWhitespace() {
// Spaces other than ' ' characters are less common but should be // Spaces other than ' ' characters are less common but should be
// checked. This configuration where we loop on the ' ' // checked. This configuration where we loop on the ' '
...@@ -469,22 +478,19 @@ dynamic parseArray(Input& in) { ...@@ -469,22 +478,19 @@ dynamic parseArray(Input& in) {
dynamic parseNumber(Input& in) { dynamic parseNumber(Input& in) {
bool const negative = (*in == '-'); bool const negative = (*in == '-');
if (negative) { if (negative) {
++in; if (in.consume("-Infinity")) {
if (in.consume("Infinity")) {
return -std::numeric_limits<double>::infinity(); return -std::numeric_limits<double>::infinity();
} }
} }
auto integral = in.skipDigits(); auto integral = in.skipMinusAndDigits();
if (integral.empty()) { if (negative && integral.size() < 2) {
in.error("expected digits after `-'"); in.error("expected digits after `-'");
} }
auto const wasE = *in == 'e' || *in == 'E'; auto const wasE = *in == 'e' || *in == 'E';
if (*in != '.' && !wasE) { if (*in != '.' && !wasE) {
auto val = to<int64_t>(integral); auto val = to<int64_t>(integral);
if (negative) {
val = -val;
}
in.skipWhitespace(); in.skipWhitespace();
return val; return val;
} }
...@@ -501,9 +507,6 @@ dynamic parseNumber(Input& in) { ...@@ -501,9 +507,6 @@ dynamic parseNumber(Input& in) {
auto fullNum = makeRange(integral.begin(), end); auto fullNum = makeRange(integral.begin(), end);
auto val = to<double>(fullNum); auto val = to<double>(fullNum);
if (negative) {
val *= -1;
}
return val; return val;
} }
......
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