poppler/Dict.cc | 4 ++-- poppler/Dict.h | 2 +- poppler/Object.cc | 4 ++-- poppler/Object.h | 9 +++++---- poppler/Parser.cc | 19 +++++++++++++------ poppler/Parser.h | 7 ++++++- poppler/XRef.cc | 30 +++++++++++++++++++++++++----- poppler/XRef.h | 2 +- 8 files changed, 55 insertions(+), 22 deletions(-)
New commits: commit 3628837febb21bcd1b54f3fb737628ea59e5d95d Author: Albert Astals Cid <aa...@kde.org> Date: Sat Nov 20 22:15:08 2010 +0000 And now generalize the previous fix Works for loops of more than one item as in bug 28784 diff --git a/poppler/Dict.cc b/poppler/Dict.cc index 9749c25..2318e69 100644 --- a/poppler/Dict.cc +++ b/poppler/Dict.cc @@ -189,10 +189,10 @@ GBool Dict::is(char *type) { return (e = find("Type")) && e->val.isName(type); } -Object *Dict::lookup(char *key, Object *obj, int fetchOriginatorNum) { +Object *Dict::lookup(char *key, Object *obj, std::set<int> *fetchOriginatorNums) { DictEntry *e; - return (e = find(key)) ? e->val.fetch(xref, obj, fetchOriginatorNum) : obj->initNull(); + return (e = find(key)) ? e->val.fetch(xref, obj, fetchOriginatorNums) : obj->initNull(); } Object *Dict::lookupNF(char *key, Object *obj) { diff --git a/poppler/Dict.h b/poppler/Dict.h index bab0277..95c596c 100644 --- a/poppler/Dict.h +++ b/poppler/Dict.h @@ -72,7 +72,7 @@ public: // Look up an entry and return the value. Returns a null object // if <key> is not in the dictionary. - Object *lookup(char *key, Object *obj, int fetchOriginatorNum = -1); + Object *lookup(char *key, Object *obj, std::set<int> *fetchOriginatorNums = NULL); Object *lookupNF(char *key, Object *obj); GBool lookupInt(const char *key, const char *alt_key, int *value); diff --git a/poppler/Object.cc b/poppler/Object.cc index af89c29..4f7da80 100644 --- a/poppler/Object.cc +++ b/poppler/Object.cc @@ -115,9 +115,9 @@ Object *Object::copy(Object *obj) { return obj; } -Object *Object::fetch(XRef *xref, Object *obj, int fetchOriginatorNum) { +Object *Object::fetch(XRef *xref, Object *obj, std::set<int> *fetchOriginatorNums) { return (type == objRef && xref) ? - xref->fetch(ref.num, ref.gen, obj, fetchOriginatorNum) : copy(obj); + xref->fetch(ref.num, ref.gen, obj, fetchOriginatorNums) : copy(obj); } void Object::free() { diff --git a/poppler/Object.h b/poppler/Object.h index 8dd9063..72ff667 100644 --- a/poppler/Object.h +++ b/poppler/Object.h @@ -30,6 +30,7 @@ #pragma interface #endif +#include <set> #include <stdio.h> #include <string.h> #include "goo/gtypes.h" @@ -153,7 +154,7 @@ public: // If object is a Ref, fetch and return the referenced object. // Otherwise, return a copy of the object. - Object *fetch(XRef *xref, Object *obj, int fetchOriginatorNum = -1); + Object *fetch(XRef *xref, Object *obj, std::set<int> *fetchOriginatorNums = NULL); // Free object contents. void free(); @@ -212,7 +213,7 @@ public: void dictAdd(char *key, Object *val); void dictSet(char *key, Object *val); GBool dictIs(char *dictType); - Object *dictLookup(char *key, Object *obj, int fetchOriginatorNum = -1); + Object *dictLookup(char *key, Object *obj, std::set<int> *fetchOriginatorNums = NULL); Object *dictLookupNF(char *key, Object *obj); char *dictGetKey(int i); Object *dictGetVal(int i, Object *obj); @@ -299,8 +300,8 @@ inline GBool Object::dictIs(char *dictType) inline GBool Object::isDict(char *dictType) { return type == objDict && dictIs(dictType); } -inline Object *Object::dictLookup(char *key, Object *obj, int fetchOriginatorNum) - { OBJECT_TYPE_CHECK(objDict); return dict->lookup(key, obj, fetchOriginatorNum); } +inline Object *Object::dictLookup(char *key, Object *obj, std::set<int> *fetchOriginatorNums) + { OBJECT_TYPE_CHECK(objDict); return dict->lookup(key, obj, fetchOriginatorNums); } inline Object *Object::dictLookupNF(char *key, Object *obj) { OBJECT_TYPE_CHECK(objDict); return dict->lookupNF(key, obj); } diff --git a/poppler/Parser.cc b/poppler/Parser.cc index 8ee927c..85383cc 100644 --- a/poppler/Parser.cc +++ b/poppler/Parser.cc @@ -53,8 +53,15 @@ Parser::~Parser() { } Object *Parser::getObj(Object *obj, Guchar *fileKey, + CryptAlgorithm encAlgorithm, int keyLength, + int objNum, int objGen) { + std::set<int> fetchOriginatorNums; + return getObj(obj, fileKey, encAlgorithm, keyLength, objNum, objGen, &fetchOriginatorNums); +} + +Object *Parser::getObj(Object *obj, Guchar *fileKey, CryptAlgorithm encAlgorithm, int keyLength, - int objNum, int objGen) { + int objNum, int objGen, std::set<int> *fetchOriginatorNums) { char *key; Stream *str; Object obj2; @@ -78,7 +85,7 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey, obj->initArray(xref); while (!buf1.isCmd("]") && !buf1.isEOF()) obj->arrayAdd(getObj(&obj2, fileKey, encAlgorithm, keyLength, - objNum, objGen)); + objNum, objGen, fetchOriginatorNums)); if (buf1.isEOF()) error(getPos(), "End of file inside array"); shift(); @@ -99,7 +106,7 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey, gfree(key); break; } - obj->dictAdd(key, getObj(&obj2, fileKey, encAlgorithm, keyLength, objNum, objGen)); + obj->dictAdd(key, getObj(&obj2, fileKey, encAlgorithm, keyLength, objNum, objGen, fetchOriginatorNums)); } } if (buf1.isEOF()) @@ -108,7 +115,7 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey, // object streams if (allowStreams && buf2.isCmd("stream")) { if ((str = makeStream(obj, fileKey, encAlgorithm, keyLength, - objNum, objGen))) { + objNum, objGen, fetchOriginatorNums))) { obj->initStream(str); } else { obj->free(); @@ -162,7 +169,7 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey, Stream *Parser::makeStream(Object *dict, Guchar *fileKey, CryptAlgorithm encAlgorithm, int keyLength, - int objNum, int objGen) { + int objNum, int objGen, std::set<int> *fetchOriginatorNums) { Object obj; BaseStream *baseStr; Stream *str; @@ -173,7 +180,7 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey, pos = lexer->getPos(); // get length - dict->dictLookup("Length", &obj, objNum); + dict->dictLookup("Length", &obj, fetchOriginatorNums); if (obj.isInt()) { length = (Guint)obj.getInt(); obj.free(); diff --git a/poppler/Parser.h b/poppler/Parser.h index d09b23b..1420984 100644 --- a/poppler/Parser.h +++ b/poppler/Parser.h @@ -46,6 +46,11 @@ public: Object *getObj(Object *obj, Guchar *fileKey = NULL, CryptAlgorithm encAlgorithm = cryptRC4, int keyLength = 0, int objNum = 0, int objGen = 0); + + Object *getObj(Object *obj, Guchar *fileKey, + CryptAlgorithm encAlgorithm, int keyLength, + int objNum, int objGen, std::set<int> *fetchOriginatorNums); + // Get stream. Stream *getStream() { return lexer->getStream(); } @@ -63,7 +68,7 @@ private: Stream *makeStream(Object *dict, Guchar *fileKey, CryptAlgorithm encAlgorithm, int keyLength, - int objNum, int objGen); + int objNum, int objGen, std::set<int> *fetchOriginatorNums); void shift(int objNum = -1); }; diff --git a/poppler/XRef.cc b/poppler/XRef.cc index c7cdc89..dd7950f 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -967,14 +967,16 @@ GBool XRef::okToAssemble(GBool ignoreOwnerPW) { return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permAssemble); } -Object *XRef::fetch(int num, int gen, Object *obj, int fetchOriginatorNum) { +Object *XRef::fetch(int num, int gen, Object *obj, std::set<int> *fetchOriginatorNums) { XRefEntry *e; Parser *parser; Object obj1, obj2, obj3; + bool deleteFetchOriginatorNums = false; + std::pair<std::set<int>::iterator, bool> fetchInsertResult; // check for bogus ref - this can happen in corrupted PDF files - if (num < 0 || num >= size || num == fetchOriginatorNum) { - goto err; + if (num < 0 || num >= size || (fetchOriginatorNums != NULL && fetchOriginatorNums->find(num) != fetchOriginatorNums->end())) { + goto err2; } e = getEntry(num); @@ -982,6 +984,13 @@ Object *XRef::fetch(int num, int gen, Object *obj, int fetchOriginatorNum) { obj = e->obj.copy(obj); return obj; } + + if (fetchOriginatorNums == NULL) { + fetchOriginatorNums = new std::set<int>(); + deleteFetchOriginatorNums = true; + } + fetchInsertResult = fetchOriginatorNums->insert(num); + switch (e->type) { case xrefEntryUncompressed: @@ -1030,7 +1039,7 @@ Object *XRef::fetch(int num, int gen, Object *obj, int fetchOriginatorNum) { goto err; } parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, - encAlgorithm, keyLength, num, gen); + encAlgorithm, keyLength, num, gen, fetchOriginatorNums); obj1.free(); obj2.free(); obj3.free(); @@ -1070,10 +1079,21 @@ Object *XRef::fetch(int num, int gen, Object *obj, int fetchOriginatorNum) { default: goto err; } - + + if (deleteFetchOriginatorNums) { + delete fetchOriginatorNums; + } else { + fetchOriginatorNums->erase(fetchInsertResult.first); + } return obj; err: + if (deleteFetchOriginatorNums) { + delete fetchOriginatorNums; + } else { + fetchOriginatorNums->erase(fetchInsertResult.first); + } + err2: return obj->initNull(); } diff --git a/poppler/XRef.h b/poppler/XRef.h index de11428..ce4e9fe 100644 --- a/poppler/XRef.h +++ b/poppler/XRef.h @@ -101,7 +101,7 @@ public: Object *getCatalog(Object *obj) { return fetch(rootNum, rootGen, obj); } // Fetch an indirect reference. - Object *fetch(int num, int gen, Object *obj, int fetchOriginatorNum = -1); + Object *fetch(int num, int gen, Object *obj, std::set<int> *fetchOriginatorNums = NULL); // Return the document's Info dictionary (if any). Object *getDocInfo(Object *obj); _______________________________________________ poppler mailing list poppler@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/poppler