Commit 1b65f9eb authored by Albert Astals Cid's avatar Albert Astals Cid

Gfx:Generalize protection against a pattern drawing itself

fixes oss-fuzz/8929
parent da349184
...@@ -960,7 +960,7 @@ GBool CairoOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *cat ...@@ -960,7 +960,7 @@ GBool CairoOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *cat
adjusted_stroke_width_tmp = adjusted_stroke_width; adjusted_stroke_width_tmp = adjusted_stroke_width;
maskTmp = mask; maskTmp = mask;
mask = nullptr; 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) if (paintType == 2)
inUncoloredPattern = gTrue; inUncoloredPattern = gTrue;
gfx->display(str); gfx->display(str);
......
...@@ -589,12 +589,18 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, int pageNum, Dict *resDict, ...@@ -589,12 +589,18 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, int pageNum, Dict *resDict,
Gfx::Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict, Gfx::Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict,
PDFRectangle *box, PDFRectangle *cropBox, PDFRectangle *box, PDFRectangle *cropBox,
GBool (*abortCheckCbkA)(void *data), GBool (*abortCheckCbkA)(void *data),
void *abortCheckCbkDataA, XRef *xrefA) void *abortCheckCbkDataA, Gfx *gfxA)
{ {
int i; int i;
doc = docA; 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(); catalog = doc->getCatalog();
subPage = gTrue; subPage = gTrue;
printCommands = globalParams->getPrintCommands(); printCommands = globalParams->getPrintCommands();
...@@ -2202,37 +2208,38 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, ...@@ -2202,37 +2208,38 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
} }
m1[4] = m[4]; m1[4] = m[4];
m1[5] = m[5]; m1[5] = m[5];
if (out->useTilingPatternFill() && {
out->tilingPatternFill(state, this, catalog, tPat->getContentStream(), bool shouldDrawPattern = gTrue;
tPat->getMatrix(), tPat->getPaintType(), tPat->getTilingType(),
tPat->getResDict(), m1, tPat->getBBox(),
xi0, yi0, xi1, yi1, xstep, ystep)) {
goto restore;
} else {
bool shouldDrawForm = gTrue;
std::set<int>::iterator patternRefIt; std::set<int>::iterator patternRefIt;
const int patternRefNum = tPat->getPatternRefNum(); const int patternRefNum = tPat->getPatternRefNum();
if (patternRefNum != -1) { if (patternRefNum != -1) {
if (formsDrawing.find(patternRefNum) == formsDrawing.end()) { if (formsDrawing.find(patternRefNum) == formsDrawing.end()) {
patternRefIt = formsDrawing.insert(patternRefNum).first; patternRefIt = formsDrawing.insert(patternRefNum).first;
} else { } else {
shouldDrawForm = gFalse; shouldDrawPattern = gFalse;
} }
} }
if (shouldDrawPattern) {
if (shouldDrawForm) { if (out->useTilingPatternFill() &&
out->updatePatternOpacity(state); out->tilingPatternFill(state, this, catalog, tPat->getContentStream(),
for (yi = yi0; yi < yi1; ++yi) { tPat->getMatrix(), tPat->getPaintType(), tPat->getTilingType(),
for (xi = xi0; xi < xi1; ++xi) { tPat->getResDict(), m1, tPat->getBBox(),
x = xi * xstep; xi0, yi0, xi1, yi1, xstep, ystep)) {
y = yi * ystep; // do nothing
m1[4] = x * m[0] + y * m[2] + m[4]; } else {
m1[5] = x * m[1] + y * m[3] + m[5]; out->updatePatternOpacity(state);
drawForm(tPat->getContentStream(), tPat->getResDict(), for (yi = yi0; yi < yi1; ++yi) {
m1, tPat->getBBox()); 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) { if (patternRefNum != -1) {
formsDrawing.erase(patternRefIt); formsDrawing.erase(patternRefIt);
} }
......
...@@ -161,7 +161,7 @@ public: ...@@ -161,7 +161,7 @@ public:
Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict, Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict,
PDFRectangle *box, PDFRectangle *cropBox, PDFRectangle *box, PDFRectangle *cropBox,
GBool (*abortCheckCbkA)(void *data) = NULL, GBool (*abortCheckCbkA)(void *data) = NULL,
void *abortCheckCbkDataA = NULL, XRef *xrefA = NULL); void *abortCheckCbkDataA = NULL, Gfx *gfxA = NULL);
#ifdef USE_CMS #ifdef USE_CMS
void initDisplayProfile(); void initDisplayProfile();
#endif #endif
...@@ -236,7 +236,7 @@ private: ...@@ -236,7 +236,7 @@ private:
Parser *parser; // parser for page content stream(s) 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 std::set<int> charProcDrawing; // the charProc that are being drawn
GBool // callback to check for an abort GBool // callback to check for an abort
......
...@@ -4526,7 +4526,7 @@ GBool PSOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *cat, O ...@@ -4526,7 +4526,7 @@ GBool PSOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *cat, O
box.y1 = bbox[1]; box.y1 = bbox[1];
box.x2 = bbox[2]; box.x2 = bbox[2];
box.y2 = bbox[3]; 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); 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; inType3Char = gTrue;
gfx->display(str); gfx->display(str);
......
...@@ -4697,7 +4697,7 @@ GBool SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *ca ...@@ -4697,7 +4697,7 @@ GBool SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *ca
box.x1 = bbox[0]; box.y1 = bbox[1]; box.x1 = bbox[0]; box.y1 = bbox[1];
box.x2 = bbox[2]; box.y2 = bbox[3]; 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 // 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]); 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]); updateCTM(gfx->getState(), m1.m[0], m1.m[1], m1.m[2], m1.m[3], m1.m[4], m1.m[5]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment