Skip to content

Commit 731490f

Browse files
terokinnunenvai-terokinnunen
authored andcommitted
Parse large floats as infinity (open-source-parsers#1349) (open-source-parsers#1353)
Return 1.9.1 functionality where values too large to fit in double are converted to positive or negative infinity. Commit 645cd04 changed functionality so that large floats cause parse error, while version 1.9.1 accepted them as infinite. This is problematic because writer outputs infinity values as `1e+9999`, which could no longer be parsed back. Fixed also legacy Reader even though it did not parse large values even before breaking change, due to problematic output/parse asymmetry. `>>` operator sets value to numeric_limits::max/lowest value if representation is too large to fit to double. [1][2] In macos value appears to be parsed to infinity. > | value in *val* | description | > |--------------------------|-------------| > | numeric_limits::max() | The sequence represents a value too large for the type of val | > | numeric_limits::lowest() | The sequence represents a value too large negative for the type of val | [1] https://www.cplusplus.com/reference/istream/istream/operator%3E%3E/ [2] https://www.cplusplus.com/reference/locale/num_get/get/ Signed-off-by: Tero Kinnunen <[email protected]> Co-authored-by: Tero Kinnunen <[email protected]>
1 parent 5ba5ed6 commit 731490f

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

Diff for: src/lib_json/json_reader.cpp

+15-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#endif // if !defined(JSON_IS_AMALGAMATION)
1313
#include <algorithm>
1414
#include <cassert>
15+
#include <cmath>
1516
#include <cstring>
1617
#include <iostream>
1718
#include <istream>
@@ -600,9 +601,15 @@ bool Reader::decodeDouble(Token& token, Value& decoded) {
600601
double value = 0;
601602
String buffer(token.start_, token.end_);
602603
IStringStream is(buffer);
603-
if (!(is >> value))
604-
return addError(
604+
if (!(is >> value)) {
605+
if (value == std::numeric_limits<double>::max())
606+
value = std::numeric_limits<double>::infinity();
607+
else if (value == std::numeric_limits<double>::lowest())
608+
value = -std::numeric_limits<double>::infinity();
609+
else if (!std::isinf(value))
610+
return addError(
605611
"'" + String(token.start_, token.end_) + "' is not a number.", token);
612+
}
606613
decoded = value;
607614
return true;
608615
}
@@ -1647,7 +1654,12 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) {
16471654
const String buffer(token.start_, token.end_);
16481655
IStringStream is(buffer);
16491656
if (!(is >> value)) {
1650-
return addError(
1657+
if (value == std::numeric_limits<double>::max())
1658+
value = std::numeric_limits<double>::infinity();
1659+
else if (value == std::numeric_limits<double>::lowest())
1660+
value = -std::numeric_limits<double>::infinity();
1661+
else if (!std::isinf(value))
1662+
return addError(
16511663
"'" + String(token.start_, token.end_) + "' is not a number.", token);
16521664
}
16531665
decoded = value;

Diff for: test/data/legacy_test_real_13.expected

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.=[]
2+
.[0]=-inf
3+
.[1]=inf

Diff for: test/data/legacy_test_real_13.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[-1e+9999, 1e+9999]

0 commit comments

Comments
 (0)