In many instances, the sensible response (and what acroread does) in
case of an error is abort the PDF stream. To avoid changing the return
value of every function and using C++ exceptions, we communicate via a
commandAborted variable.
This patch, matching acroread's behavior aborts the current stream when
there are too few arguments or we pop too many times. Implementation
note 39 in Appendix H of the PDF reference contradicts the former, but
hand-crafted test PDFs as well as the file in #24575 suggest otherwise.
Unlike all the other attempts, this patch *actually* fixes the PDF in
bug #24575.
---
poppler/Gfx.cc | 11 +++++++++++
poppler/Gfx.h | 1 +
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 5aba7e9..372443d 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -663,6 +663,7 @@ void Gfx::go(GBool topLevel) {
numArgs = 0;
parser->getObj(&obj);
while (!obj.isEOF()) {
+ commandAborted = gFalse;
// got a command - execute it
if (obj.isCmd()) {
@@ -710,6 +711,14 @@ void Gfx::go(GBool topLevel) {
updateLevel = 0;
}
+ // did the command throw an exception
+ if (commandAborted) {
+ // don't propogate; recursive drawing comes from Form XObjects which
+ // should probably be drawn in a separate context anyway for caching
+ commandAborted = gFalse;
+ break;
+ }
+
// check for an abort
if (abortCheckCbk) {
if (updateLevel - lastAbortCheck > 10) {
@@ -784,6 +793,7 @@ void Gfx::execOp(Object *cmd, Object args[], int numArgs) {
if (op->numArgs >= 0) {
if (numArgs < op->numArgs) {
error(getPos(), "Too few (%d) args to '%s' operator", numArgs, name);
+ commandAborted = gTrue;
return;
}
if (numArgs > op->numArgs) {
@@ -4762,6 +4772,7 @@ void Gfx::saveState() {
void Gfx::restoreState() {
if (stackHeight <= bottomGuard() || !state->hasSaves()) {
error(-1, "Restoring state when no valid states to pop");
+ commandAborted = gTrue;
return;
}
state = state->restore();
diff --git a/poppler/Gfx.h b/poppler/Gfx.h
index 1417d19..5999ec9 100644
--- a/poppler/Gfx.h
+++ b/poppler/Gfx.h
@@ -192,6 +192,7 @@ private:
GBool textHaveCSPattern; // in text drawing and text has pattern
colorspace
GBool drawText; // in text drawing
GBool maskHaveCSPattern; // in mask drawing and mask has pattern
colorspace
+ GBool commandAborted; // did the previous command abort the drawing?
GfxColorSpace *colorSpaceText;// colorspace after text has filled with
pattern
GfxColor colorText; // fill color after after text has filled with
pattern
GfxResources *res; // resource stack
--
1.6.6.137.g8333d.dirty
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler