diff --git a/fuzz/fuzz_ndjson.cpp b/fuzz/fuzz_ndjson.cpp index 72e880a1..62e5ad89 100644 --- a/fuzz/fuzz_ndjson.cpp +++ b/fuzz/fuzz_ndjson.cpp @@ -8,24 +8,26 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { FuzzData fd(Data, Size); - const auto batch_size=static_cast(fd.getInt<0,1000>()); - const auto json=simdjson::padded_string{fd.remainder_as_stringview()}; + const auto batch_size = static_cast(fd.getInt<0,1000>()); + const auto json = simdjson::padded_string{fd.remainder_as_stringview()}; simdjson::dom::parser parser; -#if SIMDJSON_EXCEPTIONS - try { -#endif - simdjson::dom::document_stream docs; - if(parser.parse_many(json,batch_size).get(docs)) { - return 0; - } - - [[maybe_unused]] size_t bool_count=0; + simdjson::dom::document_stream docs; + if(parser.parse_many(json,batch_size).get(docs)) { return 0; } + size_t bool_count1 = 0; + size_t total_count1 = 0; for (auto doc : docs) { - bool_count+=doc.is_bool(); + total_count1++; + bool_count1 += doc.is_bool(); } -#if SIMDJSON_EXCEPTIONS - } catch(...) { + // Restart, if we made it this far, the document *must* be accessible. + if(parser.parse_many(json,batch_size).get(docs)) { return EXIT_FAILURE; } + size_t bool_count2 = 0; + size_t total_count2 = 0; + for (auto doc : docs) { + total_count2++; + bool_count2 += doc.is_bool(); } -#endif + // They should agree!!! + if((total_count2 != total_count1) || (bool_count2 != bool_count1)) { return EXIT_FAILURE; } return 0; } diff --git a/tests/dom/document_stream_tests.cpp b/tests/dom/document_stream_tests.cpp index 15083848..b8c708e3 100644 --- a/tests/dom/document_stream_tests.cpp +++ b/tests/dom/document_stream_tests.cpp @@ -861,6 +861,23 @@ namespace document_stream_tests { return true; } + bool fuzzaccess() { + std::cout << "Running " << __func__ << std::endl; + // Issue 38801 in oss-fuzz + auto json = "\xff \n~~\n{}"_padded; + simdjson::dom::parser parser; + simdjson::dom::document_stream docs; + ASSERT_SUCCESS(parser.parse_many(json).get(docs)); + size_t bool_count = 0; + size_t total_count = 0; + + for (auto doc : docs) { + total_count++; + bool_count += doc.is_bool(); + } + return (bool_count == 0) && (bool_count == 0); + } + bool baby_fuzzer() { std::cout << "Running " << __func__ << std::endl; std::mt19937 gen(637); @@ -892,7 +909,8 @@ namespace document_stream_tests { } bool run() { - return baby_fuzzer() && + return fuzzaccess() && + baby_fuzzer() && issue1649() && adversarial_single_document_array() && adversarial_single_document() && diff --git a/tests/ondemand/ondemand_document_stream_tests.cpp b/tests/ondemand/ondemand_document_stream_tests.cpp index c3d904b4..ffb12f8d 100644 --- a/tests/ondemand/ondemand_document_stream_tests.cpp +++ b/tests/ondemand/ondemand_document_stream_tests.cpp @@ -511,6 +511,23 @@ namespace document_stream_tests { TEST_SUCCEED(); } + bool fuzzaccess() { + TEST_START(); + // Issue 38801 in oss-fuzz + auto json = "\xff \n~~\n{}"_padded; + ondemand::parser parser; + ondemand::document_stream docs; + ASSERT_SUCCESS(parser.iterate_many(json).get(docs)); + size_t bool_count = 0; + size_t total_count = 0; + for (auto doc : docs) { + total_count++; + bool b; + if(doc.get_bool().get(b) == SUCCESS) { bool_count +=b; } + } + return (bool_count == 0) && (bool_count == 0); + } + bool run() { return issue1683() &&