aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDF.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2018-02-16 23:25:27 +0100
committerJay Berkenbilt <ejb@ql.org>2018-02-19 03:06:27 +0100
commitd0e99f195a987c483bbb6c5449cf39bee34e08a1 (patch)
treecead8acd60cd14fd5d904ed380c750540cb361f3 /libqpdf/QPDF.cc
parentc2e16827b69f3d3ac3721cfcd608b87f28e2a13f (diff)
downloadqpdf-d0e99f195a987c483bbb6c5449cf39bee34e08a1.tar.zst
More robust handling of type errors
Give objects descriptions and context so it is possible to issue warnings instead of fatal errors for attempts to access objects of the wrong type.
Diffstat (limited to 'libqpdf/QPDF.cc')
-rw-r--r--libqpdf/QPDF.cc53
1 files changed, 27 insertions, 26 deletions
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index 31c8d8e2..31f13118 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -106,6 +106,7 @@ QPDF::Members::~Members()
QPDF::QPDF() :
m(new Members())
{
+ m->tokenizer.allowEOF();
}
QPDF::~QPDF()
@@ -272,10 +273,10 @@ QPDF::findHeader()
bool
QPDF::findStartxref()
{
- QPDFTokenizer::Token t = readToken(this->m->file, true);
+ QPDFTokenizer::Token t = readToken(this->m->file);
if (t == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "startxref"))
{
- t = readToken(this->m->file, true);
+ t = readToken(this->m->file);
if (t.getType() == QPDFTokenizer::tt_integer)
{
// Position in front of offset token
@@ -421,7 +422,7 @@ QPDF::reconstruct_xref(QPDFExc& e)
this->m->file->findAndSkipNextEOL();
qpdf_offset_t next_line_start = this->m->file->tell();
this->m->file->seek(line_start, SEEK_SET);
- QPDFTokenizer::Token t1 = readToken(this->m->file, true, MAX_LEN);
+ QPDFTokenizer::Token t1 = readToken(this->m->file, MAX_LEN);
qpdf_offset_t token_start =
this->m->file->tell() - t1.getValue().length();
if (token_start >= next_line_start)
@@ -440,9 +441,9 @@ QPDF::reconstruct_xref(QPDFExc& e)
if (t1.getType() == QPDFTokenizer::tt_integer)
{
QPDFTokenizer::Token t2 =
- readToken(this->m->file, true, MAX_LEN);
+ readToken(this->m->file, MAX_LEN);
QPDFTokenizer::Token t3 =
- readToken(this->m->file, true, MAX_LEN);
+ readToken(this->m->file, MAX_LEN);
if ((t2.getType() == QPDFTokenizer::tt_integer) &&
(t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj")))
{
@@ -1429,7 +1430,7 @@ bool
QPDF::findEndstream()
{
// Find endstream or endobj. Position the input at that token.
- QPDFTokenizer::Token t = readToken(this->m->file, true, 20);
+ QPDFTokenizer::Token t = readToken(this->m->file, 20);
if ((t.getType() == QPDFTokenizer::tt_word) &&
((t.getValue() == "endobj") ||
(t.getValue() == "endstream")))
@@ -1522,11 +1523,10 @@ QPDF::recoverStreamLength(PointerHolder<InputSource> input,
}
QPDFTokenizer::Token
-QPDF::readToken(PointerHolder<InputSource> input,
- bool allow_bad, size_t max_len)
+QPDF::readToken(PointerHolder<InputSource> input, size_t max_len)
{
return this->m->tokenizer.readToken(
- input, this->m->last_object_description, allow_bad, max_len);
+ input, this->m->last_object_description, true, max_len);
}
QPDFObjectHandle
@@ -1730,16 +1730,10 @@ QPDF::resolve(int objid, int generation)
}
ResolveRecorder rr(this, og);
- if (! this->m->obj_cache.count(og))
+ // PDF spec says unknown objects resolve to the null object.
+ if ((! this->m->obj_cache.count(og)) && this->m->xref_table.count(og))
{
- if (! this->m->xref_table.count(og))
- {
- // PDF spec says unknown objects resolve to the null object.
- return new QPDF_Null;
- }
-
QPDFXRefEntry const& entry = this->m->xref_table[og];
- bool success = false;
try
{
switch (entry.getType())
@@ -1768,7 +1762,6 @@ QPDF::resolve(int objid, int generation)
QUtil::int_to_string(generation) +
" has unexpected xref entry type");
}
- success = true;
}
catch (QPDFExc& e)
{
@@ -1782,16 +1775,24 @@ QPDF::resolve(int objid, int generation)
QUtil::int_to_string(generation) +
": error reading object: " + e.what()));
}
- if (! success)
- {
- QTC::TC("qpdf", "QPDF resolve failure to null");
- QPDFObjectHandle oh = QPDFObjectHandle::newNull();
- this->m->obj_cache[og] =
- ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1);
- }
+ }
+ if (this->m->obj_cache.count(og) == 0)
+ {
+ QTC::TC("qpdf", "QPDF resolve failure to null");
+ QPDFObjectHandle oh = QPDFObjectHandle::newNull();
+ this->m->obj_cache[og] =
+ ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1);
}
- return this->m->obj_cache[og].object;
+ PointerHolder<QPDFObject> result(this->m->obj_cache[og].object);
+ if (! result->hasDescription())
+ {
+ result->setDescription(
+ this,
+ "object " + QUtil::int_to_string(objid) + " " +
+ QUtil::int_to_string(generation));
+ }
+ return result;
}
void