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 | 2010-10-04 Jay Berkenbilt <ejb@ql.org> | 14 | 2010-10-04 Jay Berkenbilt <ejb@ql.org> |
| 2 | 15 | ||
| 3 | * 2.2.2: release | 16 | * 2.2.2: release |
libqpdf/QPDF.cc
| @@ -782,7 +782,7 @@ QPDF::read_xrefStream(off_t xref_offset) | @@ -782,7 +782,7 @@ QPDF::read_xrefStream(off_t xref_offset) | ||
| 782 | try | 782 | try |
| 783 | { | 783 | { |
| 784 | xref_obj = readObjectAtOffset( | 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 | catch (QPDFExc& e) | 787 | catch (QPDFExc& e) |
| 788 | { | 788 | { |
| @@ -1580,7 +1580,7 @@ QPDF::readObjectAtOffset(bool try_recovery, | @@ -1580,7 +1580,7 @@ QPDF::readObjectAtOffset(bool try_recovery, | ||
| 1580 | objid = atoi(tobjid.getValue().c_str()); | 1580 | objid = atoi(tobjid.getValue().c_str()); |
| 1581 | generation = atoi(tgen.getValue().c_str()); | 1581 | generation = atoi(tgen.getValue().c_str()); |
| 1582 | 1582 | ||
| 1583 | - if (exp_objid && | 1583 | + if ((exp_objid >= 0) && |
| 1584 | (! ((objid == exp_objid) && (generation == exp_generation)))) | 1584 | (! ((objid == exp_objid) && (generation == exp_generation)))) |
| 1585 | { | 1585 | { |
| 1586 | QTC::TC("qpdf", "QPDF err wrong objid/generation"); | 1586 | QTC::TC("qpdf", "QPDF err wrong objid/generation"); |
| @@ -1593,7 +1593,7 @@ QPDF::readObjectAtOffset(bool try_recovery, | @@ -1593,7 +1593,7 @@ QPDF::readObjectAtOffset(bool try_recovery, | ||
| 1593 | } | 1593 | } |
| 1594 | catch (QPDFExc& e) | 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 | // Try again after reconstructing xref table | 1598 | // Try again after reconstructing xref table |
| 1599 | reconstruct_xref(e); | 1599 | reconstruct_xref(e); |
libqpdf/QPDF_linearization.cc
| @@ -95,9 +95,9 @@ QPDF::isLinearized() | @@ -95,9 +95,9 @@ QPDF::isLinearized() | ||
| 95 | static PCRE lindict_re("(?s:(\\d+)\\s+0\\s+obj\\s*<<)"); | 95 | static PCRE lindict_re("(?s:(\\d+)\\s+0\\s+obj\\s*<<)"); |
| 96 | 96 | ||
| 97 | off_t offset = -1; | 97 | off_t offset = -1; |
| 98 | - int lindict_obj = 0; | 98 | + int lindict_obj = -1; |
| 99 | char* p = buf; | 99 | char* p = buf; |
| 100 | - while (lindict_obj == 0) | 100 | + while (lindict_obj == -1) |
| 101 | { | 101 | { |
| 102 | PCRE::Match m(lindict_re.match(p)); | 102 | PCRE::Match m(lindict_re.match(p)); |
| 103 | if (m) | 103 | if (m) |
| @@ -312,7 +312,7 @@ QPDF::readHintStream(Pipeline& pl, off_t offset, size_t length) | @@ -312,7 +312,7 @@ QPDF::readHintStream(Pipeline& pl, off_t offset, size_t length) | ||
| 312 | int obj; | 312 | int obj; |
| 313 | int gen; | 313 | int gen; |
| 314 | QPDFObjectHandle H = readObjectAtOffset( | 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 | ObjCache& oc = this->obj_cache[ObjGen(obj, gen)]; | 316 | ObjCache& oc = this->obj_cache[ObjGen(obj, gen)]; |
| 317 | off_t min_end_offset = oc.end_before_space; | 317 | off_t min_end_offset = oc.end_before_space; |
| 318 | off_t max_end_offset = oc.end_after_space; | 318 | off_t max_end_offset = oc.end_after_space; |
qpdf/qtest/qpdf.test
| @@ -111,7 +111,7 @@ $td->runtest("new stream", | @@ -111,7 +111,7 @@ $td->runtest("new stream", | ||
| 111 | show_ntests(); | 111 | show_ntests(); |
| 112 | # ---------- | 112 | # ---------- |
| 113 | $td->notify("--- Miscellaneous Tests ---"); | 113 | $td->notify("--- Miscellaneous Tests ---"); |
| 114 | -$n_tests += 28; | 114 | +$n_tests += 29; |
| 115 | 115 | ||
| 116 | $td->runtest("qpdf version", | 116 | $td->runtest("qpdf version", |
| 117 | {$td->COMMAND => "qpdf --version"}, | 117 | {$td->COMMAND => "qpdf --version"}, |
| @@ -191,6 +191,14 @@ foreach my $file (qw(short-id long-id)) | @@ -191,6 +191,14 @@ foreach my $file (qw(short-id long-id)) | ||
| 191 | $td->NORMALIZE_NEWLINES); | 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 | # Min/Force version | 202 | # Min/Force version |
| 195 | $td->runtest("set min version", | 203 | $td->runtest("set min version", |
| 196 | {$td->COMMAND => "qpdf --min-version=1.6 good1.pdf a.pdf"}, | 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