diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 3a1296f1dade6..bed5ab8507693 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -44,6 +44,7 @@ import { isStream, Name, Ref, + RefSet, } from "./primitives.js"; import { ErrorFont, @@ -237,9 +238,9 @@ class PartialEvaluator { return false; } - var processed = Object.create(null); + const processed = new RefSet(); if (resources.objId) { - processed[resources.objId] = true; + processed.put(resources.objId); } var nodes = [resources], @@ -249,13 +250,10 @@ class PartialEvaluator { // First check the current resources for blend modes. var graphicStates = node.get("ExtGState"); if (graphicStates instanceof Dict) { - var graphicStatesKeys = graphicStates.getKeys(); - for (let i = 0, ii = graphicStatesKeys.length; i < ii; i++) { - const key = graphicStatesKeys[i]; - + for (const key of graphicStates.getKeys()) { let graphicState = graphicStates.getRaw(key); if (graphicState instanceof Ref) { - if (processed[graphicState.toString()]) { + if (processed.has(graphicState)) { continue; // The ExtGState has already been processed. } try { @@ -264,27 +262,18 @@ class PartialEvaluator { if (ex instanceof MissingDataException) { throw ex; } - if (this.options.ignoreErrors) { - if (graphicState instanceof Ref) { - // Avoid parsing a corrupt ExtGState more than once. - processed[graphicState.toString()] = true; - } - // Error(s) in the ExtGState -- sending unsupported feature - // notification and allow parsing/rendering to continue. - this.handler.send("UnsupportedFeature", { - featureId: UNSUPPORTED_FEATURES.errorExtGState, - }); - warn(`hasBlendModes - ignoring ExtGState: "${ex}".`); - continue; - } - throw ex; + // Avoid parsing a corrupt ExtGState more than once. + processed.put(graphicState); + + info(`hasBlendModes - ignoring ExtGState: "${ex}".`); + continue; } } if (!(graphicState instanceof Dict)) { continue; } if (graphicState.objId) { - processed[graphicState.objId] = true; + processed.put(graphicState.objId); } const bm = graphicState.get("BM"); @@ -295,8 +284,8 @@ class PartialEvaluator { continue; } if (bm !== undefined && Array.isArray(bm)) { - for (let j = 0, jj = bm.length; j < jj; j++) { - if (bm[j] instanceof Name && bm[j].name !== "Normal") { + for (const element of bm) { + if (element instanceof Name && element.name !== "Normal") { return true; } } @@ -308,13 +297,10 @@ class PartialEvaluator { if (!(xObjects instanceof Dict)) { continue; } - var xObjectsKeys = xObjects.getKeys(); - for (let i = 0, ii = xObjectsKeys.length; i < ii; i++) { - const key = xObjectsKeys[i]; - + for (const key of xObjects.getKeys()) { var xObject = xObjects.getRaw(key); if (xObject instanceof Ref) { - if (processed[xObject.toString()]) { + if (processed.has(xObject)) { // The XObject has already been processed, and by avoiding a // redundant `xref.fetch` we can *significantly* reduce the load // time for badly generated PDF files (fixes issue6961.pdf). @@ -326,41 +312,31 @@ class PartialEvaluator { if (ex instanceof MissingDataException) { throw ex; } - if (this.options.ignoreErrors) { - if (xObject instanceof Ref) { - // Avoid parsing a corrupt XObject more than once. - processed[xObject.toString()] = true; - } - // Error(s) in the XObject -- sending unsupported feature - // notification and allow parsing/rendering to continue. - this.handler.send("UnsupportedFeature", { - featureId: UNSUPPORTED_FEATURES.errorXObject, - }); - warn(`hasBlendModes - ignoring XObject: "${ex}".`); - continue; - } - throw ex; + // Avoid parsing a corrupt XObject more than once. + processed.put(xObject); + + info(`hasBlendModes - ignoring XObject: "${ex}".`); + continue; } } if (!isStream(xObject)) { continue; } if (xObject.dict.objId) { - if (processed[xObject.dict.objId]) { - continue; // Stream has objId and was processed already. - } - processed[xObject.dict.objId] = true; + processed.put(xObject.dict.objId); } var xResources = xObject.dict.get("Resources"); + if (!(xResources instanceof Dict)) { + continue; + } // Checking objId to detect an infinite loop. - if ( - xResources instanceof Dict && - (!xResources.objId || !processed[xResources.objId]) - ) { - nodes.push(xResources); - if (xResources.objId) { - processed[xResources.objId] = true; - } + if (xResources.objId && processed.has(xResources.objId)) { + continue; + } + + nodes.push(xResources); + if (xResources.objId) { + processed.put(xResources.objId); } } }