diff --git a/src/core/core.js b/src/core/core.js index 2eb8fd57b..e6ad21256 100644 --- a/src/core/core.js +++ b/src/core/core.js @@ -14,12 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals assert, calculateMD5, Catalog, Dict, error, info, isArray, - isArrayBuffer, isName, isStream, isString, createPromiseCapability, - Linearization, NullStream, PartialEvaluator, shadow, Stream, Lexer, - StreamsSequenceStream, stringToPDFString, stringToBytes, Util, XRef, - MissingDataException, Promise, Annotation, ObjectLoader, OperatorList - */ +/* globals warn, Dict, isDict, shadow, isArray, Util, StreamsSequenceStream, + isStream, NullStream, ObjectLoader, PartialEvaluator, Promise, + OperatorList, Annotation, error, assert, XRef, isArrayBuffer, Stream, + isString, isName, info, Linearization, MissingDataException, Lexer, + Catalog, stringToPDFString, stringToBytes, calculateMD5 */ 'use strict'; @@ -45,17 +44,33 @@ var Page = (function PageClosure() { return this.pageDict.get(key); }, - getInheritedPageProp: function Page_inheritPageProp(key) { - var dict = this.pageDict; - var value = dict.get(key); - while (value === undefined) { - dict = dict.get('Parent'); - if (!dict) { + getInheritedPageProp: function Page_getInheritedPageProp(key) { + var dict = this.pageDict, valueArray = null, loopCount = 0; + var MAX_LOOP_COUNT = 100; + // Always walk up the entire parent chain, to be able to find + // e.g. \Resources placed on multiple levels of the tree. + while (dict) { + var value = dict.get(key); + if (value) { + if (!valueArray) { + valueArray = []; + } + valueArray.push(value); + } + if (++loopCount > MAX_LOOP_COUNT) { + warn('Page_getInheritedPageProp: maximum loop count exceeded.'); break; } - value = dict.get(key); + dict = dict.get('Parent'); } - return value; + if (!valueArray) { + return Dict.empty; + } + if (valueArray.length === 1 || !isDict(valueArray[0]) || + loopCount > MAX_LOOP_COUNT) { + return valueArray[0]; + } + return Dict.merge(this.xref, valueArray); }, get content() { @@ -63,14 +78,10 @@ var Page = (function PageClosure() { }, get resources() { - var value = this.getInheritedPageProp('Resources'); // For robustness: The spec states that a \Resources entry has to be - // present, but can be empty. Some document omit it still. In this case - // return an empty dictionary: - if (value === undefined) { - value = Dict.empty; - } - return shadow(this, 'resources', value); + // present, but can be empty. Some document omit it still, in this case + // we return an empty dictionary. + return shadow(this, 'resources', this.getInheritedPageProp('Resources')); }, get mediaBox() { diff --git a/src/core/obj.js b/src/core/obj.js index a39666f40..7e3192987 100644 --- a/src/core/obj.js +++ b/src/core/obj.js @@ -213,6 +213,24 @@ var Dict = (function DictClosure() { Dict.empty = new Dict(null); + Dict.merge = function Dict_merge(xref, dictArray) { + var mergedDict = new Dict(xref); + + for (var i = 0, ii = dictArray.length; i < ii; i++) { + var dict = dictArray[i]; + if (!isDict(dict)) { + continue; + } + for (var keyName in dict.map) { + if (mergedDict.map[keyName]) { + continue; + } + mergedDict.map[keyName] = dict.map[keyName]; + } + } + return mergedDict; + }; + return Dict; })(); diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 4e0af6f9f..00553605e 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -24,6 +24,7 @@ !issue4630.pdf !issue5202.pdf !issue5280.pdf +!issue5954.pdf !alphatrans.pdf !devicen.pdf !cmykjpeg.pdf diff --git a/test/pdfs/issue5954.pdf b/test/pdfs/issue5954.pdf new file mode 100644 index 000000000..a0a77363a --- /dev/null +++ b/test/pdfs/issue5954.pdf @@ -0,0 +1,78 @@ +%PDF-1.4 +%âãÏÓ +1 0 obj +<< +/Pages 2 0 R +/Type /Catalog +>> +endobj +3 0 obj +<< +/Parent 2 0 R +/Resources +<< +/XObject +<< +>> +>> +/MediaBox [0 0 200 50] +/Type /Page +/Contents 4 0 R +>> +endobj +4 0 obj +<< +/Length 41 +>> +stream +BT +10 20 TD +/F1 20 Tf +(Issue 5954) Tj +ET + +endstream +endobj +2 0 obj +<< +/MediaBox [0 0 200 50] +/Resources 5 0 R +/Kids [3 0 R] +/Count 1 +/Type /Pages +>> +endobj +5 0 obj +<< +/Font +<< +/F1 6 0 R +>> +>> +endobj +6 0 obj +<< +/BaseFont /Times-Roman +/Subtype /Type1 +/Name /F1 +/Type /Font +/Encoding /WinAnsiEncoding +>> +endobj xref +0 7 +0000000000 65535 f +0000000015 00000 n +0000000282 00000 n +0000000066 00000 n +0000000188 00000 n +0000000381 00000 n +0000000427 00000 n +trailer + +<< +/Root 1 0 R +/Size 7 +>> +startxref +537 +%%EOF diff --git a/test/test_manifest.json b/test/test_manifest.json index f70686c31..55e924245 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -558,6 +558,13 @@ "link": false, "type": "load" }, + { "id": "issue5954", + "file": "pdfs/issue5954.pdf", + "md5": "4f60ec0d9bbeec845b681242b8982361", + "rounds": 1, + "link": false, + "type": "eq" + }, { "id": "txt2pdf", "file": "pdfs/txt2pdf.pdf", "md5": "02cefa0f5e8d96313bb05163b2f88c8c",