summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2010-11-20 22:15:08 +0000
committerAlbert Astals Cid <aacid@kde.org>2010-11-20 22:15:08 +0000
commit3628837febb21bcd1b54f3fb737628ea59e5d95d (patch)
tree6bb4a9566b0c7524473f5e8eff5e877de28da968
parentb0555189a7fbd7f6a899e582783b9e0df44d5d6a (diff)
And now generalize the previous fix
Works for loops of more than one item as in bug 28784
-rw-r--r--poppler/Dict.cc4
-rw-r--r--poppler/Dict.h2
-rw-r--r--poppler/Object.cc4
-rw-r--r--poppler/Object.h9
-rw-r--r--poppler/Parser.cc19
-rw-r--r--poppler/Parser.h7
-rw-r--r--poppler/XRef.cc30
-rw-r--r--poppler/XRef.h2
8 files changed, 55 insertions, 22 deletions
diff --git a/poppler/Dict.cc b/poppler/Dict.cc
index 9749c25a..2318e692 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 bab02777..95c596c1 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 af89c290..4f7da80e 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 8dd9063b..72ff6678 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 8ee927ce..85383cc7 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 d09b23b4..14209846 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 c7cdc89a..dd7950f9 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 de114287..ce4e9fed 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);