Commit 5e785d3d authored by StilesCrisis's avatar StilesCrisis

Fix parsing of NaN/Inf

A failed half-consume of “NaN” now returns “value invalid” instead of
attempting to consume an “Inf”.
parent c4117c68
......@@ -1170,18 +1170,27 @@ private:
}
// Parse NaN or Infinity here
else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) {
useNanOrInf = true;
if (RAPIDJSON_LIKELY(Consume(s, 'N') && Consume(s, 'a') && Consume(s, 'N'))) {
d = std::numeric_limits<double>::quiet_NaN();
if (Consume(s, 'N')) {
if (Consume(s, 'a') && Consume(s, 'N')) {
d = std::numeric_limits<double>::quiet_NaN();
useNanOrInf = true;
}
}
else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) {
d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')
&& Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y'))))
RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
else if (RAPIDJSON_LIKELY(Consume(s, 'I'))) {
if (Consume(s, 'n') && Consume(s, 'f')) {
d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
useNanOrInf = true;
if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')
&& Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) {
RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
}
}
}
else
if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
}
}
else
RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
......
......@@ -1833,9 +1833,9 @@ TEST(Reader, ParseNanAndInfinity) {
TEST_NAN_INF("-Inf", -inf);
TEST_NAN_INF("-Infinity", -inf);
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "NInf", 1);
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "NaInf", 1);
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "NaInf", 2);
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "INan", 1);
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "InNan", 1);
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "InNan", 2);
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "nan", 1);
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "-nan", 1);
TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "NAN", 1);
......
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