• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From 2d55c7445ffedf30db62231f223137ef02e611a9 Mon Sep 17 00:00:00 2001
2From: Tero Kinnunen <tero.kinnunen@gmail.com>
3Date: Wed, 15 Dec 2021 04:00:28 +0200
4Subject: [PATCH] Parse large floats as infinity (#1349) (#1353)
5
6Return 1.9.1 functionality where values too large to fit in
7double are converted to positive or negative infinity.
8
9Commit 645cd04 changed functionality so that large floats cause
10parse error, while version 1.9.1 accepted them as infinite.
11This is problematic because writer outputs infinity values
12as `1e+9999`, which could no longer be parsed back.
13
14Fixed also legacy Reader even though it did not parse large values
15even before breaking change, due to problematic output/parse asymmetry.
16
17`>>` operator sets value to numeric_limits::max/lowest value if
18representation is too large to fit to double. [1][2] In macos
19value appears to be parsed to infinity.
20
21> | value in *val*           | description |
22> |--------------------------|-------------|
23> | numeric_limits::max()    | The sequence represents a value too large for the type of val |
24> | numeric_limits::lowest() | The sequence represents a value too large negative for the type of val |
25
26[1] https://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
27[2] https://www.cplusplus.com/reference/locale/num_get/get/
28
29Signed-off-by: Tero Kinnunen <tero.kinnunen@vaisala.com>
30
31Co-authored-by: Tero Kinnunen <tero.kinnunen@vaisala.com>
32---
33 src/lib_json/json_reader.cpp           | 18 +++++++++++++++---
34 test/data/legacy_test_real_13.expected |  3 +++
35 test/data/legacy_test_real_13.json     |  1 +
36 3 files changed, 19 insertions(+), 3 deletions(-)
37 create mode 100644 test/data/legacy_test_real_13.expected
38 create mode 100644 test/data/legacy_test_real_13.json
39
40diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp
41index a6a3f4e..896bf1b 100644
42--- a/src/lib_json/json_reader.cpp
43+++ b/src/lib_json/json_reader.cpp
44@@ -12,6 +12,7 @@
45 #endif // if !defined(JSON_IS_AMALGAMATION)
46 #include <algorithm>
47 #include <cassert>
48+#include <cmath>
49 #include <cstring>
50 #include <iostream>
51 #include <istream>
52@@ -600,9 +601,15 @@ bool Reader::decodeDouble(Token& token, Value& decoded) {
53   double value = 0;
54   String buffer(token.start_, token.end_);
55   IStringStream is(buffer);
56-  if (!(is >> value))
57-    return addError(
58+  if (!(is >> value)) {
59+    if (value == std::numeric_limits<double>::max())
60+      value = std::numeric_limits<double>::infinity();
61+    else if (value == std::numeric_limits<double>::lowest())
62+      value = -std::numeric_limits<double>::infinity();
63+    else if (!std::isinf(value))
64+      return addError(
65         "'" + String(token.start_, token.end_) + "' is not a number.", token);
66+  }
67   decoded = value;
68   return true;
69 }
70@@ -1647,7 +1654,12 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) {
71   const String buffer(token.start_, token.end_);
72   IStringStream is(buffer);
73   if (!(is >> value)) {
74-    return addError(
75+    if (value == std::numeric_limits<double>::max())
76+      value = std::numeric_limits<double>::infinity();
77+    else if (value == std::numeric_limits<double>::lowest())
78+      value = -std::numeric_limits<double>::infinity();
79+    else if (!std::isinf(value))
80+      return addError(
81         "'" + String(token.start_, token.end_) + "' is not a number.", token);
82   }
83   decoded = value;
84diff --git a/test/data/legacy_test_real_13.expected b/test/data/legacy_test_real_13.expected
85new file mode 100644
86index 0000000..8d3f03f
87--- /dev/null
88+++ b/test/data/legacy_test_real_13.expected
89@@ -0,0 +1,3 @@
90+.=[]
91+.[0]=-inf
92+.[1]=inf
93diff --git a/test/data/legacy_test_real_13.json b/test/data/legacy_test_real_13.json
94new file mode 100644
95index 0000000..287258a
96--- /dev/null
97+++ b/test/data/legacy_test_real_13.json
98@@ -0,0 +1 @@
99+[-1e+9999, 1e+9999]
100--
1012.42.0.windows.2
102
103