diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 9d5ad52db..5680ed572 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -1472,26 +1472,43 @@ class PartialEvaluator { // Shadings and patterns may be referenced by the same name but the resource // dictionary could be different so we can't use the name for the cache key. let id = localShadingPatternCache.get(shading); - if (!id) { - var shadingFill = Pattern.parseShading( + if (id) { + return id; + } + let patternIR; + + try { + const shadingFill = Pattern.parseShading( shading, this.xref, resources, this._pdfFunctionFactory, localColorSpaceCache ); - const patternIR = shadingFill.getIR(); - id = `pattern_${this.idFactory.createObjId()}`; - if (this.parsingType3Font) { - id = `${this.idFactory.getDocId()}_type3_${id}`; + patternIR = shadingFill.getIR(); + } catch (reason) { + if (reason instanceof AbortException) { + return null; } - localShadingPatternCache.set(shading, id); + if (this.options.ignoreErrors) { + warn(`parseShading - ignoring shading: "${reason}".`); - if (this.parsingType3Font) { - this.handler.send("commonobj", [id, "Pattern", patternIR]); - } else { - this.handler.send("obj", [id, this.pageIndex, "Pattern", patternIR]); + localShadingPatternCache.set(shading, null); + return null; } + throw reason; + } + + id = `pattern_${this.idFactory.createObjId()}`; + if (this.parsingType3Font) { + id = `${this.idFactory.getDocId()}_type3_${id}`; + } + localShadingPatternCache.set(shading, id); + + if (this.parsingType3Font) { + this.handler.send("commonobj", [id, "Pattern", patternIR]); + } else { + this.handler.send("obj", [id, this.pageIndex, "Pattern", patternIR]); } return id; } @@ -1551,14 +1568,16 @@ class PartialEvaluator { ); } else if (typeNum === PatternType.SHADING) { const shading = dict.get("Shading"); - const matrix = dict.getArray("Matrix"); const objId = this.parseShading({ shading, resources, localColorSpaceCache, localShadingPatternCache, }); - operatorList.addOp(fn, ["Shading", objId, matrix]); + if (objId) { + const matrix = dict.getArray("Matrix"); + operatorList.addOp(fn, ["Shading", objId, matrix]); + } return undefined; } throw new FormatError(`Unknown PatternType: ${typeNum}`); @@ -2109,6 +2128,9 @@ class PartialEvaluator { localColorSpaceCache, localShadingPatternCache, }); + if (!patternId) { + continue; + } args = [patternId]; fn = OPS.shadingFill; break; diff --git a/src/core/pattern.js b/src/core/pattern.js index a3fd8db5b..d5acbb425 100644 --- a/src/core/pattern.js +++ b/src/core/pattern.js @@ -956,13 +956,20 @@ class MeshShading extends BaseShading { } getIR() { + const { bounds } = this; + // Ensure that the shading has non-zero width and height, to prevent errors + // in `pattern_helper.js` (fixes issue17848.pdf). + if (bounds[2] - bounds[0] === 0 || bounds[3] - bounds[1] === 0) { + throw new FormatError(`Invalid MeshShading bounds: [${bounds}].`); + } + return [ "Mesh", this.shadingType, this.coords, this.colors, this.figures, - this.bounds, + bounds, this.bbox, this.background, ]; diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 29b737b57..0fcd81388 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -462,6 +462,7 @@ !issue15716.pdf !bug1671312_reduced.pdf !bug1671312_ArialNarrow.pdf +!issue17848.pdf !issue6108.pdf !issue6113.pdf !openoffice.pdf diff --git a/test/pdfs/issue17848.pdf b/test/pdfs/issue17848.pdf new file mode 100644 index 000000000..65522d539 Binary files /dev/null and b/test/pdfs/issue17848.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index 767c8d4a1..65168819f 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -2562,6 +2562,13 @@ "link": false, "type": "eq" }, + { + "id": "issue17848", + "file": "pdfs/issue17848.pdf", + "md5": "9a5b7ee97e1e03ad506115f15f9b57af", + "rounds": 1, + "type": "eq" + }, { "id": "personwithdog", "file": "pdfs/personwithdog.pdf",