aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--libqpdf/QPDF.cc6
-rw-r--r--libqpdf/QPDF_linearization.cc6
-rw-r--r--qpdf/qtest/qpdf.test10
-rw-r--r--qpdf/qtest/qpdf/obj0-check.out7
-rw-r--r--qpdf/qtest/qpdf/obj0.pdfbin0 -> 859 bytes
6 files changed, 35 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index ecc174b9..bcf8e9f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2011-01-31 Jay Berkenbilt <ejb@ql.org>
+
+ * 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 <ejb@ql.org>
* 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 00000000..0865102c
--- /dev/null
+++ b/qpdf/qtest/qpdf/obj0.pdf
Binary files differ