From a8f224872995e3b90297693cfe1f381f01c555c8 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Mon, 31 Jan 2011 14:59:42 +0000 Subject: [PATCH] handle files with object 0 as a real object git-svn-id: svn+q:///qpdf/trunk@1049 71b93d88-0707-0410-a8cf-f5a4172ac649 --- ChangeLog | 13 +++++++++++++ libqpdf/QPDF.cc | 6 +++--- libqpdf/QPDF_linearization.cc | 6 +++--- qpdf/qtest/qpdf.test | 10 +++++++++- qpdf/qtest/qpdf/obj0-check.out | 7 +++++++ qpdf/qtest/qpdf/obj0.pdf | Bin 0 -> 859 bytes 6 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 qpdf/qtest/qpdf/obj0-check.out create mode 100644 qpdf/qtest/qpdf/obj0.pdf diff --git a/ChangeLog b/ChangeLog index ecc174b9..bcf8e9f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-01-31 Jay Berkenbilt + + * libqpdf/QPDF.cc (readObjectAtOffset): use -1 rather than 0 when + reading an object at a given to indicate that no object number is + expected. This allows xref recovery to proceed even if a file + uses the invalid object number 0 as a regular object. + + * libqpdf/QPDF_linearization.cc (isLinearized): use -1 rather than + 0 as a sentintel for not having found the first object in the + file. Since -1 can never match the regular expression, this + prevents an infinite loop when checking a file that starts with + (erroneous) 0 0 obj. (Fixes qpdf-Bugs-3159950.) + 2010-10-04 Jay Berkenbilt * 2.2.2: release diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index d176e516..35d9b400 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -782,7 +782,7 @@ QPDF::read_xrefStream(off_t xref_offset) try { xref_obj = readObjectAtOffset( - false, xref_offset, "xref stream", 0, 0, xobj, xgen); + false, xref_offset, "xref stream", -1, 0, xobj, xgen); } catch (QPDFExc& e) { @@ -1580,7 +1580,7 @@ QPDF::readObjectAtOffset(bool try_recovery, objid = atoi(tobjid.getValue().c_str()); generation = atoi(tgen.getValue().c_str()); - if (exp_objid && + if ((exp_objid >= 0) && (! ((objid == exp_objid) && (generation == exp_generation)))) { QTC::TC("qpdf", "QPDF err wrong objid/generation"); @@ -1593,7 +1593,7 @@ QPDF::readObjectAtOffset(bool try_recovery, } catch (QPDFExc& e) { - if (exp_objid && try_recovery && this->attempt_recovery) + if ((exp_objid >= 0) && try_recovery && this->attempt_recovery) { // Try again after reconstructing xref table reconstruct_xref(e); diff --git a/libqpdf/QPDF_linearization.cc b/libqpdf/QPDF_linearization.cc index ca3fdbae..4152a6da 100644 --- a/libqpdf/QPDF_linearization.cc +++ b/libqpdf/QPDF_linearization.cc @@ -95,9 +95,9 @@ QPDF::isLinearized() static PCRE lindict_re("(?s:(\\d+)\\s+0\\s+obj\\s*<<)"); off_t offset = -1; - int lindict_obj = 0; + int lindict_obj = -1; char* p = buf; - while (lindict_obj == 0) + while (lindict_obj == -1) { PCRE::Match m(lindict_re.match(p)); if (m) @@ -312,7 +312,7 @@ QPDF::readHintStream(Pipeline& pl, off_t offset, size_t length) int obj; int gen; QPDFObjectHandle H = readObjectAtOffset( - false, offset, "linearization hint stream", 0, 0, obj, gen); + false, offset, "linearization hint stream", -1, 0, obj, gen); ObjCache& oc = this->obj_cache[ObjGen(obj, gen)]; off_t min_end_offset = oc.end_before_space; off_t max_end_offset = oc.end_after_space; diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index 8257633d..2562f7c3 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -111,7 +111,7 @@ $td->runtest("new stream", show_ntests(); # ---------- $td->notify("--- Miscellaneous Tests ---"); -$n_tests += 28; +$n_tests += 29; $td->runtest("qpdf version", {$td->COMMAND => "qpdf --version"}, @@ -191,6 +191,14 @@ foreach my $file (qw(short-id long-id)) $td->NORMALIZE_NEWLINES); } +# Handle file with invalid xref table and object 0 as a regular object +# (bug 3159950). +$td->runtest("check obj0.pdf", + {$td->COMMAND => "qpdf --check obj0.pdf"}, + {$td->FILE => "obj0-check.out", + $td->EXIT_STATUS => 3}, + $td->NORMALIZE_NEWLINES); + # Min/Force version $td->runtest("set min version", {$td->COMMAND => "qpdf --min-version=1.6 good1.pdf a.pdf"}, diff --git a/qpdf/qtest/qpdf/obj0-check.out b/qpdf/qtest/qpdf/obj0-check.out new file mode 100644 index 00000000..f0a71b66 --- /dev/null +++ b/qpdf/qtest/qpdf/obj0-check.out @@ -0,0 +1,7 @@ +checking obj0.pdf +PDF Version: 1.3 +File is not encrypted +File is not linearized +WARNING: obj0.pdf: file is damaged +WARNING: obj0.pdf (object 1 0, file position 77): expected n n obj +WARNING: obj0.pdf: Attempting to reconstruct cross-reference table diff --git a/qpdf/qtest/qpdf/obj0.pdf b/qpdf/qtest/qpdf/obj0.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0865102ca586c86b27d90d9b5214f66f3829bd08 GIT binary patch literal 859 zcmah{OODe(5alDJV2L{v5|Kb+u-kUxM2ak!$yh}ELK2BZltrgg2}Yi7rrluzD=xqd zSaAd{z&0a<#0u8KCD>6V^nq%1xu(RjtsdrTt_AgJ)h3Ew ziXR5GqEH+YLMzcn1NHOBN{sDiONnJJ+j)v|W?n*mC=1Au&A~1 z+v>MeL$aiuP!cW-jLOL`G)`%CBF9@FMy=Tc63$~$bRoukGHxf2HE6awvA`$(omd!N z#MWxGgJqu4Jk7{`JJX(0cDage?57_PB5*rx7`8++5FX-KU?ljs-V`{kBNtv6aIZ1- Zz4-Esk==vbaBT`3Y7OR8tA{TV=Rbb%_8