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 +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& value) | @@ -416,27 +421,17 @@ QPDF::JSONReactor::containerEnd(JSON const& 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& key, JSON const& value) | @@ -564,7 +558,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& 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& value) | @@ -763,7 +757,7 @@ QPDF::JSONReactor::makeObject(JSON const& 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)) { |