diff options
author | Jay Berkenbilt <ejb@ql.org> | 2018-02-16 23:25:27 +0100 |
---|---|---|
committer | Jay Berkenbilt <ejb@ql.org> | 2018-02-19 03:06:27 +0100 |
commit | d0e99f195a987c483bbb6c5449cf39bee34e08a1 (patch) | |
tree | cead8acd60cd14fd5d904ed380c750540cb361f3 /libqpdf/QPDF.cc | |
parent | c2e16827b69f3d3ac3721cfcd608b87f28e2a13f (diff) | |
download | qpdf-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.cc | 53 |
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 |