summaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDF.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2013-06-15 18:38:25 +0200
committerJay Berkenbilt <ejb@ql.org>2013-06-15 18:40:01 +0200
commita85007cb0d9bb8af8f0a32bda3ace19aaff97816 (patch)
tree83bd0cbe40e6f793d954c1351e97830ab966203f /libqpdf/QPDF.cc
parenta1d5a3e916a23ae22ee65b05df1789435a72d67c (diff)
downloadqpdf-a85007cb0d9bb8af8f0a32bda3ace19aaff97816.tar.zst
Handle more broken files
Space rather than newline after xref, missing /ID in trailer for encrypted file. This enables qpdf to handle some files that xpdf can handle. Adobe reader can't necessarily handle them.
Diffstat (limited to 'libqpdf/QPDF.cc')
-rw-r--r--libqpdf/QPDF.cc17
1 files changed, 14 insertions, 3 deletions
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index 00e13ca0..ad742daa 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -430,11 +430,22 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
std::map<int, int> free_table;
while (xref_offset)
{
+ char buf[7];
+ memset(buf, 0, sizeof(buf));
this->file->seek(xref_offset, SEEK_SET);
- std::string line = this->file->readLine(50);
- if (line == "xref")
+ this->file->read(buf, sizeof(buf) - 1);
+ // The PDF spec says xref must be followed by a line
+ // terminator, but files exist in the wild where it is
+ // terminated by arbitrary whitespace.
+ PCRE xref_re("^xref\\s+");
+ PCRE::Match m = xref_re.match(buf);
+ if (m)
{
- xref_offset = read_xrefTable(this->file->tell());
+ QTC::TC("qpdf", "QPDF xref space",
+ ((buf[4] == '\n') ? 0 :
+ (buf[4] == '\r') ? 1 :
+ (buf[4] == ' ') ? 2 : 9999));
+ xref_offset = read_xrefTable(xref_offset + m.getMatch(0).length());
}
else
{