diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 164d41d6f..2f901f510 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1048,10 +1048,19 @@ bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root, } bool OurReader::readValue() { - // To preserve the old behaviour we cast size_t to int. - if (nodes_.size() > features_.stackLimit_) - throwRuntimeError("Exceeded stackLimit in readValue()."); Token token; + if (nodes_.size() > features_.stackLimit_) { +#if JSON_USE_EXCEPTION + throwRuntimeError("Exceeded stackLimit in readValue()."); +#else + // throwRuntimeError aborts. Don't abort here. + token.start_ = current_; + token.end_ = current_; + token.type_ = tokenError; + return addError( + "Exceeded stackLimit for nested object and/or array values.", token); +#endif + } readTokenSkippingComments(token); bool successful = true; diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 0d1c33064..2e106bc5c 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -467,6 +467,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrays) { JSONTEST_ASSERT_EQUAL(Json::Value(17), got); JSONTEST_ASSERT_EQUAL(false, array1_.removeIndex(2, &got)); // gone now } + JSONTEST_FIXTURE_LOCAL(ValueTest, resizeArray) { Json::Value array; { @@ -3550,10 +3551,10 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithDetailError) { } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithStackLimit) { -#if JSON_USE_EXCEPTION - Json::CharReaderBuilder b; Json::Value root; + +#if JSON_USE_EXCEPTION char const doc[] = R"({ "property" : "value" })"; { b.settings_["stackLimit"] = 2; @@ -3581,7 +3582,36 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithStackLimit) { JSONTEST_ASSERT_THROWS(reader->parse( nested.data(), nested.data() + nested.size(), &root, &errs)); } - +#else + b.settings_["stackLimit"] = 10; + CharReaderPtr reader(b.newCharReader()); + { + Json::String nested(16, '['); + Json::String errs; + JSONTEST_ASSERT(!reader->parse(nested.data(), nested.data() + nested.size(), + &root, &errs)); + JSONTEST_ASSERT( + errs == + "* Line 1, Column 11\n" + " Exceeded stackLimit for nested object and/or array values.\n"); + } + { + // even if there are mixed object/array nestings + char const mixedNested[] = R"({"property":[[[[[[[[[[[]]]]]]]]]]]})"; + Json::String errs; + JSONTEST_ASSERT(!reader->parse( + mixedNested, mixedNested + std::strlen(mixedNested), &root, &errs)); + JSONTEST_ASSERT( + errs == + "* Line 1, Column 22\n" + " Exceeded stackLimit for nested object and/or array values.\n"); + } + { // should succeed: test on the limit + Json::String onLimit = Json::String(10, '[') + Json::String(10, ']'); + Json::String errs; + JSONTEST_ASSERT(reader->parse( + onLimit.data(), onLimit.data() + onLimit.size(), &root, &errs)); + } #endif // JSON_USE_EXCEPTION }