summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2010-11-03 00:02:02 +0000
committerAlbert Astals Cid <aacid@kde.org>2010-11-03 00:02:02 +0000
commitc2ff94b1600b8a5841a5e4627f014560ac460f1a (patch)
treefd6fbe234a6cf1e6e0f38fa09bca7e2f19d67420
parentcad66a7d25abdb6aa15f3aa94a35737b119b2659 (diff)
Do not loop forever in broken documents
StitchingFunctions that have themselves up in the parent chain are wrong
-rw-r--r--poppler/Function.cc22
-rw-r--r--poppler/Function.h6
2 files changed, 23 insertions, 5 deletions
diff --git a/poppler/Function.cc b/poppler/Function.cc
index 409b6790..a8fcd850 100644
--- a/poppler/Function.cc
+++ b/poppler/Function.cc
@@ -55,6 +55,11 @@ Function::~Function() {
}
Function *Function::parse(Object *funcObj) {
+ std::set<int> usedParents;
+ return parse(funcObj, &usedParents);
+}
+
+Function *Function::parse(Object *funcObj, std::set<int> *usedParents) {
Function *func;
Dict *dict;
int funcType;
@@ -84,7 +89,7 @@ Function *Function::parse(Object *funcObj) {
} else if (funcType == 2) {
func = new ExponentialFunction(funcObj, dict);
} else if (funcType == 3) {
- func = new StitchingFunction(funcObj, dict);
+ func = new StitchingFunction(funcObj, dict, usedParents);
} else if (funcType == 4) {
func = new PostScriptFunction(funcObj, dict);
} else {
@@ -569,7 +574,7 @@ void ExponentialFunction::transform(double *in, double *out) {
// StitchingFunction
//------------------------------------------------------------------------
-StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict) {
+StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict, std::set<int> *usedParents) {
Object obj1, obj2;
int i;
@@ -602,7 +607,18 @@ StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict) {
funcs[i] = NULL;
}
for (i = 0; i < k; ++i) {
- if (!(funcs[i] = Function::parse(obj1.arrayGet(i, &obj2)))) {
+ obj1.arrayGetNF(i, &obj2);
+ if (obj2.isRef()) {
+ const Ref ref = obj2.getRef();
+ if (usedParents->find(ref.num) == usedParents->end()) {
+ usedParents->insert(ref.num);
+ obj2.free();
+ obj1.arrayGet(i, &obj2);
+ } else {
+ goto err2;
+ }
+ }
+ if (!(funcs[i] = Function::parse(&obj2, usedParents))) {
goto err2;
}
if (i > 0 && (funcs[i]->getInputSize() != 1 ||
diff --git a/poppler/Function.h b/poppler/Function.h
index 2dcccb06..297401c9 100644
--- a/poppler/Function.h
+++ b/poppler/Function.h
@@ -13,7 +13,7 @@
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
-// Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2009, 2010 Albert Astals Cid <aacid@kde.org>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
@@ -29,6 +29,7 @@
#include "goo/gtypes.h"
#include "Object.h"
+#include <set>
class Dict;
class Stream;
@@ -83,6 +84,7 @@ public:
virtual GBool isOk() = 0;
protected:
+ static Function *parse(Object *funcObj, std::set<int> *usedParents);
int m, n; // size of input and output tuples
double // min and max values for function domain
@@ -184,7 +186,7 @@ private:
class StitchingFunction: public Function {
public:
- StitchingFunction(Object *funcObj, Dict *dict);
+ StitchingFunction(Object *funcObj, Dict *dict, std::set<int> *usedParents);
virtual ~StitchingFunction();
virtual Function *copy() { return new StitchingFunction(this); }
virtual int getType() { return 3; }