Commit 0ef2def8ad1f280adc34825b1588d9811d9ac031

Authored by m-holger
Committed by Jay Berkenbilt
1 parent c833c254

Delay adding offsets to object descriptions until necessary

libqpdf/QPDFParser.cc
@@ -288,8 +288,7 @@ QPDFParser::parse(bool& empty, bool content_stream) @@ -288,8 +288,7 @@ QPDFParser::parse(bool& empty, bool content_stream)
288 if (!indirect_ref && !is_null) { 288 if (!indirect_ref && !is_null) {
289 // No need to set description for direct nulls - they will 289 // No need to set description for direct nulls - they will
290 // become implicit. 290 // become implicit.
291 - auto os = input->getLastOffset();  
292 - setDescription(object, os, os); 291 + setDescription(object, input->getLastOffset());
293 } 292 }
294 set_offset = true; 293 set_offset = true;
295 olist.push_back(is_null ? null_oh : object); 294 olist.push_back(is_null ? null_oh : object);
@@ -312,7 +311,7 @@ QPDFParser::parse(bool& empty, bool content_stream) @@ -312,7 +311,7 @@ QPDFParser::parse(bool& empty, bool content_stream)
312 state_stack.pop_back(); 311 state_stack.pop_back();
313 if (old_state == st_array) { 312 if (old_state == st_array) {
314 object = QPDFObjectHandle::newArray(olist); 313 object = QPDFObjectHandle::newArray(olist);
315 - setDescription(object, offset, offset - 1); 314 + setDescription(object, offset - 1);
316 // The `offset` points to the next of "[". Set the rewind 315 // The `offset` points to the next of "[". Set the rewind
317 // offset to point to the beginning of "[". This has been 316 // offset to point to the beginning of "[". This has been
318 // explicitly tested with whitespace surrounding the array start 317 // explicitly tested with whitespace surrounding the array start
@@ -386,7 +385,7 @@ QPDFParser::parse(bool& empty, bool content_stream) @@ -386,7 +385,7 @@ QPDFParser::parse(bool& empty, bool content_stream)
386 dict["/Contents"].setParsedOffset(frame.contents_offset); 385 dict["/Contents"].setParsedOffset(frame.contents_offset);
387 } 386 }
388 object = QPDFObjectHandle::newDictionary(dict); 387 object = QPDFObjectHandle::newDictionary(dict);
389 - setDescription(object, offset, offset - 2); 388 + setDescription(object, offset - 2);
390 // The `offset` points to the next of "<<". Set the rewind 389 // The `offset` points to the next of "<<". Set the rewind
391 // offset to point to the beginning of "<<". This has been 390 // offset to point to the beginning of "<<". This has been
392 // explicitly tested with whitespace surrounding the dictionary 391 // explicitly tested with whitespace surrounding the dictionary
@@ -407,22 +406,16 @@ QPDFParser::parse(bool&amp; empty, bool content_stream) @@ -407,22 +406,16 @@ QPDFParser::parse(bool&amp; empty, bool content_stream)
407 object = QPDFObjectHandle::newNull(); 406 object = QPDFObjectHandle::newNull();
408 } 407 }
409 if (!set_offset) { 408 if (!set_offset) {
410 - setDescription(object, offset, offset); 409 + setDescription(object, offset);
411 } 410 }
412 return object; 411 return object;
413 } 412 }
414 413
415 void 414 void
416 -QPDFParser::setDescription(  
417 - QPDFObjectHandle oh,  
418 - qpdf_offset_t descr_offset,  
419 - qpdf_offset_t parsed_offset) const 415 +QPDFParser::setDescription(QPDFObjectHandle oh, qpdf_offset_t parsed_offset)
420 { 416 {
421 if (auto& obj = oh.obj) { 417 if (auto& obj = oh.obj) {
422 - auto descr = std::make_shared<std::string>(  
423 - input->getName() + ", " + object_description + " at offset " +  
424 - std::to_string(descr_offset));  
425 - obj->setDescription(context, descr, parsed_offset); 418 + obj->setDescription(context, description, parsed_offset);
426 } 419 }
427 } 420 }
428 421
libqpdf/qpdf/QPDFParser.hh
@@ -20,7 +20,9 @@ class QPDFParser @@ -20,7 +20,9 @@ class QPDFParser
20 object_description(object_description), 20 object_description(object_description),
21 tokenizer(tokenizer), 21 tokenizer(tokenizer),
22 decrypter(decrypter), 22 decrypter(decrypter),
23 - context(context) 23 + context(context),
  24 + description(std::make_shared<std::string>(
  25 + input->getName() + ", " + object_description + " at offset $PO"))
24 { 26 {
25 } 27 }
26 virtual ~QPDFParser() = default; 28 virtual ~QPDFParser() = default;
@@ -40,15 +42,13 @@ class QPDFParser @@ -40,15 +42,13 @@ class QPDFParser
40 void warn(qpdf_offset_t offset, std::string const& msg) const; 42 void warn(qpdf_offset_t offset, std::string const& msg) const;
41 void warn(std::string const& msg) const; 43 void warn(std::string const& msg) const;
42 static void warn(QPDF*, QPDFExc const&); 44 static void warn(QPDF*, QPDFExc const&);
43 - void setDescription(  
44 - QPDFObjectHandle oh,  
45 - qpdf_offset_t descr_offset,  
46 - qpdf_offset_t parsed_offset = -1) const; 45 + void setDescription(QPDFObjectHandle oh, qpdf_offset_t parsed_offset);
47 std::shared_ptr<InputSource> input; 46 std::shared_ptr<InputSource> input;
48 std::string const& object_description; 47 std::string const& object_description;
49 QPDFTokenizer& tokenizer; 48 QPDFTokenizer& tokenizer;
50 QPDFObjectHandle::StringDecrypter* decrypter; 49 QPDFObjectHandle::StringDecrypter* decrypter;
51 QPDF* context; 50 QPDF* context;
  51 + std::shared_ptr<std::string> description;
52 }; 52 };
53 53
54 #endif // QPDFPARSER_HH 54 #endif // QPDFPARSER_HH
libqpdf/qpdf/QPDFValue.hh
@@ -52,6 +52,13 @@ class QPDFValue @@ -52,6 +52,13 @@ class QPDFValue
52 if (auto pos = description.find("$OG"); pos != std::string::npos) { 52 if (auto pos = description.find("$OG"); pos != std::string::npos) {
53 description.replace(pos, 3, og.unparse(' ')); 53 description.replace(pos, 3, og.unparse(' '));
54 } 54 }
  55 + if (auto pos = description.find("$PO"); pos != std::string::npos) {
  56 + qpdf_offset_t shift = (type_code == ::ot_dictionary) ? 2
  57 + : (type_code == ::ot_array) ? 1
  58 + : 0;
  59 +
  60 + description.replace(pos, 3, std::to_string(parsed_offset + shift));
  61 + }
55 return qpdf != nullptr; 62 return qpdf != nullptr;
56 } 63 }
57 bool 64 bool