Commit 6f1041afb8e6d1f57169cd4c79f42a7c1ce94da8

Authored by Jay Berkenbilt
1 parent 9de29dab

Clarify intent in readObjectAtOffset

Rather than using object id -1 to mean "don't care", use object ID 0,
and clarify the difference between that use and indication of a direct
object.
libqpdf/QPDF.cc
@@ -1060,7 +1060,7 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset) @@ -1060,7 +1060,7 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset)
1060 QPDFObjectHandle xref_obj; 1060 QPDFObjectHandle xref_obj;
1061 try { 1061 try {
1062 xref_obj = readObjectAtOffset( 1062 xref_obj = readObjectAtOffset(
1063 - false, xref_offset, "xref stream", -1, 0, xobj, xgen); 1063 + false, xref_offset, "xref stream", 0, 0, xobj, xgen);
1064 } catch (QPDFExc&) { 1064 } catch (QPDFExc&) {
1065 // ignore -- report error below 1065 // ignore -- report error below
1066 } 1066 }
@@ -1782,10 +1782,25 @@ QPDF::readObjectAtOffset( @@ -1782,10 +1782,25 @@ QPDF::readObjectAtOffset(
1782 int& objid, 1782 int& objid,
1783 int& generation) 1783 int& generation)
1784 { 1784 {
  1785 + bool check_og = true;
  1786 + if (exp_objid == 0) {
  1787 + // This method uses an expect object ID of 0 to indicate that
  1788 + // we don't know or don't care what the actual object ID is at
  1789 + // this offset. This is true when we read the xref stream and
  1790 + // linearization hint streams. In this case, we don't verify
  1791 + // the expect object ID/generation against what was read from
  1792 + // the file. There is also no reason to attempt xref recovery
  1793 + // if we get a failure in this case since the read attempt was
  1794 + // not triggered by an xref lookup.
  1795 + check_og = false;
  1796 + try_recovery = false;
  1797 + } else {
  1798 + setLastObjectDescription(description, exp_objid, exp_generation);
  1799 + }
  1800 +
1785 if (!this->m->attempt_recovery) { 1801 if (!this->m->attempt_recovery) {
1786 try_recovery = false; 1802 try_recovery = false;
1787 } 1803 }
1788 - setLastObjectDescription(description, exp_objid, exp_generation);  
1789 1804
1790 // Special case: if offset is 0, just return null. Some PDF 1805 // Special case: if offset is 0, just return null. Some PDF
1791 // writers, in particular "Mac OS X 10.7.5 Quartz PDFContext", may 1806 // writers, in particular "Mac OS X 10.7.5 Quartz PDFContext", may
@@ -1839,7 +1854,7 @@ QPDF::readObjectAtOffset( @@ -1839,7 +1854,7 @@ QPDF::readObjectAtOffset(
1839 "object with ID 0"); 1854 "object with ID 0");
1840 } 1855 }
1841 1856
1842 - if ((exp_objid >= 0) && 1857 + if (check_og &&
1843 (!((objid == exp_objid) && (generation == exp_generation)))) { 1858 (!((objid == exp_objid) && (generation == exp_generation)))) {
1844 QTC::TC("qpdf", "QPDF err wrong objid/generation"); 1859 QTC::TC("qpdf", "QPDF err wrong objid/generation");
1845 QPDFExc e( 1860 QPDFExc e(
@@ -1859,7 +1874,7 @@ QPDF::readObjectAtOffset( @@ -1859,7 +1874,7 @@ QPDF::readObjectAtOffset(
1859 } 1874 }
1860 } 1875 }
1861 } catch (QPDFExc& e) { 1876 } catch (QPDFExc& e) {
1862 - if ((exp_objid >= 0) && try_recovery) { 1877 + if (try_recovery) {
1863 // Try again after reconstructing xref table 1878 // Try again after reconstructing xref table
1864 reconstruct_xref(e); 1879 reconstruct_xref(e);
1865 QPDFObjGen og(exp_objid, exp_generation); 1880 QPDFObjGen og(exp_objid, exp_generation);
libqpdf/QPDF_linearization.cc
@@ -328,7 +328,7 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length) @@ -328,7 +328,7 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length)
328 int obj; 328 int obj;
329 int gen; 329 int gen;
330 QPDFObjectHandle H = readObjectAtOffset( 330 QPDFObjectHandle H = readObjectAtOffset(
331 - false, offset, "linearization hint stream", -1, 0, obj, gen); 331 + false, offset, "linearization hint stream", 0, 0, obj, gen);
332 ObjCache& oc = this->m->obj_cache[QPDFObjGen(obj, gen)]; 332 ObjCache& oc = this->m->obj_cache[QPDFObjGen(obj, gen)];
333 qpdf_offset_t min_end_offset = oc.end_before_space; 333 qpdf_offset_t min_end_offset = oc.end_before_space;
334 qpdf_offset_t max_end_offset = oc.end_after_space; 334 qpdf_offset_t max_end_offset = oc.end_after_space;