Commit f099246b525a6c821706962299816c6faa560b25

Authored by m-holger
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 +6,7 @@
6 #include <qpdf/QIntC.hh> 6 #include <qpdf/QIntC.hh>
7 #include <qpdf/QPDFObject_private.hh> 7 #include <qpdf/QPDFObject_private.hh>
8 #include <qpdf/QPDFValue.hh> 8 #include <qpdf/QPDFValue.hh>
  9 +#include <qpdf/QPDF_Null.hh>
9 #include <qpdf/QTC.hh> 10 #include <qpdf/QTC.hh>
10 #include <qpdf/QUtil.hh> 11 #include <qpdf/QUtil.hh>
11 #include <algorithm> 12 #include <algorithm>
@@ -234,6 +235,11 @@ class QPDF::JSONReactor: public JSON::Reactor @@ -234,6 +235,11 @@ class QPDF::JSONReactor: public JSON::Reactor
234 descr(std::make_shared<QPDFValue::Description>(QPDFValue::JSON_Descr( 235 descr(std::make_shared<QPDFValue::Description>(QPDFValue::JSON_Descr(
235 std::make_shared<std::string>(is->getName()), ""))) 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 virtual ~JSONReactor() = default; 244 virtual ~JSONReactor() = default;
239 virtual void dictionaryStart() override; 245 virtual void dictionaryStart() override;
@@ -265,7 +271,6 @@ class QPDF::JSONReactor: public JSON::Reactor @@ -265,7 +271,6 @@ class QPDF::JSONReactor: public JSON::Reactor
265 void setObjectDescription(QPDFObjectHandle& oh, JSON const& value); 271 void setObjectDescription(QPDFObjectHandle& oh, JSON const& value);
266 QPDFObjectHandle makeObject(JSON const& value); 272 QPDFObjectHandle makeObject(JSON const& value);
267 void error(qpdf_offset_t offset, std::string const& message); 273 void error(qpdf_offset_t offset, std::string const& message);
268 - QPDFObjectHandle reserveObject(int obj, int gen);  
269 void replaceObject( 274 void replaceObject(
270 QPDFObjectHandle to_replace, 275 QPDFObjectHandle to_replace,
271 QPDFObjectHandle replacement, 276 QPDFObjectHandle replacement,
@@ -416,27 +421,17 @@ QPDF::JSONReactor::containerEnd(JSON const&amp; value) @@ -416,27 +421,17 @@ QPDF::JSONReactor::containerEnd(JSON const&amp; value)
416 object_stack.pop_back(); 421 object_stack.pop_back();
417 } 422 }
418 } else if ((state == st_top) && (from_state == st_qpdf)) { 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 void 437 void
@@ -446,7 +441,6 @@ QPDF::JSONReactor::replaceObject( @@ -446,7 +441,6 @@ QPDF::JSONReactor::replaceObject(
446 JSON const& value) 441 JSON const& value)
447 { 442 {
448 auto og = to_replace.getObjGen(); 443 auto og = to_replace.getObjGen();
449 - this->reserved.erase(og);  
450 this->pdf.replaceObject(og, replacement); 444 this->pdf.replaceObject(og, replacement);
451 auto oh = pdf.getObject(og); 445 auto oh = pdf.getObject(og);
452 setObjectDescription(oh, value); 446 setObjectDescription(oh, value);
@@ -564,7 +558,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const&amp; key, JSON const&amp; value) @@ -564,7 +558,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const&amp; key, JSON const&amp; value)
564 this->cur_object = "trailer"; 558 this->cur_object = "trailer";
565 } else if (is_obj_key(key, obj, gen)) { 559 } else if (is_obj_key(key, obj, gen)) {
566 this->cur_object = key; 560 this->cur_object = key;
567 - auto oh = reserveObject(obj, gen); 561 + auto oh = pdf.reserveObjectIfNotExists(QPDFObjGen(obj, gen));
568 object_stack.push_back(oh); 562 object_stack.push_back(oh);
569 nestedState(key, value, st_object_top); 563 nestedState(key, value, st_object_top);
570 } else { 564 } else {
@@ -763,7 +757,7 @@ QPDF::JSONReactor::makeObject(JSON const&amp; value) @@ -763,7 +757,7 @@ QPDF::JSONReactor::makeObject(JSON const&amp; value)
763 int gen = 0; 757 int gen = 0;
764 std::string str; 758 std::string str;
765 if (is_indirect_object(str_v, obj, gen)) { 759 if (is_indirect_object(str_v, obj, gen)) {
766 - result = reserveObject(obj, gen); 760 + result = pdf.reserveObjectIfNotExists(QPDFObjGen(obj, gen));
767 } else if (is_unicode_string(str_v, str)) { 761 } else if (is_unicode_string(str_v, str)) {
768 result = QPDFObjectHandle::newUnicodeString(str); 762 result = QPDFObjectHandle::newUnicodeString(str);
769 } else if (is_binary_string(str_v, str)) { 763 } else if (is_binary_string(str_v, str)) {