Commit f099246b525a6c821706962299816c6faa560b25
1 parent
7ae1e80f
Refactor removal of reserved objects in QPDF::JSONReactor
At the end of importing a JSON file, scan the object cache for reserved objects and replace with null objects.
Showing
1 changed file
with
17 additions
and
23 deletions
libqpdf/QPDF_json.cc
| ... | ... | @@ -6,6 +6,7 @@ |
| 6 | 6 | #include <qpdf/QIntC.hh> |
| 7 | 7 | #include <qpdf/QPDFObject_private.hh> |
| 8 | 8 | #include <qpdf/QPDFValue.hh> |
| 9 | +#include <qpdf/QPDF_Null.hh> | |
| 9 | 10 | #include <qpdf/QTC.hh> |
| 10 | 11 | #include <qpdf/QUtil.hh> |
| 11 | 12 | #include <algorithm> |
| ... | ... | @@ -234,6 +235,11 @@ class QPDF::JSONReactor: public JSON::Reactor |
| 234 | 235 | descr(std::make_shared<QPDFValue::Description>(QPDFValue::JSON_Descr( |
| 235 | 236 | std::make_shared<std::string>(is->getName()), ""))) |
| 236 | 237 | { |
| 238 | + for (auto& oc: pdf.m->obj_cache) { | |
| 239 | + if (oc.second.object->getTypeCode() == ::ot_reserved) { | |
| 240 | + reserved.insert(oc.first); | |
| 241 | + } | |
| 242 | + } | |
| 237 | 243 | } |
| 238 | 244 | virtual ~JSONReactor() = default; |
| 239 | 245 | virtual void dictionaryStart() override; |
| ... | ... | @@ -265,7 +271,6 @@ class QPDF::JSONReactor: public JSON::Reactor |
| 265 | 271 | void setObjectDescription(QPDFObjectHandle& oh, JSON const& value); |
| 266 | 272 | QPDFObjectHandle makeObject(JSON const& value); |
| 267 | 273 | void error(qpdf_offset_t offset, std::string const& message); |
| 268 | - QPDFObjectHandle reserveObject(int obj, int gen); | |
| 269 | 274 | void replaceObject( |
| 270 | 275 | QPDFObjectHandle to_replace, |
| 271 | 276 | QPDFObjectHandle replacement, |
| ... | ... | @@ -416,27 +421,17 @@ QPDF::JSONReactor::containerEnd(JSON const& value) |
| 416 | 421 | object_stack.pop_back(); |
| 417 | 422 | } |
| 418 | 423 | } else if ((state == st_top) && (from_state == st_qpdf)) { |
| 419 | - for (auto const& og: this->reserved) { | |
| 420 | - // Handle dangling indirect object references which the | |
| 421 | - // PDF spec says to treat as nulls. It's tempting to make | |
| 422 | - // this an error, but that would be wrong since valid | |
| 423 | - // input files may have these. | |
| 424 | - QTC::TC("qpdf", "QPDF_json non-trivial null reserved"); | |
| 425 | - this->pdf.replaceObject(og, QPDFObjectHandle::newNull()); | |
| 424 | + // Handle dangling indirect object references which the PDF spec says to | |
| 425 | + // treat as nulls. It's tempting to make this an error, but that would | |
| 426 | + // be wrong since valid input files may have these. | |
| 427 | + for (auto& oc: pdf.m->obj_cache) { | |
| 428 | + if (oc.second.object->getTypeCode() == ::ot_reserved && | |
| 429 | + reserved.count(oc.first) == 0) { | |
| 430 | + QTC::TC("qpdf", "QPDF_json non-trivial null reserved"); | |
| 431 | + pdf.updateCache(oc.first, QPDF_Null::create(), -1, -1); | |
| 432 | + } | |
| 426 | 433 | } |
| 427 | - this->reserved.clear(); | |
| 428 | - } | |
| 429 | -} | |
| 430 | - | |
| 431 | -QPDFObjectHandle | |
| 432 | -QPDF::JSONReactor::reserveObject(int obj, int gen) | |
| 433 | -{ | |
| 434 | - QPDFObjGen og(obj, gen); | |
| 435 | - auto oh = pdf.reserveObjectIfNotExists(og); | |
| 436 | - if (oh.isReserved()) { | |
| 437 | - this->reserved.insert(og); | |
| 438 | 434 | } |
| 439 | - return oh; | |
| 440 | 435 | } |
| 441 | 436 | |
| 442 | 437 | void |
| ... | ... | @@ -446,7 +441,6 @@ QPDF::JSONReactor::replaceObject( |
| 446 | 441 | JSON const& value) |
| 447 | 442 | { |
| 448 | 443 | auto og = to_replace.getObjGen(); |
| 449 | - this->reserved.erase(og); | |
| 450 | 444 | this->pdf.replaceObject(og, replacement); |
| 451 | 445 | auto oh = pdf.getObject(og); |
| 452 | 446 | setObjectDescription(oh, value); |
| ... | ... | @@ -564,7 +558,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value) |
| 564 | 558 | this->cur_object = "trailer"; |
| 565 | 559 | } else if (is_obj_key(key, obj, gen)) { |
| 566 | 560 | this->cur_object = key; |
| 567 | - auto oh = reserveObject(obj, gen); | |
| 561 | + auto oh = pdf.reserveObjectIfNotExists(QPDFObjGen(obj, gen)); | |
| 568 | 562 | object_stack.push_back(oh); |
| 569 | 563 | nestedState(key, value, st_object_top); |
| 570 | 564 | } else { |
| ... | ... | @@ -763,7 +757,7 @@ QPDF::JSONReactor::makeObject(JSON const& value) |
| 763 | 757 | int gen = 0; |
| 764 | 758 | std::string str; |
| 765 | 759 | if (is_indirect_object(str_v, obj, gen)) { |
| 766 | - result = reserveObject(obj, gen); | |
| 760 | + result = pdf.reserveObjectIfNotExists(QPDFObjGen(obj, gen)); | |
| 767 | 761 | } else if (is_unicode_string(str_v, str)) { |
| 768 | 762 | result = QPDFObjectHandle::newUnicodeString(str); |
| 769 | 763 | } else if (is_binary_string(str_v, str)) { | ... | ... |