[poppler] [PATCH 5/5] Allow commands to abort the current stream

David Benjamin davidben at MIT.EDU
Thu Jan 21 21:27:03 PST 2010


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



More information about the poppler mailing list