Commit a8f224872995e3b90297693cfe1f381f01c555c8
1 parent
5ccc788b
handle files with object 0 as a real object
git-svn-id: svn+q:///qpdf/trunk@1049 71b93d88-0707-0410-a8cf-f5a4172ac649
Showing
6 changed files
with
35 additions
and
7 deletions
ChangeLog
| 1 | +2011-01-31 Jay Berkenbilt <ejb@ql.org> | |
| 2 | + | |
| 3 | + * libqpdf/QPDF.cc (readObjectAtOffset): use -1 rather than 0 when | |
| 4 | + reading an object at a given to indicate that no object number is | |
| 5 | + expected. This allows xref recovery to proceed even if a file | |
| 6 | + uses the invalid object number 0 as a regular object. | |
| 7 | + | |
| 8 | + * libqpdf/QPDF_linearization.cc (isLinearized): use -1 rather than | |
| 9 | + 0 as a sentintel for not having found the first object in the | |
| 10 | + file. Since -1 can never match the regular expression, this | |
| 11 | + prevents an infinite loop when checking a file that starts with | |
| 12 | + (erroneous) 0 0 obj. (Fixes qpdf-Bugs-3159950.) | |
| 13 | + | |
| 1 | 14 | 2010-10-04 Jay Berkenbilt <ejb@ql.org> |
| 2 | 15 | |
| 3 | 16 | * 2.2.2: release | ... | ... |
libqpdf/QPDF.cc
| ... | ... | @@ -782,7 +782,7 @@ QPDF::read_xrefStream(off_t xref_offset) |
| 782 | 782 | try |
| 783 | 783 | { |
| 784 | 784 | xref_obj = readObjectAtOffset( |
| 785 | - false, xref_offset, "xref stream", 0, 0, xobj, xgen); | |
| 785 | + false, xref_offset, "xref stream", -1, 0, xobj, xgen); | |
| 786 | 786 | } |
| 787 | 787 | catch (QPDFExc& e) |
| 788 | 788 | { |
| ... | ... | @@ -1580,7 +1580,7 @@ QPDF::readObjectAtOffset(bool try_recovery, |
| 1580 | 1580 | objid = atoi(tobjid.getValue().c_str()); |
| 1581 | 1581 | generation = atoi(tgen.getValue().c_str()); |
| 1582 | 1582 | |
| 1583 | - if (exp_objid && | |
| 1583 | + if ((exp_objid >= 0) && | |
| 1584 | 1584 | (! ((objid == exp_objid) && (generation == exp_generation)))) |
| 1585 | 1585 | { |
| 1586 | 1586 | QTC::TC("qpdf", "QPDF err wrong objid/generation"); |
| ... | ... | @@ -1593,7 +1593,7 @@ QPDF::readObjectAtOffset(bool try_recovery, |
| 1593 | 1593 | } |
| 1594 | 1594 | catch (QPDFExc& e) |
| 1595 | 1595 | { |
| 1596 | - if (exp_objid && try_recovery && this->attempt_recovery) | |
| 1596 | + if ((exp_objid >= 0) && try_recovery && this->attempt_recovery) | |
| 1597 | 1597 | { |
| 1598 | 1598 | // Try again after reconstructing xref table |
| 1599 | 1599 | reconstruct_xref(e); | ... | ... |
libqpdf/QPDF_linearization.cc
| ... | ... | @@ -95,9 +95,9 @@ QPDF::isLinearized() |
| 95 | 95 | static PCRE lindict_re("(?s:(\\d+)\\s+0\\s+obj\\s*<<)"); |
| 96 | 96 | |
| 97 | 97 | off_t offset = -1; |
| 98 | - int lindict_obj = 0; | |
| 98 | + int lindict_obj = -1; | |
| 99 | 99 | char* p = buf; |
| 100 | - while (lindict_obj == 0) | |
| 100 | + while (lindict_obj == -1) | |
| 101 | 101 | { |
| 102 | 102 | PCRE::Match m(lindict_re.match(p)); |
| 103 | 103 | if (m) |
| ... | ... | @@ -312,7 +312,7 @@ QPDF::readHintStream(Pipeline& pl, off_t offset, size_t length) |
| 312 | 312 | int obj; |
| 313 | 313 | int gen; |
| 314 | 314 | QPDFObjectHandle H = readObjectAtOffset( |
| 315 | - false, offset, "linearization hint stream", 0, 0, obj, gen); | |
| 315 | + false, offset, "linearization hint stream", -1, 0, obj, gen); | |
| 316 | 316 | ObjCache& oc = this->obj_cache[ObjGen(obj, gen)]; |
| 317 | 317 | off_t min_end_offset = oc.end_before_space; |
| 318 | 318 | off_t max_end_offset = oc.end_after_space; | ... | ... |
qpdf/qtest/qpdf.test
| ... | ... | @@ -111,7 +111,7 @@ $td->runtest("new stream", |
| 111 | 111 | show_ntests(); |
| 112 | 112 | # ---------- |
| 113 | 113 | $td->notify("--- Miscellaneous Tests ---"); |
| 114 | -$n_tests += 28; | |
| 114 | +$n_tests += 29; | |
| 115 | 115 | |
| 116 | 116 | $td->runtest("qpdf version", |
| 117 | 117 | {$td->COMMAND => "qpdf --version"}, |
| ... | ... | @@ -191,6 +191,14 @@ foreach my $file (qw(short-id long-id)) |
| 191 | 191 | $td->NORMALIZE_NEWLINES); |
| 192 | 192 | } |
| 193 | 193 | |
| 194 | +# Handle file with invalid xref table and object 0 as a regular object | |
| 195 | +# (bug 3159950). | |
| 196 | +$td->runtest("check obj0.pdf", | |
| 197 | + {$td->COMMAND => "qpdf --check obj0.pdf"}, | |
| 198 | + {$td->FILE => "obj0-check.out", | |
| 199 | + $td->EXIT_STATUS => 3}, | |
| 200 | + $td->NORMALIZE_NEWLINES); | |
| 201 | + | |
| 194 | 202 | # Min/Force version |
| 195 | 203 | $td->runtest("set min version", |
| 196 | 204 | {$td->COMMAND => "qpdf --min-version=1.6 good1.pdf a.pdf"}, | ... | ... |
qpdf/qtest/qpdf/obj0-check.out
0 → 100644
qpdf/qtest/qpdf/obj0.pdf
0 → 100644
No preview for this file type