aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2009-02-21 03:31:32 +0100
committerJay Berkenbilt <ejb@ql.org>2009-02-21 03:31:32 +0100
commit4499e04b5714747eb954420f8133e650a5137d45 (patch)
treef7fba2f5f901ccb6081469af84285714b62fd7a6
parent35d72c822e07017feac2c6be02c1d402f4992728 (diff)
downloadqpdf-4499e04b5714747eb954420f8133e650a5137d45.tar.zst
better recovery for appended files with damaged cross-reference tables
git-svn-id: svn+q:///qpdf/trunk@649 71b93d88-0707-0410-a8cf-f5a4172ac649
-rw-r--r--ChangeLog8
-rw-r--r--TODO10
-rw-r--r--include/qpdf/QPDF.hh3
-rw-r--r--libqpdf/QPDF.cc22
4 files changed, 37 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index e327b7b3..da5150df 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-02-20 Jay Berkenbilt <ejb@ql.org>
+
+ * libqpdf/QPDF.cc (QPDF::insertXrefEntry): when recovering the
+ cross-reference table, have objects we encounter later in the file
+ supersede those we found earlier. This improves the chances of
+ being able to recover appended files with damaged cross-reference
+ tables.
+
2009-02-19 Jay Berkenbilt <ejb@ql.org>
* libqpdf/Pl_LZWDecoder.cc: correct logic error for previously
diff --git a/TODO b/TODO
index d705187e..e5097fb7 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,13 @@
+2.0.4
+=====
+
+ * Spell check to fix types in messages and comments. Known type in
+ "damanged".
+
+ * Exit with a different exit code if warning are found during check
+ mode.
+
+
General
=======
diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh
index db5c91e6..f57d4c94 100644
--- a/include/qpdf/QPDF.hh
+++ b/include/qpdf/QPDF.hh
@@ -333,7 +333,8 @@ class QPDF
int read_xrefTable(off_t offset);
int read_xrefStream(off_t offset);
int processXRefStream(off_t offset, QPDFObjectHandle& xref_stream);
- void insertXrefEntry(int obj, int f0, int f1, int f2);
+ void insertXrefEntry(int obj, int f0, int f1, int f2,
+ bool overwrite = false);
QPDFObjectHandle readObject(
InputSource*, int objid, int generation,
bool in_object_stream);
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index 6f51fa2c..a90cddc2 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -435,7 +435,7 @@ QPDF::reconstruct_xref(QPDFExc& e)
int obj = atoi(m.getMatch(1).c_str());
int gen = atoi(m.getMatch(2).c_str());
int offset = this->file.getLastOffset();
- insertXrefEntry(obj, 1, offset, gen);
+ insertXrefEntry(obj, 1, offset, gen, true);
}
else if ((! this->trailer.isInitialized()) &&
trailer_re.match(line.c_str()))
@@ -865,11 +865,15 @@ QPDF::processXRefStream(off_t xref_offset, QPDFObjectHandle& xref_obj)
}
void
-QPDF::insertXrefEntry(int obj, int f0, int f1, int f2)
+QPDF::insertXrefEntry(int obj, int f0, int f1, int f2, bool overwrite)
{
// Populate the xref table in such a way that the first reference
// to an object that we see, which is the one in the latest xref
- // table in which it appears, is the one that gets stored.
+ // table in which it appears, is the one that gets stored. This
+ // works because we are reading more recent appends before older
+ // ones. Exception: if overwrite is true, then replace any
+ // existing object. This is used in xref recovery mode, which
+ // reads the file from beginning to end.
// If there is already an entry for this object and generation in
// the table, it means that a later xref table has registered this
@@ -879,8 +883,16 @@ QPDF::insertXrefEntry(int obj, int f0, int f1, int f2)
ObjGen og(obj, gen);
if (this->xref_table.count(og))
{
- QTC::TC("qpdf", "QPDF xref reused object");
- return;
+ if (overwrite)
+ {
+ QTC::TC("qpdf", "QPDF xref overwrite object");
+ this->xref_table.erase(og);
+ }
+ else
+ {
+ QTC::TC("qpdf", "QPDF xref reused object");
+ return;
+ }
}
if (this->deleted_objects.count(obj))
{