From cfe3adb599cd19dd717529a2aebbe269d5658872 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 23 Jun 2021 18:02:00 -0400 Subject: [PATCH] Added tests over invalid documents. (#1626) * Added tests over invalid documents. * Tweaking. --- include/simdjson/generic/ondemand/parser.h | 5 +++ .../ondemand/ondemand_json_pointer_tests.cpp | 40 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/include/simdjson/generic/ondemand/parser.h b/include/simdjson/generic/ondemand/parser.h index b8539f863..2a7578ded 100644 --- a/include/simdjson/generic/ondemand/parser.h +++ b/include/simdjson/generic/ondemand/parser.h @@ -36,6 +36,11 @@ public: * ondemand::parser parser; * document doc = parser.iterate(json); * + * ### IMPORTANT: Validate what you use + * + * Calling iterate on an invalid JSON document may not immediately trigger an error. The call to + * iterate does not parse and validate the whole document. + * * ### IMPORTANT: Buffer Lifetime * * Because parsing is done while you iterate, you *must* keep the JSON buffer around at least as diff --git a/tests/ondemand/ondemand_json_pointer_tests.cpp b/tests/ondemand/ondemand_json_pointer_tests.cpp index ea7d430d7..dd0abc29d 100644 --- a/tests/ondemand/ondemand_json_pointer_tests.cpp +++ b/tests/ondemand/ondemand_json_pointer_tests.cpp @@ -123,6 +123,45 @@ namespace json_pointer_tests { if (measured != expected) { return false; } TEST_SUCCEED(); } + bool run_broken_tests() { + TEST_START(); + ondemand::parser parser; + ondemand::document doc; + ondemand::value v; + std::string_view val; + + auto invalid_escape_key = R"( {"hello": [0,1,2,3], "te\est": "foo", "bool": true, "num":1234, "success":"yes"} )"_padded; + auto invalid_escape_value = R"( {"hello": [0,1,2,3], "test": "fo\eo", "bool": true, "num":1234, "success":"yes"} )"_padded; + auto invalid_escape_value_at_jp = R"( {"hello": [0,1,2,3], "test": "foo", "bool": true, "num":1234, "success":"y\es"} )"_padded; + auto unclosed_object = R"( {"test": "foo", "bool": true, "num":1234, "success":"yes" )"_padded; + auto missing_bracket_before = R"( {"hello": [0,1,2,3, "test": "foo", "bool": true, "num":1234, "success":"yes"} )"_padded; + auto missing_bracket_after = R"( {"test": "foo", "bool": true, "num":1234, "success":"yes", "hello":[0,1,2,3} )"_padded; + + std::string json_pointer = "/success"; + std::cout << "\t- invalid_escape_key" << std::endl; + ASSERT_SUCCESS(parser.iterate(invalid_escape_key).get(doc)); + ASSERT_SUCCESS(doc.at_pointer(json_pointer).get(val)); + std::cout << "\t- invalid_escape_value" << std::endl; + ASSERT_SUCCESS(parser.iterate(invalid_escape_value).get(doc)); + ASSERT_SUCCESS(doc.at_pointer(json_pointer).get(val)); + std::cout << "\t- invalid_escape_value_at_jp_nomat" << std::endl; + ASSERT_SUCCESS(parser.iterate(invalid_escape_value_at_jp).get(doc)); + ASSERT_SUCCESS(doc.at_pointer(json_pointer).get(v)); + std::cout << "\t- invalid_escape_value_at_jp" << std::endl; + ASSERT_SUCCESS(parser.iterate(invalid_escape_value_at_jp).get(doc)); + ASSERT_ERROR(doc.at_pointer(json_pointer).get(val), simdjson::STRING_ERROR); + std::cout << "\t- unclosed_object" << std::endl; + ASSERT_SUCCESS(parser.iterate(unclosed_object).get(doc)); + ASSERT_ERROR(doc.at_pointer(json_pointer).get(val), simdjson::TAPE_ERROR); + std::cout << "\t- missing_bracket_before" << std::endl; + ASSERT_SUCCESS(parser.iterate(missing_bracket_before).get(doc)); + ASSERT_ERROR(doc.at_pointer(json_pointer).get(val), simdjson::TAPE_ERROR); + std::cout << "\t- missing_bracket_after" << std::endl; + ASSERT_SUCCESS(parser.iterate(missing_bracket_after).get(doc)); + ASSERT_SUCCESS(doc.at_pointer(json_pointer).get(val)); + TEST_SUCCEED(); + } + struct car_type { std::string make; @@ -182,6 +221,7 @@ namespace json_pointer_tests { bool run() { return + run_broken_tests() && json_pointer_invalidation() && demo_test() && demo_relative_path() &&