Commit 992b7911ce743a87589e6ddf0fe84de1ee4d9366
1 parent
e14e828c
Limit the number of warnings in json_fuzzer before giving up
Showing
2 changed files
with
12 additions
and
6 deletions
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<InputSource> 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<InputSource> 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) { | ... | ... |