summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2017-09-13 23:01:03 +0200
committerAlbert Astals Cid <aacid@kde.org>2017-09-13 23:04:50 +0200
commitaaf5327649e8f7371c9d3270e7813c43ddfd47ee (patch)
tree3af57a643659ef81515fe63f392bb5addde5a55a
parent476394e7a025e02e4897da2e765df2c895d0708f (diff)
Gfx::doShowText: Fix infinite recursion on broken files
Bug #102701
-rw-r--r--poppler/Gfx.cc25
-rw-r--r--poppler/Gfx.h1
-rw-r--r--poppler/GfxFont.cc8
-rw-r--r--poppler/GfxFont.h1
4 files changed, 33 insertions, 2 deletions
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 6ffb7bcf..3eea6d2a 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -3953,12 +3953,33 @@ void Gfx::doShowText(GooString *s) {
state->transformDelta(dx, dy, &ddx, &ddy);
if (!out->beginType3Char(state, curX + riseX, curY + riseY, ddx, ddy,
code, u, uLen)) {
- Object charProc = ((Gfx8BitFont *)font)->getCharProc(code);
+ Object charProc = ((Gfx8BitFont *)font)->getCharProcNF(code);
+ int refNum = -1;
+ if (charProc.isRef()) {
+ refNum = charProc.getRef().num;
+ charProc = charProc.fetch(((Gfx8BitFont *)font)->getCharProcs()->getXRef());
+ }
if ((resDict = ((Gfx8BitFont *)font)->getResources())) {
pushResources(resDict);
}
if (charProc.isStream()) {
- display(&charProc, gFalse);
+ std::set<int>::iterator charProcDrawingIt;
+ bool displayCharProc = true;
+ if (refNum != -1) {
+ if (charProcDrawing.find(refNum) == charProcDrawing.end()) {
+ charProcDrawingIt = charProcDrawing.insert(refNum).first;
+ } else {
+ displayCharProc = false;
+ error(errSyntaxError, -1, "CharProc wants to draw a CharProc that is already beign drawn");
+ }
+ }
+ if (displayCharProc) {
+ display(&charProc, gFalse);
+
+ if (refNum != -1) {
+ charProcDrawing.erase(charProcDrawingIt);
+ }
+ }
} else {
error(errSyntaxError, getPos(), "Missing or bad Type3 CharProc entry");
}
diff --git a/poppler/Gfx.h b/poppler/Gfx.h
index 00eaec49..293f4551 100644
--- a/poppler/Gfx.h
+++ b/poppler/Gfx.h
@@ -228,6 +228,7 @@ private:
Parser *parser; // parser for page content stream(s)
std::set<int> formsDrawing; // the forms that are being drawn
+ std::set<int> charProcDrawing; // the charProc that are being drawn
GBool // callback to check for an abort
(*abortCheckCbk)(void *data);
diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc
index d95f8f7c..1c3d0b25 100644
--- a/poppler/GfxFont.cc
+++ b/poppler/GfxFont.cc
@@ -1759,6 +1759,14 @@ Object Gfx8BitFont::getCharProc(int code) {
}
}
+Object Gfx8BitFont::getCharProcNF(int code) {
+ if (enc[code] && charProcs.isDict()) {
+ return charProcs.dictLookupNF(enc[code]);
+ } else {
+ return Object(objNull);
+ }
+}
+
Dict *Gfx8BitFont::getResources() {
return resources.isDict() ? resources.getDict() : (Dict *)NULL;
}
diff --git a/poppler/GfxFont.h b/poppler/GfxFont.h
index 06c1df6d..5985912a 100644
--- a/poppler/GfxFont.h
+++ b/poppler/GfxFont.h
@@ -353,6 +353,7 @@ public:
// Return the Type 3 CharProc for the character associated with <code>.
Object getCharProc(int code);
+ Object getCharProcNF(int code);
// Return the Type 3 Resources dictionary, or NULL if none.
Dict *getResources();