Gfx::doShowText: Fix infinite recursion on broken files
Bug #102701
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 6ffb7bc..3eea6d2 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -3953,12 +3953,33 @@
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 00eaec4..293f455 100644
--- a/poppler/Gfx.h
+++ b/poppler/Gfx.h
@@ -228,6 +228,7 @@
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 d95f8f7..1c3d0b2 100644
--- a/poppler/GfxFont.cc
+++ b/poppler/GfxFont.cc
@@ -1759,6 +1759,14 @@
}
}
+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 06c1df6..5985912 100644
--- a/poppler/GfxFont.h
+++ b/poppler/GfxFont.h
@@ -353,6 +353,7 @@
// 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();