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 1060 QPDFObjectHandle xref_obj;
1061 1061 try {
1062 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 1064 } catch (QPDFExc&) {
1065 1065 // ignore -- report error below
1066 1066 }
... ... @@ -1782,10 +1782,25 @@ QPDF::readObjectAtOffset(
1782 1782 int& objid,
1783 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 1801 if (!this->m->attempt_recovery) {
1786 1802 try_recovery = false;
1787 1803 }
1788   - setLastObjectDescription(description, exp_objid, exp_generation);
1789 1804  
1790 1805 // Special case: if offset is 0, just return null. Some PDF
1791 1806 // writers, in particular "Mac OS X 10.7.5 Quartz PDFContext", may
... ... @@ -1839,7 +1854,7 @@ QPDF::readObjectAtOffset(
1839 1854 "object with ID 0");
1840 1855 }
1841 1856  
1842   - if ((exp_objid >= 0) &&
  1857 + if (check_og &&
1843 1858 (!((objid == exp_objid) && (generation == exp_generation)))) {
1844 1859 QTC::TC("qpdf", "QPDF err wrong objid/generation");
1845 1860 QPDFExc e(
... ... @@ -1859,7 +1874,7 @@ QPDF::readObjectAtOffset(
1859 1874 }
1860 1875 }
1861 1876 } catch (QPDFExc& e) {
1862   - if ((exp_objid >= 0) && try_recovery) {
  1877 + if (try_recovery) {
1863 1878 // Try again after reconstructing xref table
1864 1879 reconstruct_xref(e);
1865 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 328 int obj;
329 329 int gen;
330 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 332 ObjCache& oc = this->m->obj_cache[QPDFObjGen(obj, gen)];
333 333 qpdf_offset_t min_end_offset = oc.end_before_space;
334 334 qpdf_offset_t max_end_offset = oc.end_after_space;
... ...