poppler/CairoOutputDev.cc  |    2 -
 poppler/Gfx.cc             |   53 +++++++++++++++++++++++++--------------------
 poppler/Gfx.h              |    4 +--
 poppler/PSOutputDev.cc     |    2 -
 poppler/SplashOutputDev.cc |    2 -
 5 files changed, 35 insertions(+), 28 deletions(-)

New commits:
commit 1b65f9eb1beef0d1a41a4d59c89e4acd193a1a3f
Author: Albert Astals Cid <[email protected]>
Date:   Fri Jun 22 17:29:26 2018 +0200

    Gfx:Generalize protection against a pattern drawing itself
    
    fixes oss-fuzz/8929

diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 18124b8f..8e8102e9 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -960,7 +960,7 @@ GBool CairoOutputDev::tilingPatternFill(GfxState *state, 
Gfx *gfxA, Catalog *cat
   adjusted_stroke_width_tmp = adjusted_stroke_width;
   maskTmp = mask;
   mask = nullptr;
-  gfx = new Gfx(doc, this, resDict, &box, nullptr, nullptr, nullptr, 
gfxA->getXRef());
+  gfx = new Gfx(doc, this, resDict, &box, nullptr, nullptr, nullptr, gfxA);
   if (paintType == 2)
     inUncoloredPattern = gTrue;
   gfx->display(str);
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 572f435c..0763e49f 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -589,12 +589,18 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, int pageNum, Dict 
*resDict,
 Gfx::Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict,
         PDFRectangle *box, PDFRectangle *cropBox,
         GBool (*abortCheckCbkA)(void *data),
-        void *abortCheckCbkDataA, XRef *xrefA)
+        void *abortCheckCbkDataA, Gfx *gfxA)
 {
   int i;
 
   doc = docA;
-  xref = (xrefA == nullptr) ? doc->getXRef() : xrefA;
+  if (gfxA) {
+    xref = gfxA->getXRef();
+    formsDrawing = gfxA->formsDrawing;
+    charProcDrawing = gfxA->charProcDrawing;
+  } else {
+    xref = doc->getXRef();
+  }
   catalog = doc->getCatalog();
   subPage = gTrue;
   printCommands = globalParams->getPrintCommands();
@@ -2202,37 +2208,38 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
   }
   m1[4] = m[4];
   m1[5] = m[5];
-  if (out->useTilingPatternFill() &&
-       out->tilingPatternFill(state, this, catalog, tPat->getContentStream(),
-                      tPat->getMatrix(), tPat->getPaintType(), 
tPat->getTilingType(),
-                      tPat->getResDict(), m1, tPat->getBBox(),
-                      xi0, yi0, xi1, yi1, xstep, ystep)) {
-    goto restore;
-  } else {
-    bool shouldDrawForm = gTrue;
+  {
+    bool shouldDrawPattern = gTrue;
     std::set<int>::iterator patternRefIt;
     const int patternRefNum = tPat->getPatternRefNum();
     if (patternRefNum != -1) {
       if (formsDrawing.find(patternRefNum) == formsDrawing.end()) {
        patternRefIt = formsDrawing.insert(patternRefNum).first;
       } else {
-       shouldDrawForm = gFalse;
+       shouldDrawPattern = gFalse;
       }
     }
-
-    if (shouldDrawForm) {
-      out->updatePatternOpacity(state);
-      for (yi = yi0; yi < yi1; ++yi) {
-       for (xi = xi0; xi < xi1; ++xi) {
-         x = xi * xstep;
-         y = yi * ystep;
-         m1[4] = x * m[0] + y * m[2] + m[4];
-         m1[5] = x * m[1] + y * m[3] + m[5];
-         drawForm(tPat->getContentStream(), tPat->getResDict(),
-                 m1, tPat->getBBox());
+    if (shouldDrawPattern) {
+      if (out->useTilingPatternFill() &&
+         out->tilingPatternFill(state, this, catalog, tPat->getContentStream(),
+                       tPat->getMatrix(), tPat->getPaintType(), 
tPat->getTilingType(),
+                       tPat->getResDict(), m1, tPat->getBBox(),
+                       xi0, yi0, xi1, yi1, xstep, ystep)) {
+       // do nothing
+      } else {
+       out->updatePatternOpacity(state);
+       for (yi = yi0; yi < yi1; ++yi) {
+         for (xi = xi0; xi < xi1; ++xi) {
+           x = xi * xstep;
+           y = yi * ystep;
+           m1[4] = x * m[0] + y * m[2] + m[4];
+           m1[5] = x * m[1] + y * m[3] + m[5];
+           drawForm(tPat->getContentStream(), tPat->getResDict(),
+                   m1, tPat->getBBox());
+         }
        }
+       out->clearPatternOpacity(state);
       }
-      out->clearPatternOpacity(state);
       if (patternRefNum != -1) {
        formsDrawing.erase(patternRefIt);
       }
diff --git a/poppler/Gfx.h b/poppler/Gfx.h
index 2ea0d9fa..3ac4c929 100644
--- a/poppler/Gfx.h
+++ b/poppler/Gfx.h
@@ -161,7 +161,7 @@ public:
   Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict,
       PDFRectangle *box, PDFRectangle *cropBox,
       GBool (*abortCheckCbkA)(void *data) = NULL,
-      void *abortCheckCbkDataA = NULL, XRef *xrefA = NULL);
+      void *abortCheckCbkDataA = NULL, Gfx *gfxA = NULL);
 #ifdef USE_CMS
   void initDisplayProfile();
 #endif
@@ -236,7 +236,7 @@ private:
 
   Parser *parser;              // parser for page content stream(s)
   
-  std::set<int> formsDrawing;  // the forms that are being drawn
+  std::set<int> formsDrawing;  // the forms/patterns that are being drawn
   std::set<int> charProcDrawing;       // the charProc that are being drawn
 
   GBool                                // callback to check for an abort
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index b466bc69..d1ead586 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -4526,7 +4526,7 @@ GBool PSOutputDev::tilingPatternFill(GfxState *state, Gfx 
*gfxA, Catalog *cat, O
     box.y1 = bbox[1];
     box.x2 = bbox[2];
     box.y2 = bbox[3];
-    gfx = new Gfx(doc, this, resDict, &box, nullptr, nullptr, nullptr, 
gfxA->getXRef());
+    gfx = new Gfx(doc, this, resDict, &box, nullptr, nullptr, nullptr, gfxA);
     writePSFmt("[{0:.6g} {1:.6g} {2:.6g} {3:.6g} {4:.6g} {5:.6g}] cm\n", 
mat[0], mat[1], mat[2], mat[3], tx, ty);
     inType3Char = gTrue;
     gfx->display(str);
diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index 74953839..3e883970 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -4697,7 +4697,7 @@ GBool SplashOutputDev::tilingPatternFill(GfxState *state, 
Gfx *gfxA, Catalog *ca
 
   box.x1 = bbox[0]; box.y1 = bbox[1];
   box.x2 = bbox[2]; box.y2 = bbox[3];
-  gfx = new Gfx(doc, this, resDict, &box, nullptr, nullptr, nullptr, 
gfxA->getXRef());
+  gfx = new Gfx(doc, this, resDict, &box, nullptr, nullptr, nullptr, gfxA);
   // set pattern transformation matrix
   gfx->getState()->setCTM(m1.m[0], m1.m[1], m1.m[2], m1.m[3], m1.m[4], 
m1.m[5]);
   updateCTM(gfx->getState(), m1.m[0], m1.m[1], m1.m[2], m1.m[3], m1.m[4], 
m1.m[5]);
_______________________________________________
poppler mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to