summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2023-04-05 00:19:04 +0200
committerAlbert Astals Cid <aacid@kde.org>2023-04-12 22:47:41 +0200
commit1be35ee8b2d6418dfafc6a8a9bbf6d70eafb2d2e (patch)
treede67315556be1c72ff208696b14863eed68ccb9e
parent8354c73ea0516a9d4a4bdf68da5c5392498b286d (diff)
Fix stack overflow in PostScriptFunction::parseCode
By using a pointer instead of a variable things are on the heap. Fixes issue #1381
-rw-r--r--poppler/Function.cc40
-rw-r--r--poppler/Function.h2
2 files changed, 22 insertions, 20 deletions
diff --git a/poppler/Function.cc b/poppler/Function.cc
index 043ae8e9..fd5b38cc 100644
--- a/poppler/Function.cc
+++ b/poppler/Function.cc
@@ -13,7 +13,7 @@
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
-// Copyright (C) 2006, 2008-2010, 2013-2015, 2017-2020, 2022 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2006, 2008-2010, 2013-2015, 2017-2020, 2022, 2023 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2006 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com>
// Copyright (C) 2011 Andrea Canciani <ranma42@gmail.com>
@@ -1131,7 +1131,7 @@ PostScriptFunction::PostScriptFunction(Object *funcObj, Dict *dict)
//----- parse the function
codeString = new GooString();
str->reset();
- if (getToken(str).cmp("{") != 0) {
+ if (getToken(str)->cmp("{") != 0) {
error(errSyntaxError, -1, "Expected '{{' at start of PostScript function");
goto err1;
}
@@ -1231,8 +1231,10 @@ bool PostScriptFunction::parseCode(Stream *str, int *codePtr)
int a, b, mid, cmp;
while (true) {
- GooString tok = getToken(str);
- const char *p = tok.c_str();
+ // This needs to be on the heap to help make parseCode
+ // able to call itself more times recursively
+ std::unique_ptr<GooString> tok = getToken(str);
+ const char *p = tok->c_str();
if (isdigit(*p) || *p == '.' || *p == '-') {
isReal = false;
for (; *p; ++p) {
@@ -1244,13 +1246,13 @@ bool PostScriptFunction::parseCode(Stream *str, int *codePtr)
resizeCode(*codePtr);
if (isReal) {
code[*codePtr].type = psReal;
- code[*codePtr].real = gatof(tok.c_str());
+ code[*codePtr].real = gatof(tok->c_str());
} else {
code[*codePtr].type = psInt;
- code[*codePtr].intg = atoi(tok.c_str());
+ code[*codePtr].intg = atoi(tok->c_str());
}
++*codePtr;
- } else if (!tok.cmp("{")) {
+ } else if (!tok->cmp("{")) {
opPtr = *codePtr;
*codePtr += 3;
resizeCode(opPtr + 2);
@@ -1258,7 +1260,7 @@ bool PostScriptFunction::parseCode(Stream *str, int *codePtr)
return false;
}
tok = getToken(str);
- if (!tok.cmp("{")) {
+ if (!tok->cmp("{")) {
elsePtr = *codePtr;
if (!parseCode(str, codePtr)) {
return false;
@@ -1267,7 +1269,7 @@ bool PostScriptFunction::parseCode(Stream *str, int *codePtr)
} else {
elsePtr = -1;
}
- if (!tok.cmp("if")) {
+ if (!tok->cmp("if")) {
if (elsePtr >= 0) {
error(errSyntaxError, -1, "Got 'if' operator with two blocks in PostScript function");
return false;
@@ -1276,7 +1278,7 @@ bool PostScriptFunction::parseCode(Stream *str, int *codePtr)
code[opPtr].op = psOpIf;
code[opPtr + 2].type = psBlock;
code[opPtr + 2].blk = *codePtr;
- } else if (!tok.cmp("ifelse")) {
+ } else if (!tok->cmp("ifelse")) {
if (elsePtr < 0) {
error(errSyntaxError, -1, "Got 'ifelse' operator with one block in PostScript function");
return false;
@@ -1291,7 +1293,7 @@ bool PostScriptFunction::parseCode(Stream *str, int *codePtr)
error(errSyntaxError, -1, "Expected if/ifelse operator in PostScript function");
return false;
}
- } else if (!tok.cmp("}")) {
+ } else if (!tok->cmp("}")) {
resizeCode(*codePtr);
code[*codePtr].type = psOperator;
code[*codePtr].op = psOpReturn;
@@ -1304,7 +1306,7 @@ bool PostScriptFunction::parseCode(Stream *str, int *codePtr)
// invariant: psOpNames[a] < tok < psOpNames[b]
while (b - a > 1) {
mid = (a + b) / 2;
- cmp = tok.cmp(psOpNames[mid]);
+ cmp = tok->cmp(psOpNames[mid]);
if (cmp > 0) {
a = mid;
} else if (cmp < 0) {
@@ -1314,7 +1316,7 @@ bool PostScriptFunction::parseCode(Stream *str, int *codePtr)
}
}
if (cmp != 0) {
- error(errSyntaxError, -1, "Unknown operator '{0:t}' in PostScript function", &tok);
+ error(errSyntaxError, -1, "Unknown operator '{0:t}' in PostScript function", tok.get());
return false;
}
resizeCode(*codePtr);
@@ -1326,12 +1328,12 @@ bool PostScriptFunction::parseCode(Stream *str, int *codePtr)
return true;
}
-GooString PostScriptFunction::getToken(Stream *str)
+std::unique_ptr<GooString> PostScriptFunction::getToken(Stream *str)
{
int c;
bool comment;
- GooString s;
+ std::string s;
comment = false;
while (true) {
if ((c = str->getChar()) == EOF) {
@@ -1349,10 +1351,10 @@ GooString PostScriptFunction::getToken(Stream *str)
}
}
if (c == '{' || c == '}') {
- s.append((char)c);
+ s.push_back((char)c);
} else if (isdigit(c) || c == '.' || c == '-') {
while (true) {
- s.append((char)c);
+ s.push_back((char)c);
c = str->lookChar();
if (c == EOF || !(isdigit(c) || c == '.' || c == '-')) {
break;
@@ -1362,7 +1364,7 @@ GooString PostScriptFunction::getToken(Stream *str)
}
} else {
while (true) {
- s.append((char)c);
+ s.push_back((char)c);
c = str->lookChar();
if (c == EOF || !isalnum(c)) {
break;
@@ -1371,7 +1373,7 @@ GooString PostScriptFunction::getToken(Stream *str)
codeString->append(c);
}
}
- return s;
+ return std::make_unique<GooString>(s);
}
void PostScriptFunction::resizeCode(int newSize)
diff --git a/poppler/Function.h b/poppler/Function.h
index c1544f43..d2c003cc 100644
--- a/poppler/Function.h
+++ b/poppler/Function.h
@@ -236,7 +236,7 @@ public:
private:
explicit PostScriptFunction(const PostScriptFunction *func);
bool parseCode(Stream *str, int *codePtr);
- GooString getToken(Stream *str);
+ std::unique_ptr<GooString> getToken(Stream *str);
void resizeCode(int newSize);
void exec(PSStack *stack, int codePtr) const;