Always traverse the entire parent chain in Page_getInheritedPageProp (issue 5954)

This enables us to find resources placed on multiple levels of the tree.

Fixes 5954.
This commit is contained in:
Jonas Jenwald 2015-05-20 15:08:55 +02:00
parent d3fa65e019
commit a28ed7c834
5 changed files with 136 additions and 21 deletions

View File

@ -14,12 +14,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* globals assert, calculateMD5, Catalog, Dict, error, info, isArray, /* globals warn, Dict, isDict, shadow, isArray, Util, StreamsSequenceStream,
isArrayBuffer, isName, isStream, isString, createPromiseCapability, isStream, NullStream, ObjectLoader, PartialEvaluator, Promise,
Linearization, NullStream, PartialEvaluator, shadow, Stream, Lexer, OperatorList, Annotation, error, assert, XRef, isArrayBuffer, Stream,
StreamsSequenceStream, stringToPDFString, stringToBytes, Util, XRef, isString, isName, info, Linearization, MissingDataException, Lexer,
MissingDataException, Promise, Annotation, ObjectLoader, OperatorList Catalog, stringToPDFString, stringToBytes, calculateMD5 */
*/
'use strict'; 'use strict';
@ -45,17 +44,33 @@ var Page = (function PageClosure() {
return this.pageDict.get(key); return this.pageDict.get(key);
}, },
getInheritedPageProp: function Page_inheritPageProp(key) { getInheritedPageProp: function Page_getInheritedPageProp(key) {
var dict = this.pageDict; var dict = this.pageDict, valueArray = null, loopCount = 0;
var value = dict.get(key); var MAX_LOOP_COUNT = 100;
while (value === undefined) { // Always walk up the entire parent chain, to be able to find
dict = dict.get('Parent'); // e.g. \Resources placed on multiple levels of the tree.
if (!dict) { 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; 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() { get content() {
@ -63,14 +78,10 @@ var Page = (function PageClosure() {
}, },
get resources() { get resources() {
var value = this.getInheritedPageProp('Resources');
// For robustness: The spec states that a \Resources entry has to be // 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 // present, but can be empty. Some document omit it still, in this case
// return an empty dictionary: // we return an empty dictionary.
if (value === undefined) { return shadow(this, 'resources', this.getInheritedPageProp('Resources'));
value = Dict.empty;
}
return shadow(this, 'resources', value);
}, },
get mediaBox() { get mediaBox() {

View File

@ -213,6 +213,24 @@ var Dict = (function DictClosure() {
Dict.empty = new Dict(null); 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; return Dict;
})(); })();

View File

@ -24,6 +24,7 @@
!issue4630.pdf !issue4630.pdf
!issue5202.pdf !issue5202.pdf
!issue5280.pdf !issue5280.pdf
!issue5954.pdf
!alphatrans.pdf !alphatrans.pdf
!devicen.pdf !devicen.pdf
!cmykjpeg.pdf !cmykjpeg.pdf

78
test/pdfs/issue5954.pdf Normal file
View File

@ -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

View File

@ -558,6 +558,13 @@
"link": false, "link": false,
"type": "load" "type": "load"
}, },
{ "id": "issue5954",
"file": "pdfs/issue5954.pdf",
"md5": "4f60ec0d9bbeec845b681242b8982361",
"rounds": 1,
"link": false,
"type": "eq"
},
{ "id": "txt2pdf", { "id": "txt2pdf",
"file": "pdfs/txt2pdf.pdf", "file": "pdfs/txt2pdf.pdf",
"md5": "02cefa0f5e8d96313bb05163b2f88c8c", "md5": "02cefa0f5e8d96313bb05163b2f88c8c",