Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/lib_json/json_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,11 @@ bool Reader::decodeNumber(Token& token, Value& decoded) {
bool isNegative = *current == '-';
if (isNegative)
++current;
// A number token that is only a sign (e.g. "-") carries no digits; the loop
// below never runs and would otherwise decode it as zero. Reject it via
// decodeDouble, matching how a non-digit inside the token is handled.
if (current == token.end_)
return decodeDouble(token, decoded);
// TODO: Help the compiler do the div and mod at compile time or get rid of
// them.
Value::LargestUInt maxIntegerValue =
Expand Down Expand Up @@ -1575,6 +1580,11 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) {
if (isNegative) {
++current;
}
// A number token that is only a sign (e.g. "-") carries no digits; the loop
// below never runs and would otherwise decode it as zero. Reject it via
// decodeDouble, matching how a non-digit inside the token is handled.
if (current == token.end_)
return decodeDouble(token, decoded);

// We assume we can represent the largest and smallest integer types as
// unsigned integers with separate sign. This is only true if they can fit
Expand Down
18 changes: 18 additions & 0 deletions src/test_lib_json/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3251,6 +3251,24 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseNumber) {
}
}

JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseBareSign) {
// A lone sign is not a valid number and used to be silently decoded as 0.
Json::CharReaderBuilder b;
CharReaderPtr reader(b.newCharReader());
Json::String errs;
for (const char* doc : {"-", "[-]", "{\"a\":-}", "-x"}) {
Json::Value root;
JSONTEST_ASSERT(!reader->parse(doc, doc + std::strlen(doc), &root, &errs));
}
// A sign followed by digits still parses.
{
Json::Value root;
char const doc[] = "-0";
JSONTEST_ASSERT(reader->parse(doc, doc + std::strlen(doc), &root, &errs));
JSONTEST_ASSERT_EQUAL(0, root.asInt());
}
}

JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseSubnormal) {
// Regression test for #1427: subnormal doubles make operator>> set failbit
// even though it produced the correctly-rounded value, so they used to fail
Expand Down
Loading