diff options
author | Albert Astals Cid <aacid@kde.org> | 2023-04-05 00:19:04 +0200 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2023-04-12 22:47:41 +0200 |
commit | 1be35ee8b2d6418dfafc6a8a9bbf6d70eafb2d2e (patch) | |
tree | de67315556be1c72ff208696b14863eed68ccb9e | |
parent | 8354c73ea0516a9d4a4bdf68da5c5392498b286d (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.cc | 40 | ||||
-rw-r--r-- | poppler/Function.h | 2 |
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; |