diff --git a/fuzz/json_fuzzer.cc b/fuzz/json_fuzzer.cc index 3ac644a7..8b46a0ad 100644 --- a/fuzz/json_fuzzer.cc +++ b/fuzz/json_fuzzer.cc @@ -33,6 +33,7 @@ FuzzHelper::doChecks() std::cerr << "runtime_error parsing json: " << e.what() << std::endl; } QPDF q; + q.setMaxWarnings(1000); Buffer buf(const_cast(data), size); auto is = std::make_shared("json", &buf); q.createFromJSON(is); diff --git a/libqpdf/QPDF_json.cc b/libqpdf/QPDF_json.cc index b06b70c9..ffdd7112 100644 --- a/libqpdf/QPDF_json.cc +++ b/libqpdf/QPDF_json.cc @@ -233,12 +233,13 @@ provide_data(std::shared_ptr is, qpdf_offset_t start, qpdf_offset_t class QPDF::JSONReactor: public JSON::Reactor { public: - JSONReactor(QPDF& pdf, std::shared_ptr is, bool must_be_complete) : + JSONReactor(QPDF& pdf, std::shared_ptr is, bool must_be_complete, int max_warnings) : pdf(pdf), is(is), must_be_complete(must_be_complete), descr(std::make_shared( - QPDFValue::JSON_Descr(std::make_shared(is->getName()), ""))) + QPDFValue::JSON_Descr(std::make_shared(is->getName()), ""))), + max_warnings(max_warnings) { for (auto& oc: pdf.m->obj_cache) { if (oc.second.object->getTypeCode() == ::ot_reserved) { @@ -291,7 +292,8 @@ class QPDF::JSONReactor: public JSON::Reactor std::shared_ptr is; bool must_be_complete{true}; std::shared_ptr descr; - bool errors{false}; + int errors{0}; + int max_warnings{0}; bool saw_qpdf{false}; bool saw_qpdf_meta{false}; bool saw_objects{false}; @@ -314,18 +316,21 @@ class QPDF::JSONReactor: public JSON::Reactor void QPDF::JSONReactor::error(qpdf_offset_t offset, std::string const& msg) { - this->errors = true; + ++errors; std::string object = this->cur_object; if (is->getName() != pdf.getFilename()) { object += " from " + is->getName(); } this->pdf.warn(qpdf_e_json, object, offset, msg); + if (max_warnings > 0 && errors >= max_warnings) { + throw std::runtime_error("errors found in JSON"); + } } bool QPDF::JSONReactor::anyErrors() const { - return this->errors; + return errors > 0; } void @@ -820,7 +825,7 @@ QPDF::updateFromJSON(std::shared_ptr is) void QPDF::importJSON(std::shared_ptr is, bool must_be_complete) { - JSONReactor reactor(*this, is, must_be_complete); + JSONReactor reactor(*this, is, must_be_complete, m->max_warnings); try { JSON::parse(*is, &reactor); } catch (std::runtime_error& e) {