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:
parent
d3fa65e019
commit
a28ed7c834
@ -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() {
|
||||||
|
@ -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;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -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
78
test/pdfs/issue5954.pdf
Normal 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
|
@ -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",
|
||||||
|
Loading…
Reference in New Issue
Block a user