Commit 992b7911ce743a87589e6ddf0fe84de1ee4d9366

Authored by m-holger
1 parent e14e828c

Limit the number of warnings in json_fuzzer before giving up

fuzz/json_fuzzer.cc
... ... @@ -33,6 +33,7 @@ FuzzHelper::doChecks()
33 33 std::cerr << "runtime_error parsing json: " << e.what() << std::endl;
34 34 }
35 35 QPDF q;
  36 + q.setMaxWarnings(1000);
36 37 Buffer buf(const_cast<unsigned char*>(data), size);
37 38 auto is = std::make_shared<BufferInputSource>("json", &buf);
38 39 q.createFromJSON(is);
... ...
libqpdf/QPDF_json.cc
... ... @@ -233,12 +233,13 @@ provide_data(std::shared_ptr&lt;InputSource&gt; is, qpdf_offset_t start, qpdf_offset_t
233 233 class QPDF::JSONReactor: public JSON::Reactor
234 234 {
235 235 public:
236   - JSONReactor(QPDF& pdf, std::shared_ptr<InputSource> is, bool must_be_complete) :
  236 + JSONReactor(QPDF& pdf, std::shared_ptr<InputSource> is, bool must_be_complete, int max_warnings) :
237 237 pdf(pdf),
238 238 is(is),
239 239 must_be_complete(must_be_complete),
240 240 descr(std::make_shared<QPDFValue::Description>(
241   - QPDFValue::JSON_Descr(std::make_shared<std::string>(is->getName()), "")))
  241 + QPDFValue::JSON_Descr(std::make_shared<std::string>(is->getName()), ""))),
  242 + max_warnings(max_warnings)
242 243 {
243 244 for (auto& oc: pdf.m->obj_cache) {
244 245 if (oc.second.object->getTypeCode() == ::ot_reserved) {
... ... @@ -291,7 +292,8 @@ class QPDF::JSONReactor: public JSON::Reactor
291 292 std::shared_ptr<InputSource> is;
292 293 bool must_be_complete{true};
293 294 std::shared_ptr<QPDFValue::Description> descr;
294   - bool errors{false};
  295 + int errors{0};
  296 + int max_warnings{0};
295 297 bool saw_qpdf{false};
296 298 bool saw_qpdf_meta{false};
297 299 bool saw_objects{false};
... ... @@ -314,18 +316,21 @@ class QPDF::JSONReactor: public JSON::Reactor
314 316 void
315 317 QPDF::JSONReactor::error(qpdf_offset_t offset, std::string const& msg)
316 318 {
317   - this->errors = true;
  319 + ++errors;
318 320 std::string object = this->cur_object;
319 321 if (is->getName() != pdf.getFilename()) {
320 322 object += " from " + is->getName();
321 323 }
322 324 this->pdf.warn(qpdf_e_json, object, offset, msg);
  325 + if (max_warnings > 0 && errors >= max_warnings) {
  326 + throw std::runtime_error("errors found in JSON");
  327 + }
323 328 }
324 329  
325 330 bool
326 331 QPDF::JSONReactor::anyErrors() const
327 332 {
328   - return this->errors;
  333 + return errors > 0;
329 334 }
330 335  
331 336 void
... ... @@ -820,7 +825,7 @@ QPDF::updateFromJSON(std::shared_ptr&lt;InputSource&gt; is)
820 825 void
821 826 QPDF::importJSON(std::shared_ptr<InputSource> is, bool must_be_complete)
822 827 {
823   - JSONReactor reactor(*this, is, must_be_complete);
  828 + JSONReactor reactor(*this, is, must_be_complete, m->max_warnings);
824 829 try {
825 830 JSON::parse(*is, &reactor);
826 831 } catch (std::runtime_error& e) {
... ...