2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 10:58:58 +00:00

better recovery for appended files with damaged cross-reference tables

git-svn-id: svn+q:///qpdf/trunk@649 71b93d88-0707-0410-a8cf-f5a4172ac649
This commit is contained in:
Jay Berkenbilt 2009-02-21 02:31:32 +00:00
parent 35d72c822e
commit 4499e04b57
4 changed files with 37 additions and 6 deletions

View File

@ -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> 2009-02-19 Jay Berkenbilt <ejb@ql.org>
* libqpdf/Pl_LZWDecoder.cc: correct logic error for previously * libqpdf/Pl_LZWDecoder.cc: correct logic error for previously

10
TODO
View File

@ -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 General
======= =======

View File

@ -333,7 +333,8 @@ class QPDF
int read_xrefTable(off_t offset); int read_xrefTable(off_t offset);
int read_xrefStream(off_t offset); int read_xrefStream(off_t offset);
int processXRefStream(off_t offset, QPDFObjectHandle& xref_stream); 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( QPDFObjectHandle readObject(
InputSource*, int objid, int generation, InputSource*, int objid, int generation,
bool in_object_stream); bool in_object_stream);

View File

@ -435,7 +435,7 @@ QPDF::reconstruct_xref(QPDFExc& e)
int obj = atoi(m.getMatch(1).c_str()); int obj = atoi(m.getMatch(1).c_str());
int gen = atoi(m.getMatch(2).c_str()); int gen = atoi(m.getMatch(2).c_str());
int offset = this->file.getLastOffset(); int offset = this->file.getLastOffset();
insertXrefEntry(obj, 1, offset, gen); insertXrefEntry(obj, 1, offset, gen, true);
} }
else if ((! this->trailer.isInitialized()) && else if ((! this->trailer.isInitialized()) &&
trailer_re.match(line.c_str())) trailer_re.match(line.c_str()))
@ -865,11 +865,15 @@ QPDF::processXRefStream(off_t xref_offset, QPDFObjectHandle& xref_obj)
} }
void 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 // 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 // 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 // If there is already an entry for this object and generation in
// the table, it means that a later xref table has registered this // 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); ObjGen og(obj, gen);
if (this->xref_table.count(og)) if (this->xref_table.count(og))
{ {
QTC::TC("qpdf", "QPDF xref reused object"); if (overwrite)
return; {
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)) if (this->deleted_objects.count(obj))
{ {