pdfjs-dist 2.0.943 → 2.4.456
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pdfjs-dist might be problematic. Click here for more details.
- package/CODE_OF_CONDUCT.md +15 -0
- package/README.md +4 -0
- package/bower.json +1 -1
- package/build/pdf.js +8286 -14230
- package/build/pdf.js.map +1 -1
- package/build/pdf.min.js +22 -1
- package/build/pdf.worker.entry.js +5 -3
- package/build/pdf.worker.js +25500 -26628
- package/build/pdf.worker.js.map +1 -1
- package/build/pdf.worker.min.js +22 -1
- package/es5/build/pdf.js +25473 -0
- package/es5/build/pdf.js.map +1 -0
- package/{lib/shared/global_scope.js → es5/build/pdf.worker.entry.js} +5 -10
- package/es5/build/pdf.worker.js +57878 -0
- package/es5/build/pdf.worker.js.map +1 -0
- package/es5/web/images/annotation-check.svg +11 -0
- package/es5/web/images/annotation-comment.svg +16 -0
- package/es5/web/images/annotation-help.svg +26 -0
- package/es5/web/images/annotation-insert.svg +10 -0
- package/es5/web/images/annotation-key.svg +11 -0
- package/es5/web/images/annotation-newparagraph.svg +11 -0
- package/es5/web/images/annotation-noicon.svg +7 -0
- package/es5/web/images/annotation-note.svg +42 -0
- package/es5/web/images/annotation-paragraph.svg +16 -0
- package/es5/web/images/loading-icon.gif +0 -0
- package/es5/web/images/shadow.png +0 -0
- package/es5/web/images/texture.png +0 -0
- package/es5/web/pdf_viewer.css +407 -0
- package/es5/web/pdf_viewer.js +7757 -0
- package/es5/web/pdf_viewer.js.map +1 -0
- package/image_decoders/pdf.image_decoders.js +2887 -4094
- package/image_decoders/pdf.image_decoders.js.map +1 -1
- package/image_decoders/pdf.image_decoders.min.js +22 -1
- package/lib/README.md +7 -0
- package/lib/core/annotation.js +855 -778
- package/lib/core/arithmetic_decoder.js +325 -311
- package/lib/core/bidi.js +117 -50
- package/lib/core/ccitt.js +251 -89
- package/lib/core/ccitt_stream.js +26 -16
- package/lib/core/cff_parser.js +525 -197
- package/lib/core/charsets.js +6 -5
- package/lib/core/chunked_stream.js +541 -406
- package/lib/core/cmap.js +368 -253
- package/lib/core/colorspace.js +781 -800
- package/lib/core/core_utils.js +152 -0
- package/lib/core/crypto.js +609 -422
- package/lib/core/document.js +649 -481
- package/lib/core/encodings.js +33 -24
- package/lib/core/evaluator.js +1471 -736
- package/lib/core/font_renderer.js +289 -149
- package/lib/core/fonts.js +1067 -413
- package/lib/core/function.js +517 -287
- package/lib/core/glyphlist.js +4529 -4527
- package/lib/core/image.js +232 -114
- package/lib/core/image_utils.js +94 -0
- package/lib/core/jbig2.js +711 -342
- package/lib/core/jbig2_stream.js +31 -19
- package/lib/core/jpeg_stream.js +151 -26
- package/lib/core/jpg.js +433 -181
- package/lib/core/jpx.js +551 -143
- package/lib/core/jpx_stream.js +40 -28
- package/lib/core/metrics.js +2931 -2931
- package/lib/core/murmurhash3.js +104 -97
- package/lib/core/obj.js +1561 -1053
- package/lib/core/operator_list.js +192 -64
- package/lib/core/parser.js +1162 -864
- package/lib/core/pattern.js +224 -75
- package/lib/core/pdf_manager.js +154 -285
- package/lib/core/primitives.js +145 -69
- package/lib/core/ps_parser.js +212 -162
- package/lib/core/standard_fonts.js +245 -244
- package/lib/core/stream.js +353 -81
- package/lib/core/type1_parser.js +218 -68
- package/lib/core/unicode.js +1682 -1655
- package/lib/core/worker.js +233 -302
- package/lib/core/worker_stream.js +168 -0
- package/lib/display/annotation_layer.js +808 -862
- package/lib/display/api.js +1778 -1462
- package/lib/display/api_compatibility.js +14 -9
- package/lib/display/canvas.js +463 -140
- package/lib/display/content_disposition.js +86 -58
- package/lib/display/display_utils.js +524 -0
- package/lib/display/fetch_stream.js +202 -274
- package/lib/display/font_loader.js +311 -333
- package/lib/display/metadata.js +98 -88
- package/lib/display/network.js +343 -347
- package/lib/display/network_utils.js +46 -26
- package/lib/display/node_stream.js +326 -404
- package/lib/display/pattern_helper.js +168 -69
- package/lib/display/svg.js +1296 -885
- package/lib/display/text_layer.js +229 -103
- package/lib/display/transport_stream.js +290 -250
- package/lib/display/webgl.js +116 -83
- package/lib/display/worker_options.js +6 -5
- package/lib/display/xml_parser.js +358 -337
- package/lib/examples/node/domstubs.js +95 -39
- package/lib/pdf.js +49 -31
- package/lib/pdf.worker.js +7 -5
- package/lib/shared/compatibility.js +3 -145
- package/lib/shared/is_node.js +8 -7
- package/lib/shared/message_handler.js +367 -314
- package/lib/shared/util.js +421 -415
- package/lib/test/unit/annotation_spec.js +1570 -690
- package/lib/test/unit/api_spec.js +855 -493
- package/lib/test/unit/bidi_spec.js +12 -12
- package/lib/test/unit/cff_parser_spec.js +88 -61
- package/lib/test/unit/clitests_helper.js +9 -12
- package/lib/test/unit/cmap_spec.js +140 -88
- package/lib/test/unit/colorspace_spec.js +204 -152
- package/lib/test/unit/core_utils_spec.js +211 -0
- package/lib/test/unit/crypto_spec.js +194 -182
- package/lib/test/unit/custom_spec.js +50 -64
- package/lib/test/unit/display_svg_spec.js +53 -38
- package/lib/test/unit/display_utils_spec.js +263 -0
- package/lib/test/unit/document_spec.js +17 -22
- package/lib/test/unit/encodings_spec.js +15 -57
- package/lib/test/unit/evaluator_spec.js +90 -83
- package/lib/test/unit/fetch_stream_spec.js +111 -0
- package/lib/test/unit/function_spec.js +219 -205
- package/lib/test/unit/jasmine-boot.js +68 -39
- package/lib/test/unit/message_handler_spec.js +187 -160
- package/lib/test/unit/metadata_spec.js +87 -34
- package/lib/test/unit/murmurhash3_spec.js +13 -13
- package/lib/test/unit/network_spec.js +26 -59
- package/lib/test/unit/network_utils_spec.js +187 -121
- package/lib/test/unit/node_stream_spec.js +98 -90
- package/lib/test/unit/parser_spec.js +173 -131
- package/lib/test/unit/pdf_find_controller_spec.js +148 -67
- package/lib/test/unit/pdf_find_utils_spec.js +35 -34
- package/lib/test/unit/pdf_history_spec.js +45 -33
- package/lib/test/unit/primitives_spec.js +161 -126
- package/lib/test/unit/stream_spec.js +22 -15
- package/lib/test/unit/test_utils.js +149 -98
- package/lib/test/unit/testreporter.js +36 -18
- package/lib/test/unit/type1_parser_spec.js +46 -44
- package/lib/test/unit/ui_utils_spec.js +388 -372
- package/lib/test/unit/unicode_spec.js +49 -46
- package/lib/test/unit/util_spec.js +144 -248
- package/lib/web/annotation_layer_builder.js +75 -95
- package/lib/web/app.js +1538 -1147
- package/lib/web/app_options.js +116 -104
- package/lib/web/base_viewer.js +950 -775
- package/lib/web/chromecom.js +217 -225
- package/lib/web/debugger.js +236 -148
- package/lib/web/download_manager.js +50 -50
- package/lib/web/firefox_print_service.js +51 -33
- package/lib/web/firefoxcom.js +225 -352
- package/lib/web/genericcom.js +30 -93
- package/lib/web/genericl10n.js +26 -143
- package/lib/web/grab_to_pan.js +57 -33
- package/lib/web/interfaces.js +105 -232
- package/lib/web/overlay_manager.js +73 -227
- package/lib/web/password_prompt.js +44 -62
- package/lib/web/pdf_attachment_viewer.js +118 -123
- package/lib/web/pdf_cursor_tools.js +89 -93
- package/lib/web/pdf_document_properties.js +242 -281
- package/lib/web/pdf_find_bar.js +157 -163
- package/lib/web/pdf_find_controller.js +598 -454
- package/lib/web/pdf_find_utils.js +32 -16
- package/lib/web/pdf_history.js +481 -355
- package/lib/web/pdf_link_service.js +355 -323
- package/lib/web/pdf_outline_viewer.js +167 -152
- package/lib/web/pdf_page_view.js +511 -457
- package/lib/web/pdf_presentation_mode.js +347 -335
- package/lib/web/pdf_print_service.js +133 -103
- package/lib/web/pdf_rendering_queue.js +98 -100
- package/lib/web/pdf_sidebar.js +323 -299
- package/lib/web/pdf_sidebar_resizer.js +107 -108
- package/lib/web/pdf_single_page_viewer.js +94 -146
- package/lib/web/pdf_thumbnail_view.js +319 -269
- package/lib/web/pdf_thumbnail_viewer.js +219 -199
- package/lib/web/pdf_viewer.component.js +111 -32
- package/lib/web/pdf_viewer.js +61 -101
- package/lib/web/preferences.js +87 -272
- package/lib/web/secondary_toolbar.js +207 -220
- package/lib/web/text_layer_builder.js +322 -322
- package/lib/web/toolbar.js +227 -180
- package/lib/web/ui_utils.js +476 -421
- package/lib/web/view_history.js +59 -208
- package/lib/web/viewer_compatibility.js +9 -6
- package/package.json +2 -9
- package/web/pdf_viewer.css +36 -22
- package/web/pdf_viewer.js +4407 -4516
- package/web/pdf_viewer.js.map +1 -1
- package/webpack.js +14 -5
- package/external/streams/streams-lib.js +0 -3962
- package/external/url/url-lib.js +0 -627
- package/lib/display/dom_utils.js +0 -441
- package/lib/shared/streams_polyfill.js +0 -39
- package/lib/shared/url_polyfill.js +0 -50
- package/lib/test/unit/dom_utils_spec.js +0 -89
- package/lib/web/dom_events.js +0 -140
package/lib/core/obj.js
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
* @licstart The following is the entire license notice for the
|
3
3
|
* Javascript code in this page
|
4
4
|
*
|
5
|
-
* Copyright
|
5
|
+
* Copyright 2020 Mozilla Foundation
|
6
6
|
*
|
7
7
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
* you may not use this file except in compliance with the License.
|
@@ -19,777 +19,1103 @@
|
|
19
19
|
* @licend The above is the entire license notice for the
|
20
20
|
* Javascript code in this page
|
21
21
|
*/
|
22
|
-
|
22
|
+
"use strict";
|
23
23
|
|
24
24
|
Object.defineProperty(exports, "__esModule", {
|
25
25
|
value: true
|
26
26
|
});
|
27
|
-
exports.FileSpec = exports.XRef = exports.ObjectLoader = exports.Catalog =
|
27
|
+
exports.FileSpec = exports.XRef = exports.ObjectLoader = exports.Catalog = void 0;
|
28
28
|
|
29
|
-
var
|
29
|
+
var _util = require("../shared/util.js");
|
30
30
|
|
31
|
-
var
|
31
|
+
var _primitives = require("./primitives.js");
|
32
32
|
|
33
|
-
var
|
33
|
+
var _parser = require("./parser.js");
|
34
34
|
|
35
|
-
var
|
35
|
+
var _core_utils = require("./core_utils.js");
|
36
36
|
|
37
|
-
var
|
37
|
+
var _crypto = require("./crypto.js");
|
38
38
|
|
39
|
-
var
|
39
|
+
var _colorspace = require("./colorspace.js");
|
40
40
|
|
41
|
-
|
41
|
+
function fetchDestination(dest) {
|
42
|
+
return (0, _primitives.isDict)(dest) ? dest.get("D") : dest;
|
43
|
+
}
|
42
44
|
|
43
|
-
|
45
|
+
class Catalog {
|
46
|
+
constructor(pdfManager, xref) {
|
47
|
+
this.pdfManager = pdfManager;
|
48
|
+
this.xref = xref;
|
49
|
+
this.catDict = xref.getCatalogObj();
|
44
50
|
|
45
|
-
|
51
|
+
if (!(0, _primitives.isDict)(this.catDict)) {
|
52
|
+
throw new _util.FormatError("Catalog object is not a dictionary.");
|
53
|
+
}
|
46
54
|
|
47
|
-
|
55
|
+
this.fontCache = new _primitives.RefSetCache();
|
56
|
+
this.builtInCMapCache = new Map();
|
57
|
+
this.pageKidsCountCache = new _primitives.RefSetCache();
|
58
|
+
}
|
48
59
|
|
49
|
-
|
60
|
+
get metadata() {
|
61
|
+
const streamRef = this.catDict.getRaw("Metadata");
|
50
62
|
|
51
|
-
|
63
|
+
if (!(0, _primitives.isRef)(streamRef)) {
|
64
|
+
return (0, _util.shadow)(this, "metadata", null);
|
65
|
+
}
|
52
66
|
|
53
|
-
|
67
|
+
const suppressEncryption = !(this.xref.encrypt && this.xref.encrypt.encryptMetadata);
|
68
|
+
const stream = this.xref.fetch(streamRef, suppressEncryption);
|
69
|
+
let metadata;
|
54
70
|
|
55
|
-
|
71
|
+
if (stream && (0, _primitives.isDict)(stream.dict)) {
|
72
|
+
const type = stream.dict.get("Type");
|
73
|
+
const subtype = stream.dict.get("Subtype");
|
56
74
|
|
57
|
-
|
75
|
+
if ((0, _primitives.isName)(type, "Metadata") && (0, _primitives.isName)(subtype, "XML")) {
|
76
|
+
try {
|
77
|
+
metadata = (0, _util.stringToUTF8String)((0, _util.bytesToString)(stream.getBytes()));
|
78
|
+
} catch (e) {
|
79
|
+
if (e instanceof _core_utils.MissingDataException) {
|
80
|
+
throw e;
|
81
|
+
}
|
58
82
|
|
59
|
-
|
83
|
+
(0, _util.info)("Skipping invalid metadata.");
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
60
87
|
|
61
|
-
|
62
|
-
|
63
|
-
}
|
88
|
+
return (0, _util.shadow)(this, "metadata", metadata);
|
89
|
+
}
|
64
90
|
|
65
|
-
|
66
|
-
|
67
|
-
_classCallCheck(this, Catalog);
|
91
|
+
get toplevelPagesDict() {
|
92
|
+
const pagesObj = this.catDict.get("Pages");
|
68
93
|
|
69
|
-
|
70
|
-
|
71
|
-
this.catDict = xref.getCatalogObj();
|
72
|
-
if (!(0, _primitives.isDict)(this.catDict)) {
|
73
|
-
throw new _util.FormatError('Catalog object is not a dictionary.');
|
94
|
+
if (!(0, _primitives.isDict)(pagesObj)) {
|
95
|
+
throw new _util.FormatError("Invalid top-level pages dictionary.");
|
74
96
|
}
|
75
|
-
|
76
|
-
this
|
77
|
-
this.pageKidsCountCache = new _primitives.RefSetCache();
|
97
|
+
|
98
|
+
return (0, _util.shadow)(this, "toplevelPagesDict", pagesObj);
|
78
99
|
}
|
79
100
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
if (!(0, _primitives.isRef)(obj)) {
|
89
|
-
return null;
|
101
|
+
get documentOutline() {
|
102
|
+
let obj = null;
|
103
|
+
|
104
|
+
try {
|
105
|
+
obj = this._readDocumentOutline();
|
106
|
+
} catch (ex) {
|
107
|
+
if (ex instanceof _core_utils.MissingDataException) {
|
108
|
+
throw ex;
|
90
109
|
}
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
110
|
+
|
111
|
+
(0, _util.warn)("Unable to read document outline.");
|
112
|
+
}
|
113
|
+
|
114
|
+
return (0, _util.shadow)(this, "documentOutline", obj);
|
115
|
+
}
|
116
|
+
|
117
|
+
_readDocumentOutline() {
|
118
|
+
let obj = this.catDict.get("Outlines");
|
119
|
+
|
120
|
+
if (!(0, _primitives.isDict)(obj)) {
|
121
|
+
return null;
|
122
|
+
}
|
123
|
+
|
124
|
+
obj = obj.getRaw("First");
|
125
|
+
|
126
|
+
if (!(0, _primitives.isRef)(obj)) {
|
127
|
+
return null;
|
128
|
+
}
|
129
|
+
|
130
|
+
const root = {
|
131
|
+
items: []
|
132
|
+
};
|
133
|
+
const queue = [{
|
134
|
+
obj,
|
135
|
+
parent: root
|
136
|
+
}];
|
137
|
+
const processed = new _primitives.RefSet();
|
138
|
+
processed.put(obj);
|
139
|
+
const xref = this.xref,
|
99
140
|
blackColor = new Uint8ClampedArray(3);
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
throw new _util.FormatError('Invalid outline item encountered.');
|
108
|
-
}
|
109
|
-
var data = {
|
110
|
-
url: null,
|
111
|
-
dest: null
|
112
|
-
};
|
113
|
-
Catalog.parseDestDictionary({
|
114
|
-
destDict: outlineDict,
|
115
|
-
resultObj: data,
|
116
|
-
docBaseUrl: this.pdfManager.docBaseUrl
|
117
|
-
});
|
118
|
-
var title = outlineDict.get('Title');
|
119
|
-
var flags = outlineDict.get('F') || 0;
|
120
|
-
var color = outlineDict.getArray('C');
|
121
|
-
var rgbColor = blackColor;
|
122
|
-
if (Array.isArray(color) && color.length === 3 && (color[0] !== 0 || color[1] !== 0 || color[2] !== 0)) {
|
123
|
-
rgbColor = _colorspace.ColorSpace.singletons.rgb.getRgb(color, 0);
|
124
|
-
}
|
125
|
-
var outlineItem = {
|
126
|
-
dest: data.dest,
|
127
|
-
url: data.url,
|
128
|
-
unsafeUrl: data.unsafeUrl,
|
129
|
-
newWindow: data.newWindow,
|
130
|
-
title: (0, _util.stringToPDFString)(title),
|
131
|
-
color: rgbColor,
|
132
|
-
count: outlineDict.get('Count'),
|
133
|
-
bold: !!(flags & 2),
|
134
|
-
italic: !!(flags & 1),
|
135
|
-
items: []
|
136
|
-
};
|
137
|
-
i.parent.items.push(outlineItem);
|
138
|
-
obj = outlineDict.getRaw('First');
|
139
|
-
if ((0, _primitives.isRef)(obj) && !processed.has(obj)) {
|
140
|
-
queue.push({
|
141
|
-
obj: obj,
|
142
|
-
parent: outlineItem
|
143
|
-
});
|
144
|
-
processed.put(obj);
|
145
|
-
}
|
146
|
-
obj = outlineDict.getRaw('Next');
|
147
|
-
if ((0, _primitives.isRef)(obj) && !processed.has(obj)) {
|
148
|
-
queue.push({
|
149
|
-
obj: obj,
|
150
|
-
parent: i.parent
|
151
|
-
});
|
152
|
-
processed.put(obj);
|
153
|
-
}
|
141
|
+
|
142
|
+
while (queue.length > 0) {
|
143
|
+
const i = queue.shift();
|
144
|
+
const outlineDict = xref.fetchIfRef(i.obj);
|
145
|
+
|
146
|
+
if (outlineDict === null) {
|
147
|
+
continue;
|
154
148
|
}
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
key: '_readPermissions',
|
159
|
-
value: function _readPermissions() {
|
160
|
-
var encrypt = this.xref.trailer.get('Encrypt');
|
161
|
-
if (!(0, _primitives.isDict)(encrypt)) {
|
162
|
-
return null;
|
149
|
+
|
150
|
+
if (!outlineDict.has("Title")) {
|
151
|
+
throw new _util.FormatError("Invalid outline item encountered.");
|
163
152
|
}
|
164
|
-
|
165
|
-
|
166
|
-
|
153
|
+
|
154
|
+
const data = {
|
155
|
+
url: null,
|
156
|
+
dest: null
|
157
|
+
};
|
158
|
+
Catalog.parseDestDictionary({
|
159
|
+
destDict: outlineDict,
|
160
|
+
resultObj: data,
|
161
|
+
docBaseUrl: this.pdfManager.docBaseUrl
|
162
|
+
});
|
163
|
+
const title = outlineDict.get("Title");
|
164
|
+
const flags = outlineDict.get("F") || 0;
|
165
|
+
const color = outlineDict.getArray("C");
|
166
|
+
const count = outlineDict.get("Count");
|
167
|
+
let rgbColor = blackColor;
|
168
|
+
|
169
|
+
if (Array.isArray(color) && color.length === 3 && (color[0] !== 0 || color[1] !== 0 || color[2] !== 0)) {
|
170
|
+
rgbColor = _colorspace.ColorSpace.singletons.rgb.getRgb(color, 0);
|
167
171
|
}
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
172
|
+
|
173
|
+
const outlineItem = {
|
174
|
+
dest: data.dest,
|
175
|
+
url: data.url,
|
176
|
+
unsafeUrl: data.unsafeUrl,
|
177
|
+
newWindow: data.newWindow,
|
178
|
+
title: (0, _util.stringToPDFString)(title),
|
179
|
+
color: rgbColor,
|
180
|
+
count: Number.isInteger(count) ? count : undefined,
|
181
|
+
bold: !!(flags & 2),
|
182
|
+
italic: !!(flags & 1),
|
183
|
+
items: []
|
184
|
+
};
|
185
|
+
i.parent.items.push(outlineItem);
|
186
|
+
obj = outlineDict.getRaw("First");
|
187
|
+
|
188
|
+
if ((0, _primitives.isRef)(obj) && !processed.has(obj)) {
|
189
|
+
queue.push({
|
190
|
+
obj,
|
191
|
+
parent: outlineItem
|
192
|
+
});
|
193
|
+
processed.put(obj);
|
194
|
+
}
|
195
|
+
|
196
|
+
obj = outlineDict.getRaw("Next");
|
197
|
+
|
198
|
+
if ((0, _primitives.isRef)(obj) && !processed.has(obj)) {
|
199
|
+
queue.push({
|
200
|
+
obj,
|
201
|
+
parent: i.parent
|
202
|
+
});
|
203
|
+
processed.put(obj);
|
175
204
|
}
|
176
|
-
return permissions;
|
177
205
|
}
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
206
|
+
|
207
|
+
return root.items.length > 0 ? root.items : null;
|
208
|
+
}
|
209
|
+
|
210
|
+
get permissions() {
|
211
|
+
let permissions = null;
|
212
|
+
|
213
|
+
try {
|
214
|
+
permissions = this._readPermissions();
|
215
|
+
} catch (ex) {
|
216
|
+
if (ex instanceof _core_utils.MissingDataException) {
|
217
|
+
throw ex;
|
184
218
|
}
|
219
|
+
|
220
|
+
(0, _util.warn)("Unable to read permissions.");
|
221
|
+
}
|
222
|
+
|
223
|
+
return (0, _util.shadow)(this, "permissions", permissions);
|
224
|
+
}
|
225
|
+
|
226
|
+
_readPermissions() {
|
227
|
+
const encrypt = this.xref.trailer.get("Encrypt");
|
228
|
+
|
229
|
+
if (!(0, _primitives.isDict)(encrypt)) {
|
230
|
+
return null;
|
231
|
+
}
|
232
|
+
|
233
|
+
let flags = encrypt.get("P");
|
234
|
+
|
235
|
+
if (!(0, _util.isNum)(flags)) {
|
185
236
|
return null;
|
186
237
|
}
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
238
|
+
|
239
|
+
flags += 2 ** 32;
|
240
|
+
const permissions = [];
|
241
|
+
|
242
|
+
for (const key in _util.PermissionFlag) {
|
243
|
+
const value = _util.PermissionFlag[key];
|
244
|
+
|
245
|
+
if (flags & value) {
|
246
|
+
permissions.push(value);
|
195
247
|
}
|
196
248
|
}
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
249
|
+
|
250
|
+
return permissions;
|
251
|
+
}
|
252
|
+
|
253
|
+
get numPages() {
|
254
|
+
const obj = this.toplevelPagesDict.get("Count");
|
255
|
+
|
256
|
+
if (!Number.isInteger(obj)) {
|
257
|
+
throw new _util.FormatError("Page count in top-level pages dictionary is not an integer.");
|
258
|
+
}
|
259
|
+
|
260
|
+
return (0, _util.shadow)(this, "numPages", obj);
|
261
|
+
}
|
262
|
+
|
263
|
+
get destinations() {
|
264
|
+
const obj = this._readDests(),
|
265
|
+
dests = Object.create(null);
|
266
|
+
|
267
|
+
if (obj instanceof NameTree) {
|
268
|
+
const names = obj.getAll();
|
269
|
+
|
270
|
+
for (const name in names) {
|
271
|
+
dests[name] = fetchDestination(names[name]);
|
203
272
|
}
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
273
|
+
} else if (obj instanceof _primitives.Dict) {
|
274
|
+
obj.forEach(function (key, value) {
|
275
|
+
if (value) {
|
276
|
+
dests[key] = fetchDestination(value);
|
277
|
+
}
|
278
|
+
});
|
279
|
+
}
|
280
|
+
|
281
|
+
return (0, _util.shadow)(this, "destinations", dests);
|
282
|
+
}
|
283
|
+
|
284
|
+
getDestination(destinationId) {
|
285
|
+
const obj = this._readDests();
|
286
|
+
|
287
|
+
if (obj instanceof NameTree || obj instanceof _primitives.Dict) {
|
288
|
+
return fetchDestination(obj.get(destinationId) || null);
|
289
|
+
}
|
290
|
+
|
291
|
+
return null;
|
292
|
+
}
|
293
|
+
|
294
|
+
_readDests() {
|
295
|
+
const obj = this.catDict.get("Names");
|
296
|
+
|
297
|
+
if (obj && obj.has("Dests")) {
|
298
|
+
return new NameTree(obj.getRaw("Dests"), this.xref);
|
299
|
+
} else if (this.catDict.has("Dests")) {
|
300
|
+
return this.catDict.get("Dests");
|
301
|
+
}
|
302
|
+
|
303
|
+
return undefined;
|
304
|
+
}
|
305
|
+
|
306
|
+
get pageLabels() {
|
307
|
+
let obj = null;
|
308
|
+
|
309
|
+
try {
|
310
|
+
obj = this._readPageLabels();
|
311
|
+
} catch (ex) {
|
312
|
+
if (ex instanceof _core_utils.MissingDataException) {
|
313
|
+
throw ex;
|
314
|
+
}
|
315
|
+
|
316
|
+
(0, _util.warn)("Unable to read page labels.");
|
317
|
+
}
|
318
|
+
|
319
|
+
return (0, _util.shadow)(this, "pageLabels", obj);
|
320
|
+
}
|
321
|
+
|
322
|
+
_readPageLabels() {
|
323
|
+
const obj = this.catDict.getRaw("PageLabels");
|
324
|
+
|
325
|
+
if (!obj) {
|
326
|
+
return null;
|
327
|
+
}
|
328
|
+
|
329
|
+
const pageLabels = new Array(this.numPages);
|
330
|
+
let style = null,
|
331
|
+
prefix = "";
|
332
|
+
const numberTree = new NumberTree(obj, this.xref);
|
333
|
+
const nums = numberTree.getAll();
|
334
|
+
let currentLabel = "",
|
335
|
+
currentIndex = 1;
|
336
|
+
|
337
|
+
for (let i = 0, ii = this.numPages; i < ii; i++) {
|
338
|
+
if (i in nums) {
|
339
|
+
const labelDict = nums[i];
|
340
|
+
|
341
|
+
if (!(0, _primitives.isDict)(labelDict)) {
|
342
|
+
throw new _util.FormatError("PageLabel is not a dictionary.");
|
343
|
+
}
|
344
|
+
|
345
|
+
if (labelDict.has("Type") && !(0, _primitives.isName)(labelDict.get("Type"), "PageLabel")) {
|
346
|
+
throw new _util.FormatError("Invalid type in PageLabel dictionary.");
|
347
|
+
}
|
348
|
+
|
349
|
+
if (labelDict.has("S")) {
|
350
|
+
const s = labelDict.get("S");
|
351
|
+
|
352
|
+
if (!(0, _primitives.isName)(s)) {
|
353
|
+
throw new _util.FormatError("Invalid style in PageLabel dictionary.");
|
216
354
|
}
|
217
|
-
|
218
|
-
|
355
|
+
|
356
|
+
style = s.name;
|
357
|
+
} else {
|
358
|
+
style = null;
|
359
|
+
}
|
360
|
+
|
361
|
+
if (labelDict.has("P")) {
|
362
|
+
const p = labelDict.get("P");
|
363
|
+
|
364
|
+
if (!(0, _util.isString)(p)) {
|
365
|
+
throw new _util.FormatError("Invalid prefix in PageLabel dictionary.");
|
219
366
|
}
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
367
|
+
|
368
|
+
prefix = (0, _util.stringToPDFString)(p);
|
369
|
+
} else {
|
370
|
+
prefix = "";
|
371
|
+
}
|
372
|
+
|
373
|
+
if (labelDict.has("St")) {
|
374
|
+
const st = labelDict.get("St");
|
375
|
+
|
376
|
+
if (!(Number.isInteger(st) && st >= 1)) {
|
377
|
+
throw new _util.FormatError("Invalid start in PageLabel dictionary.");
|
228
378
|
}
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
379
|
+
|
380
|
+
currentIndex = st;
|
381
|
+
} else {
|
382
|
+
currentIndex = 1;
|
383
|
+
}
|
384
|
+
}
|
385
|
+
|
386
|
+
switch (style) {
|
387
|
+
case "D":
|
388
|
+
currentLabel = currentIndex;
|
389
|
+
break;
|
390
|
+
|
391
|
+
case "R":
|
392
|
+
case "r":
|
393
|
+
currentLabel = (0, _core_utils.toRomanNumerals)(currentIndex, style === "r");
|
394
|
+
break;
|
395
|
+
|
396
|
+
case "A":
|
397
|
+
case "a":
|
398
|
+
const LIMIT = 26;
|
399
|
+
const A_UPPER_CASE = 0x41,
|
400
|
+
A_LOWER_CASE = 0x61;
|
401
|
+
const baseCharCode = style === "a" ? A_LOWER_CASE : A_UPPER_CASE;
|
402
|
+
const letterIndex = currentIndex - 1;
|
403
|
+
const character = String.fromCharCode(baseCharCode + letterIndex % LIMIT);
|
404
|
+
const charBuf = [];
|
405
|
+
|
406
|
+
for (let j = 0, jj = letterIndex / LIMIT | 0; j <= jj; j++) {
|
407
|
+
charBuf.push(character);
|
237
408
|
}
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
currentIndex = 1;
|
409
|
+
|
410
|
+
currentLabel = charBuf.join("");
|
411
|
+
break;
|
412
|
+
|
413
|
+
default:
|
414
|
+
if (style) {
|
415
|
+
throw new _util.FormatError(`Invalid style "${style}" in PageLabel dictionary.`);
|
246
416
|
}
|
417
|
+
|
418
|
+
currentLabel = "";
|
419
|
+
}
|
420
|
+
|
421
|
+
pageLabels[i] = prefix + currentLabel;
|
422
|
+
currentIndex++;
|
423
|
+
}
|
424
|
+
|
425
|
+
return pageLabels;
|
426
|
+
}
|
427
|
+
|
428
|
+
get pageLayout() {
|
429
|
+
const obj = this.catDict.get("PageLayout");
|
430
|
+
let pageLayout = "";
|
431
|
+
|
432
|
+
if ((0, _primitives.isName)(obj)) {
|
433
|
+
switch (obj.name) {
|
434
|
+
case "SinglePage":
|
435
|
+
case "OneColumn":
|
436
|
+
case "TwoColumnLeft":
|
437
|
+
case "TwoColumnRight":
|
438
|
+
case "TwoPageLeft":
|
439
|
+
case "TwoPageRight":
|
440
|
+
pageLayout = obj.name;
|
441
|
+
}
|
442
|
+
}
|
443
|
+
|
444
|
+
return (0, _util.shadow)(this, "pageLayout", pageLayout);
|
445
|
+
}
|
446
|
+
|
447
|
+
get pageMode() {
|
448
|
+
const obj = this.catDict.get("PageMode");
|
449
|
+
let pageMode = "UseNone";
|
450
|
+
|
451
|
+
if ((0, _primitives.isName)(obj)) {
|
452
|
+
switch (obj.name) {
|
453
|
+
case "UseNone":
|
454
|
+
case "UseOutlines":
|
455
|
+
case "UseThumbs":
|
456
|
+
case "FullScreen":
|
457
|
+
case "UseOC":
|
458
|
+
case "UseAttachments":
|
459
|
+
pageMode = obj.name;
|
460
|
+
}
|
461
|
+
}
|
462
|
+
|
463
|
+
return (0, _util.shadow)(this, "pageMode", pageMode);
|
464
|
+
}
|
465
|
+
|
466
|
+
get viewerPreferences() {
|
467
|
+
const ViewerPreferencesValidators = {
|
468
|
+
HideToolbar: _util.isBool,
|
469
|
+
HideMenubar: _util.isBool,
|
470
|
+
HideWindowUI: _util.isBool,
|
471
|
+
FitWindow: _util.isBool,
|
472
|
+
CenterWindow: _util.isBool,
|
473
|
+
DisplayDocTitle: _util.isBool,
|
474
|
+
NonFullScreenPageMode: _primitives.isName,
|
475
|
+
Direction: _primitives.isName,
|
476
|
+
ViewArea: _primitives.isName,
|
477
|
+
ViewClip: _primitives.isName,
|
478
|
+
PrintArea: _primitives.isName,
|
479
|
+
PrintClip: _primitives.isName,
|
480
|
+
PrintScaling: _primitives.isName,
|
481
|
+
Duplex: _primitives.isName,
|
482
|
+
PickTrayByPDFSize: _util.isBool,
|
483
|
+
PrintPageRange: Array.isArray,
|
484
|
+
NumCopies: Number.isInteger
|
485
|
+
};
|
486
|
+
const obj = this.catDict.get("ViewerPreferences");
|
487
|
+
const prefs = Object.create(null);
|
488
|
+
|
489
|
+
if ((0, _primitives.isDict)(obj)) {
|
490
|
+
for (const key in ViewerPreferencesValidators) {
|
491
|
+
if (!obj.has(key)) {
|
492
|
+
continue;
|
493
|
+
}
|
494
|
+
|
495
|
+
const value = obj.get(key);
|
496
|
+
|
497
|
+
if (!ViewerPreferencesValidators[key](value)) {
|
498
|
+
(0, _util.info)(`Bad value in ViewerPreferences for "${key}".`);
|
499
|
+
continue;
|
247
500
|
}
|
248
|
-
|
249
|
-
|
250
|
-
|
501
|
+
|
502
|
+
let prefValue;
|
503
|
+
|
504
|
+
switch (key) {
|
505
|
+
case "NonFullScreenPageMode":
|
506
|
+
switch (value.name) {
|
507
|
+
case "UseNone":
|
508
|
+
case "UseOutlines":
|
509
|
+
case "UseThumbs":
|
510
|
+
case "UseOC":
|
511
|
+
prefValue = value.name;
|
512
|
+
break;
|
513
|
+
|
514
|
+
default:
|
515
|
+
prefValue = "UseNone";
|
516
|
+
}
|
517
|
+
|
251
518
|
break;
|
252
|
-
|
253
|
-
case
|
254
|
-
|
519
|
+
|
520
|
+
case "Direction":
|
521
|
+
switch (value.name) {
|
522
|
+
case "L2R":
|
523
|
+
case "R2L":
|
524
|
+
prefValue = value.name;
|
525
|
+
break;
|
526
|
+
|
527
|
+
default:
|
528
|
+
prefValue = "L2R";
|
529
|
+
}
|
530
|
+
|
255
531
|
break;
|
256
|
-
|
257
|
-
case
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
532
|
+
|
533
|
+
case "ViewArea":
|
534
|
+
case "ViewClip":
|
535
|
+
case "PrintArea":
|
536
|
+
case "PrintClip":
|
537
|
+
switch (value.name) {
|
538
|
+
case "MediaBox":
|
539
|
+
case "CropBox":
|
540
|
+
case "BleedBox":
|
541
|
+
case "TrimBox":
|
542
|
+
case "ArtBox":
|
543
|
+
prefValue = value.name;
|
544
|
+
break;
|
545
|
+
|
546
|
+
default:
|
547
|
+
prefValue = "CropBox";
|
267
548
|
}
|
268
|
-
|
549
|
+
|
269
550
|
break;
|
270
|
-
|
271
|
-
|
272
|
-
|
551
|
+
|
552
|
+
case "PrintScaling":
|
553
|
+
switch (value.name) {
|
554
|
+
case "None":
|
555
|
+
case "AppDefault":
|
556
|
+
prefValue = value.name;
|
557
|
+
break;
|
558
|
+
|
559
|
+
default:
|
560
|
+
prefValue = "AppDefault";
|
561
|
+
}
|
562
|
+
|
563
|
+
break;
|
564
|
+
|
565
|
+
case "Duplex":
|
566
|
+
switch (value.name) {
|
567
|
+
case "Simplex":
|
568
|
+
case "DuplexFlipShortEdge":
|
569
|
+
case "DuplexFlipLongEdge":
|
570
|
+
prefValue = value.name;
|
571
|
+
break;
|
572
|
+
|
573
|
+
default:
|
574
|
+
prefValue = "None";
|
575
|
+
}
|
576
|
+
|
577
|
+
break;
|
578
|
+
|
579
|
+
case "PrintPageRange":
|
580
|
+
const length = value.length;
|
581
|
+
|
582
|
+
if (length % 2 !== 0) {
|
583
|
+
break;
|
584
|
+
}
|
585
|
+
|
586
|
+
const isValid = value.every((page, i, arr) => {
|
587
|
+
return Number.isInteger(page) && page > 0 && (i === 0 || page >= arr[i - 1]) && page <= this.numPages;
|
588
|
+
});
|
589
|
+
|
590
|
+
if (isValid) {
|
591
|
+
prefValue = value;
|
592
|
+
}
|
593
|
+
|
594
|
+
break;
|
595
|
+
|
596
|
+
case "NumCopies":
|
597
|
+
if (value > 0) {
|
598
|
+
prefValue = value;
|
273
599
|
}
|
274
|
-
|
600
|
+
|
601
|
+
break;
|
602
|
+
|
603
|
+
default:
|
604
|
+
(0, _util.assert)(typeof value === "boolean");
|
605
|
+
prefValue = value;
|
606
|
+
}
|
607
|
+
|
608
|
+
if (prefValue !== undefined) {
|
609
|
+
prefs[key] = prefValue;
|
610
|
+
} else {
|
611
|
+
(0, _util.info)(`Bad value in ViewerPreferences for "${key}".`);
|
275
612
|
}
|
276
|
-
pageLabels[i] = prefix + currentLabel;
|
277
|
-
currentIndex++;
|
278
613
|
}
|
279
|
-
return pageLabels;
|
280
614
|
}
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
615
|
+
|
616
|
+
return (0, _util.shadow)(this, "viewerPreferences", prefs);
|
617
|
+
}
|
618
|
+
|
619
|
+
get openAction() {
|
620
|
+
const obj = this.catDict.get("OpenAction");
|
621
|
+
let openAction = null;
|
622
|
+
|
623
|
+
if ((0, _primitives.isDict)(obj)) {
|
624
|
+
const destDict = new _primitives.Dict(this.xref);
|
625
|
+
destDict.set("A", obj);
|
626
|
+
const resultObj = {
|
627
|
+
url: null,
|
628
|
+
dest: null,
|
629
|
+
action: null
|
630
|
+
};
|
631
|
+
Catalog.parseDestDictionary({
|
632
|
+
destDict,
|
633
|
+
resultObj
|
290
634
|
});
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
635
|
+
|
636
|
+
if (Array.isArray(resultObj.dest)) {
|
637
|
+
if (!openAction) {
|
638
|
+
openAction = Object.create(null);
|
295
639
|
}
|
296
|
-
|
297
|
-
|
298
|
-
})
|
640
|
+
|
641
|
+
openAction.dest = resultObj.dest;
|
642
|
+
} else if (resultObj.action) {
|
643
|
+
if (!openAction) {
|
644
|
+
openAction = Object.create(null);
|
645
|
+
}
|
646
|
+
|
647
|
+
openAction.action = resultObj.action;
|
648
|
+
}
|
649
|
+
} else if (Array.isArray(obj)) {
|
650
|
+
if (!openAction) {
|
651
|
+
openAction = Object.create(null);
|
652
|
+
}
|
653
|
+
|
654
|
+
openAction.dest = obj;
|
655
|
+
}
|
656
|
+
|
657
|
+
return (0, _util.shadow)(this, "openAction", openAction);
|
658
|
+
}
|
659
|
+
|
660
|
+
get attachments() {
|
661
|
+
const obj = this.catDict.get("Names");
|
662
|
+
let attachments = null;
|
663
|
+
|
664
|
+
if (obj && obj.has("EmbeddedFiles")) {
|
665
|
+
const nameTree = new NameTree(obj.getRaw("EmbeddedFiles"), this.xref);
|
666
|
+
const names = nameTree.getAll();
|
667
|
+
|
668
|
+
for (const name in names) {
|
669
|
+
const fs = new FileSpec(names[name], this.xref);
|
670
|
+
|
671
|
+
if (!attachments) {
|
672
|
+
attachments = Object.create(null);
|
673
|
+
}
|
674
|
+
|
675
|
+
attachments[(0, _util.stringToPDFString)(name)] = fs.serializable;
|
676
|
+
}
|
299
677
|
}
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
678
|
+
|
679
|
+
return (0, _util.shadow)(this, "attachments", attachments);
|
680
|
+
}
|
681
|
+
|
682
|
+
get javaScript() {
|
683
|
+
const obj = this.catDict.get("Names");
|
684
|
+
let javaScript = null;
|
685
|
+
|
686
|
+
function appendIfJavaScriptDict(jsDict) {
|
687
|
+
const type = jsDict.get("S");
|
688
|
+
|
689
|
+
if (!(0, _primitives.isName)(type, "JavaScript")) {
|
690
|
+
return;
|
691
|
+
}
|
692
|
+
|
693
|
+
let js = jsDict.get("JS");
|
694
|
+
|
695
|
+
if ((0, _primitives.isStream)(js)) {
|
696
|
+
js = (0, _util.bytesToString)(js.getBytes());
|
697
|
+
} else if (!(0, _util.isString)(js)) {
|
698
|
+
return;
|
699
|
+
}
|
700
|
+
|
701
|
+
if (!javaScript) {
|
702
|
+
javaScript = [];
|
703
|
+
}
|
704
|
+
|
705
|
+
javaScript.push((0, _util.stringToPDFString)(js));
|
706
|
+
}
|
707
|
+
|
708
|
+
if (obj && obj.has("JavaScript")) {
|
709
|
+
const nameTree = new NameTree(obj.getRaw("JavaScript"), this.xref);
|
710
|
+
const names = nameTree.getAll();
|
711
|
+
|
712
|
+
for (const name in names) {
|
713
|
+
const jsDict = names[name];
|
714
|
+
|
715
|
+
if ((0, _primitives.isDict)(jsDict)) {
|
716
|
+
appendIfJavaScriptDict(jsDict);
|
717
|
+
}
|
718
|
+
}
|
719
|
+
}
|
720
|
+
|
721
|
+
const openAction = this.catDict.get("OpenAction");
|
722
|
+
|
723
|
+
if ((0, _primitives.isDict)(openAction) && (0, _primitives.isName)(openAction.get("S"), "JavaScript")) {
|
724
|
+
appendIfJavaScriptDict(openAction);
|
725
|
+
}
|
726
|
+
|
727
|
+
return (0, _util.shadow)(this, "javaScript", javaScript);
|
728
|
+
}
|
729
|
+
|
730
|
+
fontFallback(id, handler) {
|
731
|
+
const promises = [];
|
732
|
+
this.fontCache.forEach(function (promise) {
|
733
|
+
promises.push(promise);
|
734
|
+
});
|
735
|
+
return Promise.all(promises).then(translatedFonts => {
|
736
|
+
for (const translatedFont of translatedFonts) {
|
737
|
+
if (translatedFont.loadedName === id) {
|
738
|
+
translatedFont.fallback(handler);
|
739
|
+
return;
|
740
|
+
}
|
741
|
+
}
|
742
|
+
});
|
743
|
+
}
|
744
|
+
|
745
|
+
cleanup() {
|
746
|
+
(0, _primitives.clearPrimitiveCaches)();
|
747
|
+
this.pageKidsCountCache.clear();
|
748
|
+
const promises = [];
|
749
|
+
this.fontCache.forEach(function (promise) {
|
750
|
+
promises.push(promise);
|
751
|
+
});
|
752
|
+
return Promise.all(promises).then(translatedFonts => {
|
753
|
+
for (const {
|
754
|
+
dict
|
755
|
+
} of translatedFonts) {
|
756
|
+
delete dict.translated;
|
757
|
+
}
|
758
|
+
|
759
|
+
this.fontCache.clear();
|
760
|
+
this.builtInCMapCache.clear();
|
761
|
+
});
|
762
|
+
}
|
763
|
+
|
764
|
+
getPageDict(pageIndex) {
|
765
|
+
const capability = (0, _util.createPromiseCapability)();
|
766
|
+
const nodesToVisit = [this.catDict.getRaw("Pages")];
|
767
|
+
const visitedNodes = new _primitives.RefSet();
|
768
|
+
const xref = this.xref,
|
306
769
|
pageKidsCountCache = this.pageKidsCountCache;
|
307
|
-
|
308
|
-
|
309
|
-
function next() {
|
310
|
-
var _loop = function _loop() {
|
311
|
-
var currentNode = nodesToVisit.pop();
|
312
|
-
if ((0, _primitives.isRef)(currentNode)) {
|
313
|
-
count = pageKidsCountCache.get(currentNode);
|
314
|
-
if (count > 0 && currentPageIndex + count < pageIndex) {
|
315
|
-
currentPageIndex += count;
|
316
|
-
return 'continue';
|
317
|
-
}
|
318
|
-
xref.fetchAsync(currentNode).then(function (obj) {
|
319
|
-
if ((0, _primitives.isDict)(obj, 'Page') || (0, _primitives.isDict)(obj) && !obj.has('Kids')) {
|
320
|
-
if (pageIndex === currentPageIndex) {
|
321
|
-
if (currentNode && !pageKidsCountCache.has(currentNode)) {
|
322
|
-
pageKidsCountCache.put(currentNode, 1);
|
323
|
-
}
|
324
|
-
capability.resolve([obj, currentNode]);
|
325
|
-
} else {
|
326
|
-
currentPageIndex++;
|
327
|
-
next();
|
328
|
-
}
|
329
|
-
return;
|
330
|
-
}
|
331
|
-
nodesToVisit.push(obj);
|
332
|
-
next();
|
333
|
-
}, capability.reject);
|
334
|
-
return {
|
335
|
-
v: void 0
|
336
|
-
};
|
337
|
-
}
|
338
|
-
if (!(0, _primitives.isDict)(currentNode)) {
|
339
|
-
capability.reject(new _util.FormatError('Page dictionary kid reference points to wrong type of object.'));
|
340
|
-
return {
|
341
|
-
v: void 0
|
342
|
-
};
|
343
|
-
}
|
344
|
-
count = currentNode.get('Count');
|
345
|
-
if (Number.isInteger(count) && count >= 0) {
|
346
|
-
var objId = currentNode.objId;
|
347
|
-
if (objId && !pageKidsCountCache.has(objId)) {
|
348
|
-
pageKidsCountCache.put(objId, count);
|
349
|
-
}
|
350
|
-
if (currentPageIndex + count <= pageIndex) {
|
351
|
-
currentPageIndex += count;
|
352
|
-
return 'continue';
|
353
|
-
}
|
354
|
-
}
|
355
|
-
var kids = currentNode.get('Kids');
|
356
|
-
if (!Array.isArray(kids)) {
|
357
|
-
if ((0, _primitives.isName)(currentNode.get('Type'), 'Page') || !currentNode.has('Type') && currentNode.has('Contents')) {
|
358
|
-
if (currentPageIndex === pageIndex) {
|
359
|
-
capability.resolve([currentNode, null]);
|
360
|
-
return {
|
361
|
-
v: void 0
|
362
|
-
};
|
363
|
-
}
|
364
|
-
currentPageIndex++;
|
365
|
-
return 'continue';
|
366
|
-
}
|
367
|
-
capability.reject(new _util.FormatError('Page dictionary kids object is not an array.'));
|
368
|
-
return {
|
369
|
-
v: void 0
|
370
|
-
};
|
371
|
-
}
|
372
|
-
for (var last = kids.length - 1; last >= 0; last--) {
|
373
|
-
nodesToVisit.push(kids[last]);
|
374
|
-
}
|
375
|
-
};
|
770
|
+
let count,
|
771
|
+
currentPageIndex = 0;
|
376
772
|
|
377
|
-
|
378
|
-
|
773
|
+
function next() {
|
774
|
+
while (nodesToVisit.length) {
|
775
|
+
const currentNode = nodesToVisit.pop();
|
379
776
|
|
380
|
-
|
381
|
-
|
382
|
-
continue;
|
777
|
+
if ((0, _primitives.isRef)(currentNode)) {
|
778
|
+
count = pageKidsCountCache.get(currentNode);
|
383
779
|
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
}
|
388
|
-
capability.reject(new Error('Page index ' + pageIndex + ' not found.'));
|
389
|
-
}
|
390
|
-
next();
|
391
|
-
return capability.promise;
|
392
|
-
}
|
393
|
-
}, {
|
394
|
-
key: 'getPageIndex',
|
395
|
-
value: function getPageIndex(pageRef) {
|
396
|
-
var xref = this.xref;
|
397
|
-
function pagesBeforeRef(kidRef) {
|
398
|
-
var total = 0,
|
399
|
-
parentRef = void 0;
|
400
|
-
return xref.fetchAsync(kidRef).then(function (node) {
|
401
|
-
if ((0, _primitives.isRefsEqual)(kidRef, pageRef) && !(0, _primitives.isDict)(node, 'Page') && !((0, _primitives.isDict)(node) && !node.has('Type') && node.has('Contents'))) {
|
402
|
-
throw new _util.FormatError('The reference does not point to a /Page dictionary.');
|
403
|
-
}
|
404
|
-
if (!node) {
|
405
|
-
return null;
|
406
|
-
}
|
407
|
-
if (!(0, _primitives.isDict)(node)) {
|
408
|
-
throw new _util.FormatError('Node must be a dictionary.');
|
409
|
-
}
|
410
|
-
parentRef = node.getRaw('Parent');
|
411
|
-
return node.getAsync('Parent');
|
412
|
-
}).then(function (parent) {
|
413
|
-
if (!parent) {
|
414
|
-
return null;
|
415
|
-
}
|
416
|
-
if (!(0, _primitives.isDict)(parent)) {
|
417
|
-
throw new _util.FormatError('Parent must be a dictionary.');
|
780
|
+
if (count > 0 && currentPageIndex + count < pageIndex) {
|
781
|
+
currentPageIndex += count;
|
782
|
+
continue;
|
418
783
|
}
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
return
|
784
|
+
|
785
|
+
if (visitedNodes.has(currentNode)) {
|
786
|
+
capability.reject(new _util.FormatError("Pages tree contains circular reference."));
|
787
|
+
return;
|
423
788
|
}
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
}
|
435
|
-
kidPromises.push(xref.fetchAsync(kid).then(function (kid) {
|
436
|
-
if (!(0, _primitives.isDict)(kid)) {
|
437
|
-
throw new _util.FormatError('Kid node must be a dictionary.');
|
438
|
-
}
|
439
|
-
if (kid.has('Count')) {
|
440
|
-
total += kid.get('Count');
|
789
|
+
|
790
|
+
visitedNodes.put(currentNode);
|
791
|
+
xref.fetchAsync(currentNode).then(function (obj) {
|
792
|
+
if ((0, _primitives.isDict)(obj, "Page") || (0, _primitives.isDict)(obj) && !obj.has("Kids")) {
|
793
|
+
if (pageIndex === currentPageIndex) {
|
794
|
+
if (currentNode && !pageKidsCountCache.has(currentNode)) {
|
795
|
+
pageKidsCountCache.put(currentNode, 1);
|
796
|
+
}
|
797
|
+
|
798
|
+
capability.resolve([obj, currentNode]);
|
441
799
|
} else {
|
442
|
-
|
800
|
+
currentPageIndex++;
|
801
|
+
next();
|
443
802
|
}
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
803
|
+
|
804
|
+
return;
|
805
|
+
}
|
806
|
+
|
807
|
+
nodesToVisit.push(obj);
|
808
|
+
next();
|
809
|
+
}, capability.reject);
|
810
|
+
return;
|
811
|
+
}
|
812
|
+
|
813
|
+
if (!(0, _primitives.isDict)(currentNode)) {
|
814
|
+
capability.reject(new _util.FormatError("Page dictionary kid reference points to wrong type of object."));
|
815
|
+
return;
|
816
|
+
}
|
817
|
+
|
818
|
+
count = currentNode.get("Count");
|
819
|
+
|
820
|
+
if (Number.isInteger(count) && count >= 0) {
|
821
|
+
const objId = currentNode.objId;
|
822
|
+
|
823
|
+
if (objId && !pageKidsCountCache.has(objId)) {
|
824
|
+
pageKidsCountCache.put(objId, count);
|
448
825
|
}
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
}
|
454
|
-
var total = 0;
|
455
|
-
function next(ref) {
|
456
|
-
return pagesBeforeRef(ref).then(function (args) {
|
457
|
-
if (!args) {
|
458
|
-
return total;
|
826
|
+
|
827
|
+
if (currentPageIndex + count <= pageIndex) {
|
828
|
+
currentPageIndex += count;
|
829
|
+
continue;
|
459
830
|
}
|
831
|
+
}
|
460
832
|
|
461
|
-
|
462
|
-
count = _args[0],
|
463
|
-
parentRef = _args[1];
|
833
|
+
const kids = currentNode.get("Kids");
|
464
834
|
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
}
|
471
|
-
}, {
|
472
|
-
key: 'metadata',
|
473
|
-
get: function get() {
|
474
|
-
var streamRef = this.catDict.getRaw('Metadata');
|
475
|
-
if (!(0, _primitives.isRef)(streamRef)) {
|
476
|
-
return (0, _util.shadow)(this, 'metadata', null);
|
477
|
-
}
|
478
|
-
var suppressEncryption = !(this.xref.encrypt && this.xref.encrypt.encryptMetadata);
|
479
|
-
var stream = this.xref.fetch(streamRef, suppressEncryption);
|
480
|
-
var metadata = void 0;
|
481
|
-
if (stream && (0, _primitives.isDict)(stream.dict)) {
|
482
|
-
var type = stream.dict.get('Type');
|
483
|
-
var subtype = stream.dict.get('Subtype');
|
484
|
-
if ((0, _primitives.isName)(type, 'Metadata') && (0, _primitives.isName)(subtype, 'XML')) {
|
485
|
-
try {
|
486
|
-
metadata = (0, _util.stringToUTF8String)((0, _util.bytesToString)(stream.getBytes()));
|
487
|
-
} catch (e) {
|
488
|
-
if (e instanceof _util.MissingDataException) {
|
489
|
-
throw e;
|
835
|
+
if (!Array.isArray(kids)) {
|
836
|
+
if ((0, _primitives.isName)(currentNode.get("Type"), "Page") || !currentNode.has("Type") && currentNode.has("Contents")) {
|
837
|
+
if (currentPageIndex === pageIndex) {
|
838
|
+
capability.resolve([currentNode, null]);
|
839
|
+
return;
|
490
840
|
}
|
491
|
-
|
841
|
+
|
842
|
+
currentPageIndex++;
|
843
|
+
continue;
|
492
844
|
}
|
845
|
+
|
846
|
+
capability.reject(new _util.FormatError("Page dictionary kids object is not an array."));
|
847
|
+
return;
|
493
848
|
}
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
}, {
|
498
|
-
key: 'toplevelPagesDict',
|
499
|
-
get: function get() {
|
500
|
-
var pagesObj = this.catDict.get('Pages');
|
501
|
-
if (!(0, _primitives.isDict)(pagesObj)) {
|
502
|
-
throw new _util.FormatError('Invalid top-level pages dictionary.');
|
503
|
-
}
|
504
|
-
return (0, _util.shadow)(this, 'toplevelPagesDict', pagesObj);
|
505
|
-
}
|
506
|
-
}, {
|
507
|
-
key: 'documentOutline',
|
508
|
-
get: function get() {
|
509
|
-
var obj = null;
|
510
|
-
try {
|
511
|
-
obj = this._readDocumentOutline();
|
512
|
-
} catch (ex) {
|
513
|
-
if (ex instanceof _util.MissingDataException) {
|
514
|
-
throw ex;
|
849
|
+
|
850
|
+
for (let last = kids.length - 1; last >= 0; last--) {
|
851
|
+
nodesToVisit.push(kids[last]);
|
515
852
|
}
|
516
|
-
(0, _util.warn)('Unable to read document outline.');
|
517
853
|
}
|
518
|
-
|
854
|
+
|
855
|
+
capability.reject(new Error(`Page index ${pageIndex} not found.`));
|
519
856
|
}
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
857
|
+
|
858
|
+
next();
|
859
|
+
return capability.promise;
|
860
|
+
}
|
861
|
+
|
862
|
+
getPageIndex(pageRef) {
|
863
|
+
const xref = this.xref;
|
864
|
+
|
865
|
+
function pagesBeforeRef(kidRef) {
|
866
|
+
let total = 0,
|
867
|
+
parentRef;
|
868
|
+
return xref.fetchAsync(kidRef).then(function (node) {
|
869
|
+
if ((0, _primitives.isRefsEqual)(kidRef, pageRef) && !(0, _primitives.isDict)(node, "Page") && !((0, _primitives.isDict)(node) && !node.has("Type") && node.has("Contents"))) {
|
870
|
+
throw new _util.FormatError("The reference does not point to a /Page dictionary.");
|
529
871
|
}
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
}
|
534
|
-
}, {
|
535
|
-
key: 'numPages',
|
536
|
-
get: function get() {
|
537
|
-
var obj = this.toplevelPagesDict.get('Count');
|
538
|
-
if (!Number.isInteger(obj)) {
|
539
|
-
throw new _util.FormatError('Page count in top-level pages dictionary is not an integer.');
|
540
|
-
}
|
541
|
-
return (0, _util.shadow)(this, 'numPages', obj);
|
542
|
-
}
|
543
|
-
}, {
|
544
|
-
key: 'destinations',
|
545
|
-
get: function get() {
|
546
|
-
var obj = this._readDests(),
|
547
|
-
dests = Object.create(null);
|
548
|
-
if (obj instanceof NameTree) {
|
549
|
-
var names = obj.getAll();
|
550
|
-
for (var name in names) {
|
551
|
-
dests[name] = fetchDestination(names[name]);
|
552
|
-
}
|
553
|
-
} else if (obj instanceof _primitives.Dict) {
|
554
|
-
obj.forEach(function (key, value) {
|
555
|
-
if (value) {
|
556
|
-
dests[key] = fetchDestination(value);
|
557
|
-
}
|
558
|
-
});
|
559
|
-
}
|
560
|
-
return (0, _util.shadow)(this, 'destinations', dests);
|
561
|
-
}
|
562
|
-
}, {
|
563
|
-
key: 'pageLabels',
|
564
|
-
get: function get() {
|
565
|
-
var obj = null;
|
566
|
-
try {
|
567
|
-
obj = this._readPageLabels();
|
568
|
-
} catch (ex) {
|
569
|
-
if (ex instanceof _util.MissingDataException) {
|
570
|
-
throw ex;
|
872
|
+
|
873
|
+
if (!node) {
|
874
|
+
return null;
|
571
875
|
}
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
}
|
576
|
-
}, {
|
577
|
-
key: 'pageMode',
|
578
|
-
get: function get() {
|
579
|
-
var obj = this.catDict.get('PageMode');
|
580
|
-
var pageMode = 'UseNone';
|
581
|
-
if ((0, _primitives.isName)(obj)) {
|
582
|
-
switch (obj.name) {
|
583
|
-
case 'UseNone':
|
584
|
-
case 'UseOutlines':
|
585
|
-
case 'UseThumbs':
|
586
|
-
case 'FullScreen':
|
587
|
-
case 'UseOC':
|
588
|
-
case 'UseAttachments':
|
589
|
-
pageMode = obj.name;
|
590
|
-
}
|
591
|
-
}
|
592
|
-
return (0, _util.shadow)(this, 'pageMode', pageMode);
|
593
|
-
}
|
594
|
-
}, {
|
595
|
-
key: 'attachments',
|
596
|
-
get: function get() {
|
597
|
-
var obj = this.catDict.get('Names');
|
598
|
-
var attachments = null;
|
599
|
-
if (obj && obj.has('EmbeddedFiles')) {
|
600
|
-
var nameTree = new NameTree(obj.getRaw('EmbeddedFiles'), this.xref);
|
601
|
-
var names = nameTree.getAll();
|
602
|
-
for (var name in names) {
|
603
|
-
var fs = new FileSpec(names[name], this.xref);
|
604
|
-
if (!attachments) {
|
605
|
-
attachments = Object.create(null);
|
606
|
-
}
|
607
|
-
attachments[(0, _util.stringToPDFString)(name)] = fs.serializable;
|
876
|
+
|
877
|
+
if (!(0, _primitives.isDict)(node)) {
|
878
|
+
throw new _util.FormatError("Node must be a dictionary.");
|
608
879
|
}
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
var obj = this.catDict.get('Names');
|
616
|
-
var javaScript = null;
|
617
|
-
function appendIfJavaScriptDict(jsDict) {
|
618
|
-
var type = jsDict.get('S');
|
619
|
-
if (!(0, _primitives.isName)(type, 'JavaScript')) {
|
620
|
-
return;
|
880
|
+
|
881
|
+
parentRef = node.getRaw("Parent");
|
882
|
+
return node.getAsync("Parent");
|
883
|
+
}).then(function (parent) {
|
884
|
+
if (!parent) {
|
885
|
+
return null;
|
621
886
|
}
|
622
|
-
|
623
|
-
if ((0, _primitives.
|
624
|
-
|
625
|
-
} else if (!(0, _util.isString)(js)) {
|
626
|
-
return;
|
887
|
+
|
888
|
+
if (!(0, _primitives.isDict)(parent)) {
|
889
|
+
throw new _util.FormatError("Parent must be a dictionary.");
|
627
890
|
}
|
628
|
-
|
629
|
-
|
891
|
+
|
892
|
+
return parent.getAsync("Kids");
|
893
|
+
}).then(function (kids) {
|
894
|
+
if (!kids) {
|
895
|
+
return null;
|
630
896
|
}
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
if ((0, _primitives.
|
639
|
-
|
897
|
+
|
898
|
+
const kidPromises = [];
|
899
|
+
let found = false;
|
900
|
+
|
901
|
+
for (let i = 0, ii = kids.length; i < ii; i++) {
|
902
|
+
const kid = kids[i];
|
903
|
+
|
904
|
+
if (!(0, _primitives.isRef)(kid)) {
|
905
|
+
throw new _util.FormatError("Kid must be a reference.");
|
640
906
|
}
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
var actionType = openActionDict.get('S');
|
646
|
-
if ((0, _primitives.isName)(actionType, 'Named')) {
|
647
|
-
var action = openActionDict.get('N');
|
648
|
-
if ((0, _primitives.isName)(action, 'Print')) {
|
649
|
-
if (!javaScript) {
|
650
|
-
javaScript = [];
|
651
|
-
}
|
652
|
-
javaScript.push('print({});');
|
907
|
+
|
908
|
+
if ((0, _primitives.isRefsEqual)(kid, kidRef)) {
|
909
|
+
found = true;
|
910
|
+
break;
|
653
911
|
}
|
654
|
-
|
655
|
-
|
912
|
+
|
913
|
+
kidPromises.push(xref.fetchAsync(kid).then(function (kid) {
|
914
|
+
if (!(0, _primitives.isDict)(kid)) {
|
915
|
+
throw new _util.FormatError("Kid node must be a dictionary.");
|
916
|
+
}
|
917
|
+
|
918
|
+
if (kid.has("Count")) {
|
919
|
+
total += kid.get("Count");
|
920
|
+
} else {
|
921
|
+
total++;
|
922
|
+
}
|
923
|
+
}));
|
656
924
|
}
|
657
|
-
|
658
|
-
|
925
|
+
|
926
|
+
if (!found) {
|
927
|
+
throw new _util.FormatError("Kid reference not found in parent's kids.");
|
928
|
+
}
|
929
|
+
|
930
|
+
return Promise.all(kidPromises).then(function () {
|
931
|
+
return [total, parentRef];
|
932
|
+
});
|
933
|
+
});
|
659
934
|
}
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
935
|
+
|
936
|
+
let total = 0;
|
937
|
+
|
938
|
+
function next(ref) {
|
939
|
+
return pagesBeforeRef(ref).then(function (args) {
|
940
|
+
if (!args) {
|
941
|
+
return total;
|
666
942
|
}
|
943
|
+
|
944
|
+
const [count, parentRef] = args;
|
945
|
+
total += count;
|
946
|
+
return next(parentRef);
|
947
|
+
});
|
948
|
+
}
|
949
|
+
|
950
|
+
return next(pageRef);
|
951
|
+
}
|
952
|
+
|
953
|
+
static parseDestDictionary(params) {
|
954
|
+
function addDefaultProtocolToUrl(url) {
|
955
|
+
return url.startsWith("www.") ? `http://${url}` : url;
|
956
|
+
}
|
957
|
+
|
958
|
+
function tryConvertUrlEncoding(url) {
|
959
|
+
try {
|
960
|
+
return (0, _util.stringToUTF8String)(url);
|
961
|
+
} catch (e) {
|
667
962
|
return url;
|
668
963
|
}
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
964
|
+
}
|
965
|
+
|
966
|
+
const destDict = params.destDict;
|
967
|
+
|
968
|
+
if (!(0, _primitives.isDict)(destDict)) {
|
969
|
+
(0, _util.warn)("parseDestDictionary: `destDict` must be a dictionary.");
|
970
|
+
return;
|
971
|
+
}
|
972
|
+
|
973
|
+
const resultObj = params.resultObj;
|
974
|
+
|
975
|
+
if (typeof resultObj !== "object") {
|
976
|
+
(0, _util.warn)("parseDestDictionary: `resultObj` must be an object.");
|
977
|
+
return;
|
978
|
+
}
|
979
|
+
|
980
|
+
const docBaseUrl = params.docBaseUrl || null;
|
981
|
+
let action = destDict.get("A"),
|
982
|
+
url,
|
983
|
+
dest;
|
984
|
+
|
985
|
+
if (!(0, _primitives.isDict)(action) && destDict.has("Dest")) {
|
986
|
+
action = destDict.get("Dest");
|
987
|
+
}
|
988
|
+
|
989
|
+
if ((0, _primitives.isDict)(action)) {
|
990
|
+
const actionType = action.get("S");
|
991
|
+
|
992
|
+
if (!(0, _primitives.isName)(actionType)) {
|
993
|
+
(0, _util.warn)("parseDestDictionary: Invalid type in Action dictionary.");
|
684
994
|
return;
|
685
995
|
}
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
996
|
+
|
997
|
+
const actionName = actionType.name;
|
998
|
+
|
999
|
+
switch (actionName) {
|
1000
|
+
case "URI":
|
1001
|
+
url = action.get("URI");
|
1002
|
+
|
1003
|
+
if ((0, _primitives.isName)(url)) {
|
1004
|
+
url = "/" + url.name;
|
1005
|
+
} else if ((0, _util.isString)(url)) {
|
1006
|
+
url = addDefaultProtocolToUrl(url);
|
1007
|
+
}
|
1008
|
+
|
1009
|
+
break;
|
1010
|
+
|
1011
|
+
case "GoTo":
|
1012
|
+
dest = action.get("D");
|
1013
|
+
break;
|
1014
|
+
|
1015
|
+
case "Launch":
|
1016
|
+
case "GoToR":
|
1017
|
+
const urlDict = action.get("F");
|
1018
|
+
|
1019
|
+
if ((0, _primitives.isDict)(urlDict)) {
|
1020
|
+
url = urlDict.get("F") || null;
|
1021
|
+
} else if ((0, _util.isString)(urlDict)) {
|
1022
|
+
url = urlDict;
|
1023
|
+
}
|
1024
|
+
|
1025
|
+
let remoteDest = action.get("D");
|
1026
|
+
|
1027
|
+
if (remoteDest) {
|
1028
|
+
if ((0, _primitives.isName)(remoteDest)) {
|
1029
|
+
remoteDest = remoteDest.name;
|
719
1030
|
}
|
720
|
-
|
721
|
-
if (
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
url = baseUrl + '#' + remoteDest;
|
729
|
-
} else if (Array.isArray(remoteDest)) {
|
730
|
-
url = baseUrl + '#' + JSON.stringify(remoteDest);
|
731
|
-
}
|
1031
|
+
|
1032
|
+
if ((0, _util.isString)(url)) {
|
1033
|
+
const baseUrl = url.split("#")[0];
|
1034
|
+
|
1035
|
+
if ((0, _util.isString)(remoteDest)) {
|
1036
|
+
url = baseUrl + "#" + remoteDest;
|
1037
|
+
} else if (Array.isArray(remoteDest)) {
|
1038
|
+
url = baseUrl + "#" + JSON.stringify(remoteDest);
|
732
1039
|
}
|
733
1040
|
}
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
1041
|
+
}
|
1042
|
+
|
1043
|
+
const newWindow = action.get("NewWindow");
|
1044
|
+
|
1045
|
+
if ((0, _util.isBool)(newWindow)) {
|
1046
|
+
resultObj.newWindow = newWindow;
|
1047
|
+
}
|
1048
|
+
|
1049
|
+
break;
|
1050
|
+
|
1051
|
+
case "Named":
|
1052
|
+
const namedAction = action.get("N");
|
1053
|
+
|
1054
|
+
if ((0, _primitives.isName)(namedAction)) {
|
1055
|
+
resultObj.action = namedAction.name;
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
break;
|
1059
|
+
|
1060
|
+
case "JavaScript":
|
1061
|
+
const jsAction = action.get("JS");
|
1062
|
+
let js;
|
1063
|
+
|
1064
|
+
if ((0, _primitives.isStream)(jsAction)) {
|
1065
|
+
js = (0, _util.bytesToString)(jsAction.getBytes());
|
1066
|
+
} else if ((0, _util.isString)(jsAction)) {
|
1067
|
+
js = jsAction;
|
1068
|
+
}
|
1069
|
+
|
1070
|
+
if (js) {
|
1071
|
+
const URL_OPEN_METHODS = ["app.launchURL", "window.open"];
|
1072
|
+
const regex = new RegExp("^\\s*(" + URL_OPEN_METHODS.join("|").split(".").join("\\.") + ")\\((?:'|\")([^'\"]*)(?:'|\")(?:,\\s*(\\w+)\\)|\\))", "i");
|
1073
|
+
const jsUrl = regex.exec((0, _util.stringToPDFString)(js));
|
1074
|
+
|
1075
|
+
if (jsUrl && jsUrl[2]) {
|
1076
|
+
url = jsUrl[2];
|
1077
|
+
|
1078
|
+
if (jsUrl[3] === "true" && jsUrl[1] === "app.launchURL") {
|
1079
|
+
resultObj.newWindow = true;
|
763
1080
|
}
|
1081
|
+
|
1082
|
+
break;
|
764
1083
|
}
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
dest = destDict.get('Dest');
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
default:
|
1087
|
+
(0, _util.warn)(`parseDestDictionary: unsupported action type "${actionName}".`);
|
1088
|
+
break;
|
771
1089
|
}
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
1090
|
+
} else if (destDict.has("Dest")) {
|
1091
|
+
dest = destDict.get("Dest");
|
1092
|
+
}
|
1093
|
+
|
1094
|
+
if ((0, _util.isString)(url)) {
|
1095
|
+
url = tryConvertUrlEncoding(url);
|
1096
|
+
const absoluteUrl = (0, _util.createValidAbsoluteUrl)(url, docBaseUrl);
|
1097
|
+
|
1098
|
+
if (absoluteUrl) {
|
1099
|
+
resultObj.url = absoluteUrl.href;
|
779
1100
|
}
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
1101
|
+
|
1102
|
+
resultObj.unsafeUrl = url;
|
1103
|
+
}
|
1104
|
+
|
1105
|
+
if (dest) {
|
1106
|
+
if ((0, _primitives.isName)(dest)) {
|
1107
|
+
dest = dest.name;
|
1108
|
+
}
|
1109
|
+
|
1110
|
+
if ((0, _util.isString)(dest) || Array.isArray(dest)) {
|
1111
|
+
resultObj.dest = dest;
|
787
1112
|
}
|
788
1113
|
}
|
789
|
-
}
|
1114
|
+
}
|
790
1115
|
|
791
|
-
|
792
|
-
|
1116
|
+
}
|
1117
|
+
|
1118
|
+
exports.Catalog = Catalog;
|
793
1119
|
|
794
1120
|
var XRef = function XRefClosure() {
|
795
1121
|
function XRef(stream, pdfManager) {
|
@@ -797,61 +1123,72 @@ var XRef = function XRefClosure() {
|
|
797
1123
|
this.pdfManager = pdfManager;
|
798
1124
|
this.entries = [];
|
799
1125
|
this.xrefstms = Object.create(null);
|
800
|
-
this.
|
1126
|
+
this._cacheMap = new Map();
|
801
1127
|
this.stats = {
|
802
|
-
streamTypes:
|
803
|
-
fontTypes:
|
1128
|
+
streamTypes: Object.create(null),
|
1129
|
+
fontTypes: Object.create(null)
|
804
1130
|
};
|
805
1131
|
}
|
1132
|
+
|
806
1133
|
XRef.prototype = {
|
807
1134
|
setStartXRef: function XRef_setStartXRef(startXRef) {
|
808
1135
|
this.startXRefQueue = [startXRef];
|
809
1136
|
},
|
810
1137
|
parse: function XRef_parse(recoveryMode) {
|
811
1138
|
var trailerDict;
|
1139
|
+
|
812
1140
|
if (!recoveryMode) {
|
813
1141
|
trailerDict = this.readXRef();
|
814
1142
|
} else {
|
815
|
-
(0, _util.warn)(
|
1143
|
+
(0, _util.warn)("Indexing all PDF objects");
|
816
1144
|
trailerDict = this.indexObjects();
|
817
1145
|
}
|
1146
|
+
|
818
1147
|
trailerDict.assignXref(this);
|
819
1148
|
this.trailer = trailerDict;
|
820
|
-
|
1149
|
+
let encrypt;
|
1150
|
+
|
821
1151
|
try {
|
822
|
-
encrypt = trailerDict.get(
|
1152
|
+
encrypt = trailerDict.get("Encrypt");
|
823
1153
|
} catch (ex) {
|
824
|
-
if (ex instanceof
|
1154
|
+
if (ex instanceof _core_utils.MissingDataException) {
|
825
1155
|
throw ex;
|
826
1156
|
}
|
827
|
-
|
1157
|
+
|
1158
|
+
(0, _util.warn)(`XRef.parse - Invalid "Encrypt" reference: "${ex}".`);
|
828
1159
|
}
|
1160
|
+
|
829
1161
|
if ((0, _primitives.isDict)(encrypt)) {
|
830
|
-
var ids = trailerDict.get(
|
831
|
-
var fileId = ids && ids.length ? ids[0] :
|
1162
|
+
var ids = trailerDict.get("ID");
|
1163
|
+
var fileId = ids && ids.length ? ids[0] : "";
|
832
1164
|
encrypt.suppressEncryption = true;
|
833
1165
|
this.encrypt = new _crypto.CipherTransformFactory(encrypt, fileId, this.pdfManager.password);
|
834
1166
|
}
|
835
|
-
|
1167
|
+
|
1168
|
+
let root;
|
1169
|
+
|
836
1170
|
try {
|
837
|
-
root = trailerDict.get(
|
1171
|
+
root = trailerDict.get("Root");
|
838
1172
|
} catch (ex) {
|
839
|
-
if (ex instanceof
|
1173
|
+
if (ex instanceof _core_utils.MissingDataException) {
|
840
1174
|
throw ex;
|
841
1175
|
}
|
842
|
-
|
1176
|
+
|
1177
|
+
(0, _util.warn)(`XRef.parse - Invalid "Root" reference: "${ex}".`);
|
843
1178
|
}
|
844
|
-
|
1179
|
+
|
1180
|
+
if ((0, _primitives.isDict)(root) && root.has("Pages")) {
|
845
1181
|
this.root = root;
|
846
1182
|
} else {
|
847
1183
|
if (!recoveryMode) {
|
848
|
-
throw new
|
1184
|
+
throw new _core_utils.XRefParseException();
|
849
1185
|
}
|
850
|
-
|
1186
|
+
|
1187
|
+
throw new _util.FormatError("Invalid root reference");
|
851
1188
|
}
|
852
1189
|
},
|
853
1190
|
processXRefTable: function XRef_processXRefTable(parser) {
|
854
|
-
if (!(
|
1191
|
+
if (!("tableState" in this)) {
|
855
1192
|
this.tableState = {
|
856
1193
|
entryNum: 0,
|
857
1194
|
streamPos: parser.lexer.stream.pos,
|
@@ -859,17 +1196,23 @@ var XRef = function XRefClosure() {
|
|
859
1196
|
parserBuf2: parser.buf2
|
860
1197
|
};
|
861
1198
|
}
|
1199
|
+
|
862
1200
|
var obj = this.readXRefTable(parser);
|
863
|
-
|
864
|
-
|
1201
|
+
|
1202
|
+
if (!(0, _primitives.isCmd)(obj, "trailer")) {
|
1203
|
+
throw new _util.FormatError("Invalid XRef table: could not find trailer dictionary");
|
865
1204
|
}
|
1205
|
+
|
866
1206
|
var dict = parser.getObj();
|
1207
|
+
|
867
1208
|
if (!(0, _primitives.isDict)(dict) && dict.dict) {
|
868
1209
|
dict = dict.dict;
|
869
1210
|
}
|
1211
|
+
|
870
1212
|
if (!(0, _primitives.isDict)(dict)) {
|
871
|
-
throw new _util.FormatError(
|
1213
|
+
throw new _util.FormatError("Invalid XRef table: could not parse trailer dictionary");
|
872
1214
|
}
|
1215
|
+
|
873
1216
|
delete this.tableState;
|
874
1217
|
return dict;
|
875
1218
|
},
|
@@ -880,19 +1223,24 @@ var XRef = function XRefClosure() {
|
|
880
1223
|
parser.buf1 = tableState.parserBuf1;
|
881
1224
|
parser.buf2 = tableState.parserBuf2;
|
882
1225
|
var obj;
|
1226
|
+
|
883
1227
|
while (true) {
|
884
|
-
if (!(
|
885
|
-
if ((0, _primitives.isCmd)(obj = parser.getObj(),
|
1228
|
+
if (!("firstEntryNum" in tableState) || !("entryCount" in tableState)) {
|
1229
|
+
if ((0, _primitives.isCmd)(obj = parser.getObj(), "trailer")) {
|
886
1230
|
break;
|
887
1231
|
}
|
1232
|
+
|
888
1233
|
tableState.firstEntryNum = obj;
|
889
1234
|
tableState.entryCount = parser.getObj();
|
890
1235
|
}
|
1236
|
+
|
891
1237
|
var first = tableState.firstEntryNum;
|
892
1238
|
var count = tableState.entryCount;
|
1239
|
+
|
893
1240
|
if (!Number.isInteger(first) || !Number.isInteger(count)) {
|
894
|
-
throw new _util.FormatError(
|
1241
|
+
throw new _util.FormatError("Invalid XRef table: wrong types in subsection header");
|
895
1242
|
}
|
1243
|
+
|
896
1244
|
for (var i = tableState.entryNum; i < count; i++) {
|
897
1245
|
tableState.streamPos = stream.pos;
|
898
1246
|
tableState.entryNum = i;
|
@@ -902,21 +1250,32 @@ var XRef = function XRefClosure() {
|
|
902
1250
|
entry.offset = parser.getObj();
|
903
1251
|
entry.gen = parser.getObj();
|
904
1252
|
var type = parser.getObj();
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
1253
|
+
|
1254
|
+
if (type instanceof _primitives.Cmd) {
|
1255
|
+
switch (type.cmd) {
|
1256
|
+
case "f":
|
1257
|
+
entry.free = true;
|
1258
|
+
break;
|
1259
|
+
|
1260
|
+
case "n":
|
1261
|
+
entry.uncompressed = true;
|
1262
|
+
break;
|
1263
|
+
}
|
909
1264
|
}
|
1265
|
+
|
910
1266
|
if (!Number.isInteger(entry.offset) || !Number.isInteger(entry.gen) || !(entry.free || entry.uncompressed)) {
|
911
|
-
throw new _util.FormatError(
|
1267
|
+
throw new _util.FormatError(`Invalid entry in XRef subsection: ${first}, ${count}`);
|
912
1268
|
}
|
1269
|
+
|
913
1270
|
if (i === 0 && entry.free && first === 1) {
|
914
1271
|
first = 0;
|
915
1272
|
}
|
1273
|
+
|
916
1274
|
if (!this.entries[i + first]) {
|
917
1275
|
this.entries[i + first] = entry;
|
918
1276
|
}
|
919
1277
|
}
|
1278
|
+
|
920
1279
|
tableState.entryNum = 0;
|
921
1280
|
tableState.streamPos = stream.pos;
|
922
1281
|
tableState.parserBuf1 = parser.buf1;
|
@@ -924,26 +1283,31 @@ var XRef = function XRefClosure() {
|
|
924
1283
|
delete tableState.firstEntryNum;
|
925
1284
|
delete tableState.entryCount;
|
926
1285
|
}
|
1286
|
+
|
927
1287
|
if (this.entries[0] && !this.entries[0].free) {
|
928
|
-
throw new _util.FormatError(
|
1288
|
+
throw new _util.FormatError("Invalid XRef table: unexpected first object");
|
929
1289
|
}
|
1290
|
+
|
930
1291
|
return obj;
|
931
1292
|
},
|
932
1293
|
processXRefStream: function XRef_processXRefStream(stream) {
|
933
|
-
if (!(
|
1294
|
+
if (!("streamState" in this)) {
|
934
1295
|
var streamParameters = stream.dict;
|
935
|
-
var byteWidths = streamParameters.get(
|
936
|
-
var range = streamParameters.get(
|
1296
|
+
var byteWidths = streamParameters.get("W");
|
1297
|
+
var range = streamParameters.get("Index");
|
1298
|
+
|
937
1299
|
if (!range) {
|
938
|
-
range = [0, streamParameters.get(
|
1300
|
+
range = [0, streamParameters.get("Size")];
|
939
1301
|
}
|
1302
|
+
|
940
1303
|
this.streamState = {
|
941
1304
|
entryRanges: range,
|
942
|
-
byteWidths
|
1305
|
+
byteWidths,
|
943
1306
|
entryNum: 0,
|
944
1307
|
streamPos: stream.pos
|
945
1308
|
};
|
946
1309
|
}
|
1310
|
+
|
947
1311
|
this.readXRefStream(stream);
|
948
1312
|
delete this.streamState;
|
949
1313
|
return stream.dict;
|
@@ -957,52 +1321,67 @@ var XRef = function XRefClosure() {
|
|
957
1321
|
var offsetFieldWidth = byteWidths[1];
|
958
1322
|
var generationFieldWidth = byteWidths[2];
|
959
1323
|
var entryRanges = streamState.entryRanges;
|
1324
|
+
|
960
1325
|
while (entryRanges.length > 0) {
|
961
1326
|
var first = entryRanges[0];
|
962
1327
|
var n = entryRanges[1];
|
1328
|
+
|
963
1329
|
if (!Number.isInteger(first) || !Number.isInteger(n)) {
|
964
|
-
throw new _util.FormatError(
|
1330
|
+
throw new _util.FormatError(`Invalid XRef range fields: ${first}, ${n}`);
|
965
1331
|
}
|
1332
|
+
|
966
1333
|
if (!Number.isInteger(typeFieldWidth) || !Number.isInteger(offsetFieldWidth) || !Number.isInteger(generationFieldWidth)) {
|
967
|
-
throw new _util.FormatError(
|
1334
|
+
throw new _util.FormatError(`Invalid XRef entry fields length: ${first}, ${n}`);
|
968
1335
|
}
|
1336
|
+
|
969
1337
|
for (i = streamState.entryNum; i < n; ++i) {
|
970
1338
|
streamState.entryNum = i;
|
971
1339
|
streamState.streamPos = stream.pos;
|
972
1340
|
var type = 0,
|
973
1341
|
offset = 0,
|
974
1342
|
generation = 0;
|
1343
|
+
|
975
1344
|
for (j = 0; j < typeFieldWidth; ++j) {
|
976
1345
|
type = type << 8 | stream.getByte();
|
977
1346
|
}
|
1347
|
+
|
978
1348
|
if (typeFieldWidth === 0) {
|
979
1349
|
type = 1;
|
980
1350
|
}
|
1351
|
+
|
981
1352
|
for (j = 0; j < offsetFieldWidth; ++j) {
|
982
1353
|
offset = offset << 8 | stream.getByte();
|
983
1354
|
}
|
1355
|
+
|
984
1356
|
for (j = 0; j < generationFieldWidth; ++j) {
|
985
1357
|
generation = generation << 8 | stream.getByte();
|
986
1358
|
}
|
1359
|
+
|
987
1360
|
var entry = {};
|
988
1361
|
entry.offset = offset;
|
989
1362
|
entry.gen = generation;
|
1363
|
+
|
990
1364
|
switch (type) {
|
991
1365
|
case 0:
|
992
1366
|
entry.free = true;
|
993
1367
|
break;
|
1368
|
+
|
994
1369
|
case 1:
|
995
1370
|
entry.uncompressed = true;
|
996
1371
|
break;
|
1372
|
+
|
997
1373
|
case 2:
|
998
1374
|
break;
|
1375
|
+
|
999
1376
|
default:
|
1000
|
-
throw new _util.FormatError(
|
1377
|
+
throw new _util.FormatError(`Invalid XRef entry type: ${type}`);
|
1001
1378
|
}
|
1379
|
+
|
1002
1380
|
if (!this.entries[first + i]) {
|
1003
1381
|
this.entries[first + i] = entry;
|
1004
1382
|
}
|
1005
1383
|
}
|
1384
|
+
|
1006
1385
|
streamState.entryNum = 0;
|
1007
1386
|
streamState.streamPos = stream.pos;
|
1008
1387
|
entryRanges.splice(0, 2);
|
@@ -1010,47 +1389,58 @@ var XRef = function XRefClosure() {
|
|
1010
1389
|
},
|
1011
1390
|
indexObjects: function XRef_indexObjects() {
|
1012
1391
|
var TAB = 0x9,
|
1013
|
-
LF =
|
1014
|
-
CR =
|
1392
|
+
LF = 0xa,
|
1393
|
+
CR = 0xd,
|
1015
1394
|
SPACE = 0x20;
|
1016
1395
|
var PERCENT = 0x25,
|
1017
|
-
LT =
|
1396
|
+
LT = 0x3c;
|
1397
|
+
|
1018
1398
|
function readToken(data, offset) {
|
1019
|
-
var token =
|
1399
|
+
var token = "",
|
1020
1400
|
ch = data[offset];
|
1401
|
+
|
1021
1402
|
while (ch !== LF && ch !== CR && ch !== LT) {
|
1022
1403
|
if (++offset >= data.length) {
|
1023
1404
|
break;
|
1024
1405
|
}
|
1406
|
+
|
1025
1407
|
token += String.fromCharCode(ch);
|
1026
1408
|
ch = data[offset];
|
1027
1409
|
}
|
1410
|
+
|
1028
1411
|
return token;
|
1029
1412
|
}
|
1413
|
+
|
1030
1414
|
function skipUntil(data, offset, what) {
|
1031
1415
|
var length = what.length,
|
1032
1416
|
dataLength = data.length;
|
1033
1417
|
var skipped = 0;
|
1418
|
+
|
1034
1419
|
while (offset < dataLength) {
|
1035
1420
|
var i = 0;
|
1421
|
+
|
1036
1422
|
while (i < length && data[offset + i] === what[i]) {
|
1037
1423
|
++i;
|
1038
1424
|
}
|
1425
|
+
|
1039
1426
|
if (i >= length) {
|
1040
1427
|
break;
|
1041
1428
|
}
|
1429
|
+
|
1042
1430
|
offset++;
|
1043
1431
|
skipped++;
|
1044
1432
|
}
|
1433
|
+
|
1045
1434
|
return skipped;
|
1046
1435
|
}
|
1436
|
+
|
1047
1437
|
var objRegExp = /^(\d+)\s+(\d+)\s+obj\b/;
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1438
|
+
const endobjRegExp = /\bendobj[\b\s]$/;
|
1439
|
+
const nestedObjRegExp = /\s+(\d+\s+\d+\s+obj[\b\s<])$/;
|
1440
|
+
const CHECK_CONTENT_LENGTH = 25;
|
1051
1441
|
var trailerBytes = new Uint8Array([116, 114, 97, 105, 108, 101, 114]);
|
1052
1442
|
var startxrefBytes = new Uint8Array([115, 116, 97, 114, 116, 120, 114, 101, 102]);
|
1053
|
-
|
1443
|
+
const objBytes = new Uint8Array([111, 98, 106]);
|
1054
1444
|
var xrefBytes = new Uint8Array([47, 88, 82, 101, 102]);
|
1055
1445
|
this.entries.length = 0;
|
1056
1446
|
var stream = this.stream;
|
@@ -1060,367 +1450,424 @@ var XRef = function XRefClosure() {
|
|
1060
1450
|
length = buffer.length;
|
1061
1451
|
var trailers = [],
|
1062
1452
|
xrefStms = [];
|
1453
|
+
|
1063
1454
|
while (position < length) {
|
1064
1455
|
var ch = buffer[position];
|
1456
|
+
|
1065
1457
|
if (ch === TAB || ch === LF || ch === CR || ch === SPACE) {
|
1066
1458
|
++position;
|
1067
1459
|
continue;
|
1068
1460
|
}
|
1461
|
+
|
1069
1462
|
if (ch === PERCENT) {
|
1070
1463
|
do {
|
1071
1464
|
++position;
|
1465
|
+
|
1072
1466
|
if (position >= length) {
|
1073
1467
|
break;
|
1074
1468
|
}
|
1469
|
+
|
1075
1470
|
ch = buffer[position];
|
1076
1471
|
} while (ch !== LF && ch !== CR);
|
1472
|
+
|
1077
1473
|
continue;
|
1078
1474
|
}
|
1475
|
+
|
1079
1476
|
var token = readToken(buffer, position);
|
1080
1477
|
var m;
|
1081
|
-
|
1478
|
+
|
1479
|
+
if (token.startsWith("xref") && (token.length === 4 || /\s/.test(token[4]))) {
|
1082
1480
|
position += skipUntil(buffer, position, trailerBytes);
|
1083
1481
|
trailers.push(position);
|
1084
1482
|
position += skipUntil(buffer, position, startxrefBytes);
|
1085
1483
|
} else if (m = objRegExp.exec(token)) {
|
1086
|
-
|
1087
|
-
|
1484
|
+
const num = m[1] | 0,
|
1485
|
+
gen = m[2] | 0;
|
1486
|
+
|
1487
|
+
if (!this.entries[num] || this.entries[num].gen === gen) {
|
1488
|
+
this.entries[num] = {
|
1088
1489
|
offset: position - stream.start,
|
1089
|
-
gen
|
1490
|
+
gen,
|
1090
1491
|
uncompressed: true
|
1091
1492
|
};
|
1092
1493
|
}
|
1093
|
-
|
1494
|
+
|
1495
|
+
let contentLength,
|
1094
1496
|
startPos = position + token.length;
|
1497
|
+
|
1095
1498
|
while (startPos < buffer.length) {
|
1096
|
-
|
1499
|
+
const endPos = startPos + skipUntil(buffer, startPos, objBytes) + 4;
|
1097
1500
|
contentLength = endPos - position;
|
1098
|
-
|
1099
|
-
|
1501
|
+
const checkPos = Math.max(endPos - CHECK_CONTENT_LENGTH, startPos);
|
1502
|
+
const tokenStr = (0, _util.bytesToString)(buffer.subarray(checkPos, endPos));
|
1503
|
+
|
1100
1504
|
if (endobjRegExp.test(tokenStr)) {
|
1101
1505
|
break;
|
1102
1506
|
} else {
|
1103
|
-
|
1507
|
+
const objToken = nestedObjRegExp.exec(tokenStr);
|
1508
|
+
|
1104
1509
|
if (objToken && objToken[1]) {
|
1105
1510
|
(0, _util.warn)('indexObjects: Found new "obj" inside of another "obj", ' + 'caused by missing "endobj" -- trying to recover.');
|
1106
1511
|
contentLength -= objToken[1].length;
|
1107
1512
|
break;
|
1108
1513
|
}
|
1109
1514
|
}
|
1515
|
+
|
1110
1516
|
startPos = endPos;
|
1111
1517
|
}
|
1112
|
-
|
1518
|
+
|
1519
|
+
const content = buffer.subarray(position, position + contentLength);
|
1113
1520
|
var xrefTagOffset = skipUntil(content, 0, xrefBytes);
|
1521
|
+
|
1114
1522
|
if (xrefTagOffset < contentLength && content[xrefTagOffset + 5] < 64) {
|
1115
1523
|
xrefStms.push(position - stream.start);
|
1116
1524
|
this.xrefstms[position - stream.start] = 1;
|
1117
1525
|
}
|
1526
|
+
|
1118
1527
|
position += contentLength;
|
1119
|
-
} else if (token.
|
1528
|
+
} else if (token.startsWith("trailer") && (token.length === 7 || /\s/.test(token[7]))) {
|
1120
1529
|
trailers.push(position);
|
1121
1530
|
position += skipUntil(buffer, position, startxrefBytes);
|
1122
1531
|
} else {
|
1123
1532
|
position += token.length + 1;
|
1124
1533
|
}
|
1125
1534
|
}
|
1535
|
+
|
1126
1536
|
var i, ii;
|
1537
|
+
|
1127
1538
|
for (i = 0, ii = xrefStms.length; i < ii; ++i) {
|
1128
1539
|
this.startXRefQueue.push(xrefStms[i]);
|
1129
1540
|
this.readXRef(true);
|
1130
1541
|
}
|
1131
|
-
|
1542
|
+
|
1543
|
+
let trailerDict;
|
1544
|
+
|
1132
1545
|
for (i = 0, ii = trailers.length; i < ii; ++i) {
|
1133
1546
|
stream.pos = trailers[i];
|
1134
|
-
|
1547
|
+
const parser = new _parser.Parser({
|
1548
|
+
lexer: new _parser.Lexer(stream),
|
1549
|
+
xref: this,
|
1550
|
+
allowStreams: true,
|
1551
|
+
recoveryMode: true
|
1552
|
+
});
|
1135
1553
|
var obj = parser.getObj();
|
1136
|
-
|
1554
|
+
|
1555
|
+
if (!(0, _primitives.isCmd)(obj, "trailer")) {
|
1137
1556
|
continue;
|
1138
1557
|
}
|
1139
|
-
|
1558
|
+
|
1559
|
+
const dict = parser.getObj();
|
1560
|
+
|
1140
1561
|
if (!(0, _primitives.isDict)(dict)) {
|
1141
1562
|
continue;
|
1142
1563
|
}
|
1143
|
-
|
1564
|
+
|
1565
|
+
let rootDict;
|
1566
|
+
|
1144
1567
|
try {
|
1145
|
-
rootDict = dict.get(
|
1568
|
+
rootDict = dict.get("Root");
|
1146
1569
|
} catch (ex) {
|
1147
|
-
if (ex instanceof
|
1570
|
+
if (ex instanceof _core_utils.MissingDataException) {
|
1148
1571
|
throw ex;
|
1149
1572
|
}
|
1573
|
+
|
1150
1574
|
continue;
|
1151
1575
|
}
|
1152
|
-
|
1576
|
+
|
1577
|
+
if (!(0, _primitives.isDict)(rootDict) || !rootDict.has("Pages")) {
|
1153
1578
|
continue;
|
1154
1579
|
}
|
1155
|
-
|
1580
|
+
|
1581
|
+
if (dict.has("ID")) {
|
1156
1582
|
return dict;
|
1157
1583
|
}
|
1584
|
+
|
1158
1585
|
trailerDict = dict;
|
1159
1586
|
}
|
1587
|
+
|
1160
1588
|
if (trailerDict) {
|
1161
1589
|
return trailerDict;
|
1162
1590
|
}
|
1163
|
-
|
1591
|
+
|
1592
|
+
throw new _util.InvalidPDFException("Invalid PDF structure.");
|
1164
1593
|
},
|
1165
1594
|
readXRef: function XRef_readXRef(recoveryMode) {
|
1166
1595
|
var stream = this.stream;
|
1167
|
-
|
1596
|
+
const startXRefParsedCache = Object.create(null);
|
1597
|
+
|
1168
1598
|
try {
|
1169
1599
|
while (this.startXRefQueue.length) {
|
1170
1600
|
var startXRef = this.startXRefQueue[0];
|
1601
|
+
|
1171
1602
|
if (startXRefParsedCache[startXRef]) {
|
1172
|
-
(0, _util.warn)(
|
1603
|
+
(0, _util.warn)("readXRef - skipping XRef table since it was already parsed.");
|
1173
1604
|
this.startXRefQueue.shift();
|
1174
1605
|
continue;
|
1175
1606
|
}
|
1607
|
+
|
1176
1608
|
startXRefParsedCache[startXRef] = true;
|
1177
1609
|
stream.pos = startXRef + stream.start;
|
1178
|
-
|
1610
|
+
const parser = new _parser.Parser({
|
1611
|
+
lexer: new _parser.Lexer(stream),
|
1612
|
+
xref: this,
|
1613
|
+
allowStreams: true
|
1614
|
+
});
|
1179
1615
|
var obj = parser.getObj();
|
1180
1616
|
var dict;
|
1181
|
-
|
1617
|
+
|
1618
|
+
if ((0, _primitives.isCmd)(obj, "xref")) {
|
1182
1619
|
dict = this.processXRefTable(parser);
|
1620
|
+
|
1183
1621
|
if (!this.topDict) {
|
1184
1622
|
this.topDict = dict;
|
1185
1623
|
}
|
1186
|
-
|
1624
|
+
|
1625
|
+
obj = dict.get("XRefStm");
|
1626
|
+
|
1187
1627
|
if (Number.isInteger(obj)) {
|
1188
1628
|
var pos = obj;
|
1629
|
+
|
1189
1630
|
if (!(pos in this.xrefstms)) {
|
1190
1631
|
this.xrefstms[pos] = 1;
|
1191
1632
|
this.startXRefQueue.push(pos);
|
1192
1633
|
}
|
1193
1634
|
}
|
1194
1635
|
} else if (Number.isInteger(obj)) {
|
1195
|
-
if (!Number.isInteger(parser.getObj()) || !(0, _primitives.isCmd)(parser.getObj(),
|
1196
|
-
throw new _util.FormatError(
|
1636
|
+
if (!Number.isInteger(parser.getObj()) || !(0, _primitives.isCmd)(parser.getObj(), "obj") || !(0, _primitives.isStream)(obj = parser.getObj())) {
|
1637
|
+
throw new _util.FormatError("Invalid XRef stream");
|
1197
1638
|
}
|
1639
|
+
|
1198
1640
|
dict = this.processXRefStream(obj);
|
1641
|
+
|
1199
1642
|
if (!this.topDict) {
|
1200
1643
|
this.topDict = dict;
|
1201
1644
|
}
|
1645
|
+
|
1202
1646
|
if (!dict) {
|
1203
|
-
throw new _util.FormatError(
|
1647
|
+
throw new _util.FormatError("Failed to read XRef stream");
|
1204
1648
|
}
|
1205
1649
|
} else {
|
1206
|
-
throw new _util.FormatError(
|
1650
|
+
throw new _util.FormatError("Invalid XRef stream header");
|
1207
1651
|
}
|
1208
|
-
|
1652
|
+
|
1653
|
+
obj = dict.get("Prev");
|
1654
|
+
|
1209
1655
|
if (Number.isInteger(obj)) {
|
1210
1656
|
this.startXRefQueue.push(obj);
|
1211
1657
|
} else if ((0, _primitives.isRef)(obj)) {
|
1212
1658
|
this.startXRefQueue.push(obj.num);
|
1213
1659
|
}
|
1660
|
+
|
1214
1661
|
this.startXRefQueue.shift();
|
1215
1662
|
}
|
1663
|
+
|
1216
1664
|
return this.topDict;
|
1217
1665
|
} catch (e) {
|
1218
|
-
if (e instanceof
|
1666
|
+
if (e instanceof _core_utils.MissingDataException) {
|
1219
1667
|
throw e;
|
1220
1668
|
}
|
1221
|
-
|
1669
|
+
|
1670
|
+
(0, _util.info)("(while reading XRef): " + e);
|
1222
1671
|
}
|
1672
|
+
|
1223
1673
|
if (recoveryMode) {
|
1224
|
-
return;
|
1674
|
+
return undefined;
|
1225
1675
|
}
|
1226
|
-
|
1676
|
+
|
1677
|
+
throw new _core_utils.XRefParseException();
|
1227
1678
|
},
|
1228
1679
|
getEntry: function XRef_getEntry(i) {
|
1229
1680
|
var xrefEntry = this.entries[i];
|
1681
|
+
|
1230
1682
|
if (xrefEntry && !xrefEntry.free && xrefEntry.offset) {
|
1231
1683
|
return xrefEntry;
|
1232
1684
|
}
|
1685
|
+
|
1233
1686
|
return null;
|
1234
1687
|
},
|
1235
1688
|
fetchIfRef: function XRef_fetchIfRef(obj, suppressEncryption) {
|
1236
|
-
if (
|
1237
|
-
return obj;
|
1689
|
+
if (obj instanceof _primitives.Ref) {
|
1690
|
+
return this.fetch(obj, suppressEncryption);
|
1238
1691
|
}
|
1239
|
-
|
1692
|
+
|
1693
|
+
return obj;
|
1240
1694
|
},
|
1241
1695
|
fetch: function XRef_fetch(ref, suppressEncryption) {
|
1242
|
-
if (!(
|
1243
|
-
throw new Error(
|
1696
|
+
if (!(ref instanceof _primitives.Ref)) {
|
1697
|
+
throw new Error("ref object is not a reference");
|
1244
1698
|
}
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1699
|
+
|
1700
|
+
const num = ref.num;
|
1701
|
+
|
1702
|
+
const cacheEntry = this._cacheMap.get(num);
|
1703
|
+
|
1704
|
+
if (cacheEntry !== undefined) {
|
1248
1705
|
if (cacheEntry instanceof _primitives.Dict && !cacheEntry.objId) {
|
1249
1706
|
cacheEntry.objId = ref.toString();
|
1250
1707
|
}
|
1708
|
+
|
1251
1709
|
return cacheEntry;
|
1252
1710
|
}
|
1253
|
-
|
1711
|
+
|
1712
|
+
let xrefEntry = this.getEntry(num);
|
1713
|
+
|
1254
1714
|
if (xrefEntry === null) {
|
1255
|
-
|
1715
|
+
this._cacheMap.set(num, xrefEntry);
|
1716
|
+
|
1717
|
+
return xrefEntry;
|
1256
1718
|
}
|
1719
|
+
|
1257
1720
|
if (xrefEntry.uncompressed) {
|
1258
1721
|
xrefEntry = this.fetchUncompressed(ref, xrefEntry, suppressEncryption);
|
1259
1722
|
} else {
|
1260
|
-
xrefEntry = this.fetchCompressed(xrefEntry, suppressEncryption);
|
1723
|
+
xrefEntry = this.fetchCompressed(ref, xrefEntry, suppressEncryption);
|
1261
1724
|
}
|
1725
|
+
|
1262
1726
|
if ((0, _primitives.isDict)(xrefEntry)) {
|
1263
1727
|
xrefEntry.objId = ref.toString();
|
1264
1728
|
} else if ((0, _primitives.isStream)(xrefEntry)) {
|
1265
1729
|
xrefEntry.dict.objId = ref.toString();
|
1266
1730
|
}
|
1731
|
+
|
1267
1732
|
return xrefEntry;
|
1268
1733
|
},
|
1269
|
-
|
1734
|
+
|
1735
|
+
fetchUncompressed(ref, xrefEntry, suppressEncryption = false) {
|
1270
1736
|
var gen = ref.gen;
|
1271
1737
|
var num = ref.num;
|
1738
|
+
|
1272
1739
|
if (xrefEntry.gen !== gen) {
|
1273
|
-
throw new
|
1740
|
+
throw new _core_utils.XRefEntryException(`Inconsistent generation in XRef: ${ref}`);
|
1274
1741
|
}
|
1742
|
+
|
1275
1743
|
var stream = this.stream.makeSubStream(xrefEntry.offset + this.stream.start);
|
1276
|
-
|
1744
|
+
const parser = new _parser.Parser({
|
1745
|
+
lexer: new _parser.Lexer(stream),
|
1746
|
+
xref: this,
|
1747
|
+
allowStreams: true
|
1748
|
+
});
|
1277
1749
|
var obj1 = parser.getObj();
|
1278
1750
|
var obj2 = parser.getObj();
|
1279
1751
|
var obj3 = parser.getObj();
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
if (!Number.isInteger(obj2)) {
|
1284
|
-
obj2 = parseInt(obj2, 10);
|
1285
|
-
}
|
1286
|
-
if (obj1 !== num || obj2 !== gen || !(0, _primitives.isCmd)(obj3)) {
|
1287
|
-
throw new _util.FormatError('bad XRef entry');
|
1752
|
+
|
1753
|
+
if (obj1 !== num || obj2 !== gen || !(obj3 instanceof _primitives.Cmd)) {
|
1754
|
+
throw new _core_utils.XRefEntryException(`Bad (uncompressed) XRef entry: ${ref}`);
|
1288
1755
|
}
|
1289
|
-
|
1290
|
-
|
1756
|
+
|
1757
|
+
if (obj3.cmd !== "obj") {
|
1758
|
+
if (obj3.cmd.startsWith("obj")) {
|
1291
1759
|
num = parseInt(obj3.cmd.substring(3), 10);
|
1760
|
+
|
1292
1761
|
if (!Number.isNaN(num)) {
|
1293
1762
|
return num;
|
1294
1763
|
}
|
1295
1764
|
}
|
1296
|
-
|
1765
|
+
|
1766
|
+
throw new _core_utils.XRefEntryException(`Bad (uncompressed) XRef entry: ${ref}`);
|
1297
1767
|
}
|
1768
|
+
|
1298
1769
|
if (this.encrypt && !suppressEncryption) {
|
1299
1770
|
xrefEntry = parser.getObj(this.encrypt.createCipherTransform(num, gen));
|
1300
1771
|
} else {
|
1301
1772
|
xrefEntry = parser.getObj();
|
1302
1773
|
}
|
1774
|
+
|
1303
1775
|
if (!(0, _primitives.isStream)(xrefEntry)) {
|
1304
|
-
this.
|
1776
|
+
this._cacheMap.set(num, xrefEntry);
|
1305
1777
|
}
|
1778
|
+
|
1306
1779
|
return xrefEntry;
|
1307
1780
|
},
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1781
|
+
|
1782
|
+
fetchCompressed(ref, xrefEntry, suppressEncryption = false) {
|
1783
|
+
const tableOffset = xrefEntry.offset;
|
1784
|
+
const stream = this.fetch(_primitives.Ref.get(tableOffset, 0));
|
1785
|
+
|
1311
1786
|
if (!(0, _primitives.isStream)(stream)) {
|
1312
|
-
throw new _util.FormatError(
|
1787
|
+
throw new _util.FormatError("bad ObjStm stream");
|
1313
1788
|
}
|
1314
|
-
|
1315
|
-
|
1789
|
+
|
1790
|
+
const first = stream.dict.get("First");
|
1791
|
+
const n = stream.dict.get("N");
|
1792
|
+
|
1316
1793
|
if (!Number.isInteger(first) || !Number.isInteger(n)) {
|
1317
|
-
throw new _util.FormatError(
|
1318
|
-
}
|
1319
|
-
|
1320
|
-
parser
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1794
|
+
throw new _util.FormatError("invalid first and n parameters for ObjStm stream");
|
1795
|
+
}
|
1796
|
+
|
1797
|
+
const parser = new _parser.Parser({
|
1798
|
+
lexer: new _parser.Lexer(stream),
|
1799
|
+
xref: this,
|
1800
|
+
allowStreams: true
|
1801
|
+
});
|
1802
|
+
const nums = new Array(n);
|
1803
|
+
|
1804
|
+
for (let i = 0; i < n; ++i) {
|
1805
|
+
const num = parser.getObj();
|
1806
|
+
|
1327
1807
|
if (!Number.isInteger(num)) {
|
1328
|
-
throw new _util.FormatError(
|
1808
|
+
throw new _util.FormatError(`invalid object number in the ObjStm stream: ${num}`);
|
1329
1809
|
}
|
1330
|
-
|
1331
|
-
|
1810
|
+
|
1811
|
+
const offset = parser.getObj();
|
1812
|
+
|
1332
1813
|
if (!Number.isInteger(offset)) {
|
1333
|
-
throw new _util.FormatError(
|
1814
|
+
throw new _util.FormatError(`invalid object offset in the ObjStm stream: ${offset}`);
|
1334
1815
|
}
|
1816
|
+
|
1817
|
+
nums[i] = num;
|
1335
1818
|
}
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1819
|
+
|
1820
|
+
const entries = new Array(n);
|
1821
|
+
|
1822
|
+
for (let i = 0; i < n; ++i) {
|
1823
|
+
const obj = parser.getObj();
|
1824
|
+
entries[i] = obj;
|
1825
|
+
|
1826
|
+
if (parser.buf1 instanceof _primitives.Cmd && parser.buf1.cmd === "endobj") {
|
1339
1827
|
parser.shift();
|
1340
1828
|
}
|
1341
|
-
|
1342
|
-
|
1829
|
+
|
1830
|
+
if ((0, _primitives.isStream)(obj)) {
|
1831
|
+
continue;
|
1832
|
+
}
|
1833
|
+
|
1834
|
+
const num = nums[i],
|
1835
|
+
entry = this.entries[num];
|
1836
|
+
|
1343
1837
|
if (entry && entry.offset === tableOffset && entry.gen === i) {
|
1344
|
-
this.
|
1838
|
+
this._cacheMap.set(num, obj);
|
1345
1839
|
}
|
1346
1840
|
}
|
1841
|
+
|
1347
1842
|
xrefEntry = entries[xrefEntry.gen];
|
1843
|
+
|
1348
1844
|
if (xrefEntry === undefined) {
|
1349
|
-
throw new
|
1845
|
+
throw new _core_utils.XRefEntryException(`Bad (compressed) XRef entry: ${ref}`);
|
1350
1846
|
}
|
1847
|
+
|
1351
1848
|
return xrefEntry;
|
1352
1849
|
},
|
1353
|
-
fetchIfRefAsync: function () {
|
1354
|
-
var _ref = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee(obj, suppressEncryption) {
|
1355
|
-
return _regenerator2.default.wrap(function _callee$(_context) {
|
1356
|
-
while (1) {
|
1357
|
-
switch (_context.prev = _context.next) {
|
1358
|
-
case 0:
|
1359
|
-
if ((0, _primitives.isRef)(obj)) {
|
1360
|
-
_context.next = 2;
|
1361
|
-
break;
|
1362
|
-
}
|
1363
|
-
|
1364
|
-
return _context.abrupt('return', obj);
|
1365
|
-
|
1366
|
-
case 2:
|
1367
|
-
return _context.abrupt('return', this.fetchAsync(obj, suppressEncryption));
|
1368
|
-
|
1369
|
-
case 3:
|
1370
|
-
case 'end':
|
1371
|
-
return _context.stop();
|
1372
|
-
}
|
1373
|
-
}
|
1374
|
-
}, _callee, this);
|
1375
|
-
}));
|
1376
|
-
|
1377
|
-
function fetchIfRefAsync(_x, _x2) {
|
1378
|
-
return _ref.apply(this, arguments);
|
1379
|
-
}
|
1380
|
-
|
1381
|
-
return fetchIfRefAsync;
|
1382
|
-
}(),
|
1383
|
-
fetchAsync: function () {
|
1384
|
-
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regenerator2.default.mark(function _callee2(ref, suppressEncryption) {
|
1385
|
-
return _regenerator2.default.wrap(function _callee2$(_context2) {
|
1386
|
-
while (1) {
|
1387
|
-
switch (_context2.prev = _context2.next) {
|
1388
|
-
case 0:
|
1389
|
-
_context2.prev = 0;
|
1390
|
-
return _context2.abrupt('return', this.fetch(ref, suppressEncryption));
|
1391
|
-
|
1392
|
-
case 4:
|
1393
|
-
_context2.prev = 4;
|
1394
|
-
_context2.t0 = _context2['catch'](0);
|
1395
|
-
|
1396
|
-
if (_context2.t0 instanceof _util.MissingDataException) {
|
1397
|
-
_context2.next = 8;
|
1398
|
-
break;
|
1399
|
-
}
|
1400
1850
|
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
return this.pdfManager.requestRange(_context2.t0.begin, _context2.t0.end);
|
1851
|
+
async fetchIfRefAsync(obj, suppressEncryption) {
|
1852
|
+
if (obj instanceof _primitives.Ref) {
|
1853
|
+
return this.fetchAsync(obj, suppressEncryption);
|
1854
|
+
}
|
1406
1855
|
|
1407
|
-
|
1408
|
-
|
1856
|
+
return obj;
|
1857
|
+
},
|
1409
1858
|
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1859
|
+
async fetchAsync(ref, suppressEncryption) {
|
1860
|
+
try {
|
1861
|
+
return this.fetch(ref, suppressEncryption);
|
1862
|
+
} catch (ex) {
|
1863
|
+
if (!(ex instanceof _core_utils.MissingDataException)) {
|
1864
|
+
throw ex;
|
1865
|
+
}
|
1417
1866
|
|
1418
|
-
|
1419
|
-
return
|
1867
|
+
await this.pdfManager.requestRange(ex.begin, ex.end);
|
1868
|
+
return this.fetchAsync(ref, suppressEncryption);
|
1420
1869
|
}
|
1421
|
-
|
1422
|
-
return fetchAsync;
|
1423
|
-
}(),
|
1870
|
+
},
|
1424
1871
|
|
1425
1872
|
getCatalogObj: function XRef_getCatalogObj() {
|
1426
1873
|
return this.root;
|
@@ -1429,294 +1876,351 @@ var XRef = function XRefClosure() {
|
|
1429
1876
|
return XRef;
|
1430
1877
|
}();
|
1431
1878
|
|
1432
|
-
|
1433
|
-
function NameOrNumberTree(root, xref, type) {
|
1434
|
-
_classCallCheck(this, NameOrNumberTree);
|
1879
|
+
exports.XRef = XRef;
|
1435
1880
|
|
1881
|
+
class NameOrNumberTree {
|
1882
|
+
constructor(root, xref, type) {
|
1436
1883
|
if (this.constructor === NameOrNumberTree) {
|
1437
|
-
(0, _util.unreachable)(
|
1884
|
+
(0, _util.unreachable)("Cannot initialize NameOrNumberTree.");
|
1438
1885
|
}
|
1886
|
+
|
1439
1887
|
this.root = root;
|
1440
1888
|
this.xref = xref;
|
1441
1889
|
this._type = type;
|
1442
1890
|
}
|
1443
1891
|
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
if (!this.root) {
|
1449
|
-
return dict;
|
1450
|
-
}
|
1451
|
-
var xref = this.xref;
|
1452
|
-
var processed = new _primitives.RefSet();
|
1453
|
-
processed.put(this.root);
|
1454
|
-
var queue = [this.root];
|
1455
|
-
while (queue.length > 0) {
|
1456
|
-
var obj = xref.fetchIfRef(queue.shift());
|
1457
|
-
if (!(0, _primitives.isDict)(obj)) {
|
1458
|
-
continue;
|
1459
|
-
}
|
1460
|
-
if (obj.has('Kids')) {
|
1461
|
-
var _kids = obj.get('Kids');
|
1462
|
-
for (var i = 0, ii = _kids.length; i < ii; i++) {
|
1463
|
-
var kid = _kids[i];
|
1464
|
-
if (processed.has(kid)) {
|
1465
|
-
throw new _util.FormatError('Duplicate entry in "' + this._type + '" tree.');
|
1466
|
-
}
|
1467
|
-
queue.push(kid);
|
1468
|
-
processed.put(kid);
|
1469
|
-
}
|
1470
|
-
continue;
|
1471
|
-
}
|
1472
|
-
var entries = obj.get(this._type);
|
1473
|
-
if (Array.isArray(entries)) {
|
1474
|
-
for (var _i2 = 0, _ii = entries.length; _i2 < _ii; _i2 += 2) {
|
1475
|
-
dict[xref.fetchIfRef(entries[_i2])] = xref.fetchIfRef(entries[_i2 + 1]);
|
1476
|
-
}
|
1477
|
-
}
|
1478
|
-
}
|
1892
|
+
getAll() {
|
1893
|
+
const dict = Object.create(null);
|
1894
|
+
|
1895
|
+
if (!this.root) {
|
1479
1896
|
return dict;
|
1480
1897
|
}
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1898
|
+
|
1899
|
+
const xref = this.xref;
|
1900
|
+
const processed = new _primitives.RefSet();
|
1901
|
+
processed.put(this.root);
|
1902
|
+
const queue = [this.root];
|
1903
|
+
|
1904
|
+
while (queue.length > 0) {
|
1905
|
+
const obj = xref.fetchIfRef(queue.shift());
|
1906
|
+
|
1907
|
+
if (!(0, _primitives.isDict)(obj)) {
|
1908
|
+
continue;
|
1486
1909
|
}
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
var _kids2 = kidsOrEntries.get('Kids');
|
1497
|
-
if (!Array.isArray(_kids2)) {
|
1498
|
-
return null;
|
1499
|
-
}
|
1500
|
-
var l = 0,
|
1501
|
-
r = _kids2.length - 1;
|
1502
|
-
while (l <= r) {
|
1503
|
-
var m = l + r >> 1;
|
1504
|
-
var kid = xref.fetchIfRef(_kids2[m]);
|
1505
|
-
var limits = kid.get('Limits');
|
1506
|
-
if (key < xref.fetchIfRef(limits[0])) {
|
1507
|
-
r = m - 1;
|
1508
|
-
} else if (key > xref.fetchIfRef(limits[1])) {
|
1509
|
-
l = m + 1;
|
1510
|
-
} else {
|
1511
|
-
kidsOrEntries = xref.fetchIfRef(_kids2[m]);
|
1512
|
-
break;
|
1910
|
+
|
1911
|
+
if (obj.has("Kids")) {
|
1912
|
+
const kids = obj.get("Kids");
|
1913
|
+
|
1914
|
+
for (let i = 0, ii = kids.length; i < ii; i++) {
|
1915
|
+
const kid = kids[i];
|
1916
|
+
|
1917
|
+
if (processed.has(kid)) {
|
1918
|
+
throw new _util.FormatError(`Duplicate entry in "${this._type}" tree.`);
|
1513
1919
|
}
|
1920
|
+
|
1921
|
+
queue.push(kid);
|
1922
|
+
processed.put(kid);
|
1514
1923
|
}
|
1515
|
-
|
1516
|
-
|
1517
|
-
}
|
1924
|
+
|
1925
|
+
continue;
|
1518
1926
|
}
|
1519
|
-
|
1927
|
+
|
1928
|
+
const entries = obj.get(this._type);
|
1929
|
+
|
1520
1930
|
if (Array.isArray(entries)) {
|
1521
|
-
|
1522
|
-
|
1523
|
-
while (_l <= _r) {
|
1524
|
-
var _m = _l + _r & ~1;
|
1525
|
-
var currentKey = xref.fetchIfRef(entries[_m]);
|
1526
|
-
if (key < currentKey) {
|
1527
|
-
_r = _m - 2;
|
1528
|
-
} else if (key > currentKey) {
|
1529
|
-
_l = _m + 2;
|
1530
|
-
} else {
|
1531
|
-
return xref.fetchIfRef(entries[_m + 1]);
|
1532
|
-
}
|
1931
|
+
for (let i = 0, ii = entries.length; i < ii; i += 2) {
|
1932
|
+
dict[xref.fetchIfRef(entries[i])] = xref.fetchIfRef(entries[i + 1]);
|
1533
1933
|
}
|
1534
1934
|
}
|
1935
|
+
}
|
1936
|
+
|
1937
|
+
return dict;
|
1938
|
+
}
|
1939
|
+
|
1940
|
+
get(key) {
|
1941
|
+
if (!this.root) {
|
1535
1942
|
return null;
|
1536
1943
|
}
|
1537
|
-
}]);
|
1538
1944
|
|
1539
|
-
|
1540
|
-
|
1945
|
+
const xref = this.xref;
|
1946
|
+
let kidsOrEntries = xref.fetchIfRef(this.root);
|
1947
|
+
let loopCount = 0;
|
1948
|
+
const MAX_LEVELS = 10;
|
1949
|
+
|
1950
|
+
while (kidsOrEntries.has("Kids")) {
|
1951
|
+
if (++loopCount > MAX_LEVELS) {
|
1952
|
+
(0, _util.warn)(`Search depth limit reached for "${this._type}" tree.`);
|
1953
|
+
return null;
|
1954
|
+
}
|
1955
|
+
|
1956
|
+
const kids = kidsOrEntries.get("Kids");
|
1957
|
+
|
1958
|
+
if (!Array.isArray(kids)) {
|
1959
|
+
return null;
|
1960
|
+
}
|
1961
|
+
|
1962
|
+
let l = 0,
|
1963
|
+
r = kids.length - 1;
|
1964
|
+
|
1965
|
+
while (l <= r) {
|
1966
|
+
const m = l + r >> 1;
|
1967
|
+
const kid = xref.fetchIfRef(kids[m]);
|
1968
|
+
const limits = kid.get("Limits");
|
1969
|
+
|
1970
|
+
if (key < xref.fetchIfRef(limits[0])) {
|
1971
|
+
r = m - 1;
|
1972
|
+
} else if (key > xref.fetchIfRef(limits[1])) {
|
1973
|
+
l = m + 1;
|
1974
|
+
} else {
|
1975
|
+
kidsOrEntries = xref.fetchIfRef(kids[m]);
|
1976
|
+
break;
|
1977
|
+
}
|
1978
|
+
}
|
1979
|
+
|
1980
|
+
if (l > r) {
|
1981
|
+
return null;
|
1982
|
+
}
|
1983
|
+
}
|
1984
|
+
|
1985
|
+
const entries = kidsOrEntries.get(this._type);
|
1986
|
+
|
1987
|
+
if (Array.isArray(entries)) {
|
1988
|
+
let l = 0,
|
1989
|
+
r = entries.length - 2;
|
1541
1990
|
|
1542
|
-
|
1543
|
-
|
1991
|
+
while (l <= r) {
|
1992
|
+
const tmp = l + r >> 1,
|
1993
|
+
m = tmp + (tmp & 1);
|
1994
|
+
const currentKey = xref.fetchIfRef(entries[m]);
|
1544
1995
|
|
1545
|
-
|
1546
|
-
|
1996
|
+
if (key < currentKey) {
|
1997
|
+
r = m - 2;
|
1998
|
+
} else if (key > currentKey) {
|
1999
|
+
l = m + 2;
|
2000
|
+
} else {
|
2001
|
+
return xref.fetchIfRef(entries[m + 1]);
|
2002
|
+
}
|
2003
|
+
}
|
2004
|
+
|
2005
|
+
(0, _util.info)(`Falling back to an exhaustive search, for key "${key}", ` + `in "${this._type}" tree.`);
|
2006
|
+
|
2007
|
+
for (let m = 0, mm = entries.length; m < mm; m += 2) {
|
2008
|
+
const currentKey = xref.fetchIfRef(entries[m]);
|
2009
|
+
|
2010
|
+
if (currentKey === key) {
|
2011
|
+
(0, _util.warn)(`The "${key}" key was found at an incorrect, ` + `i.e. out-of-order, position in "${this._type}" tree.`);
|
2012
|
+
return xref.fetchIfRef(entries[m + 1]);
|
2013
|
+
}
|
2014
|
+
}
|
2015
|
+
}
|
1547
2016
|
|
1548
|
-
return
|
2017
|
+
return null;
|
1549
2018
|
}
|
1550
2019
|
|
1551
|
-
|
1552
|
-
}(NameOrNumberTree);
|
2020
|
+
}
|
1553
2021
|
|
1554
|
-
|
1555
|
-
|
2022
|
+
class NameTree extends NameOrNumberTree {
|
2023
|
+
constructor(root, xref) {
|
2024
|
+
super(root, xref, "Names");
|
2025
|
+
}
|
1556
2026
|
|
1557
|
-
|
1558
|
-
_classCallCheck(this, NumberTree);
|
2027
|
+
}
|
1559
2028
|
|
1560
|
-
|
2029
|
+
class NumberTree extends NameOrNumberTree {
|
2030
|
+
constructor(root, xref) {
|
2031
|
+
super(root, xref, "Nums");
|
1561
2032
|
}
|
1562
2033
|
|
1563
|
-
|
1564
|
-
}(NameOrNumberTree);
|
2034
|
+
}
|
1565
2035
|
|
1566
2036
|
var FileSpec = function FileSpecClosure() {
|
1567
2037
|
function FileSpec(root, xref) {
|
1568
2038
|
if (!root || !(0, _primitives.isDict)(root)) {
|
1569
2039
|
return;
|
1570
2040
|
}
|
2041
|
+
|
1571
2042
|
this.xref = xref;
|
1572
2043
|
this.root = root;
|
1573
|
-
|
1574
|
-
|
2044
|
+
|
2045
|
+
if (root.has("FS")) {
|
2046
|
+
this.fs = root.get("FS");
|
1575
2047
|
}
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
2048
|
+
|
2049
|
+
this.description = root.has("Desc") ? (0, _util.stringToPDFString)(root.get("Desc")) : "";
|
2050
|
+
|
2051
|
+
if (root.has("RF")) {
|
2052
|
+
(0, _util.warn)("Related file specifications are not supported");
|
1579
2053
|
}
|
2054
|
+
|
1580
2055
|
this.contentAvailable = true;
|
1581
|
-
|
2056
|
+
|
2057
|
+
if (!root.has("EF")) {
|
1582
2058
|
this.contentAvailable = false;
|
1583
|
-
(0, _util.warn)(
|
2059
|
+
(0, _util.warn)("Non-embedded file specifications are not supported");
|
1584
2060
|
}
|
1585
2061
|
}
|
2062
|
+
|
1586
2063
|
function pickPlatformItem(dict) {
|
1587
|
-
if (dict.has(
|
1588
|
-
return dict.get(
|
1589
|
-
} else if (dict.has(
|
1590
|
-
return dict.get(
|
1591
|
-
} else if (dict.has(
|
1592
|
-
return dict.get(
|
1593
|
-
} else if (dict.has(
|
1594
|
-
return dict.get(
|
1595
|
-
} else if (dict.has(
|
1596
|
-
return dict.get(
|
2064
|
+
if (dict.has("UF")) {
|
2065
|
+
return dict.get("UF");
|
2066
|
+
} else if (dict.has("F")) {
|
2067
|
+
return dict.get("F");
|
2068
|
+
} else if (dict.has("Unix")) {
|
2069
|
+
return dict.get("Unix");
|
2070
|
+
} else if (dict.has("Mac")) {
|
2071
|
+
return dict.get("Mac");
|
2072
|
+
} else if (dict.has("DOS")) {
|
2073
|
+
return dict.get("DOS");
|
1597
2074
|
}
|
2075
|
+
|
1598
2076
|
return null;
|
1599
2077
|
}
|
2078
|
+
|
1600
2079
|
FileSpec.prototype = {
|
1601
2080
|
get filename() {
|
1602
2081
|
if (!this._filename && this.root) {
|
1603
|
-
var filename = pickPlatformItem(this.root) ||
|
1604
|
-
this._filename = (0, _util.stringToPDFString)(filename).replace(/\\\\/g,
|
2082
|
+
var filename = pickPlatformItem(this.root) || "unnamed";
|
2083
|
+
this._filename = (0, _util.stringToPDFString)(filename).replace(/\\\\/g, "\\").replace(/\\\//g, "/").replace(/\\/g, "/");
|
1605
2084
|
}
|
2085
|
+
|
1606
2086
|
return this._filename;
|
1607
2087
|
},
|
2088
|
+
|
1608
2089
|
get content() {
|
1609
2090
|
if (!this.contentAvailable) {
|
1610
2091
|
return null;
|
1611
2092
|
}
|
2093
|
+
|
1612
2094
|
if (!this.contentRef && this.root) {
|
1613
|
-
this.contentRef = pickPlatformItem(this.root.get(
|
2095
|
+
this.contentRef = pickPlatformItem(this.root.get("EF"));
|
1614
2096
|
}
|
2097
|
+
|
1615
2098
|
var content = null;
|
2099
|
+
|
1616
2100
|
if (this.contentRef) {
|
1617
2101
|
var xref = this.xref;
|
1618
2102
|
var fileObj = xref.fetchIfRef(this.contentRef);
|
2103
|
+
|
1619
2104
|
if (fileObj && (0, _primitives.isStream)(fileObj)) {
|
1620
2105
|
content = fileObj.getBytes();
|
1621
2106
|
} else {
|
1622
|
-
(0, _util.warn)(
|
2107
|
+
(0, _util.warn)("Embedded file specification points to non-existing/invalid " + "content");
|
1623
2108
|
}
|
1624
2109
|
} else {
|
1625
|
-
(0, _util.warn)(
|
2110
|
+
(0, _util.warn)("Embedded file specification does not have a content");
|
1626
2111
|
}
|
2112
|
+
|
1627
2113
|
return content;
|
1628
2114
|
},
|
2115
|
+
|
1629
2116
|
get serializable() {
|
1630
2117
|
return {
|
1631
2118
|
filename: this.filename,
|
1632
2119
|
content: this.content
|
1633
2120
|
};
|
1634
2121
|
}
|
2122
|
+
|
1635
2123
|
};
|
1636
2124
|
return FileSpec;
|
1637
2125
|
}();
|
1638
|
-
|
2126
|
+
|
2127
|
+
exports.FileSpec = FileSpec;
|
2128
|
+
|
2129
|
+
const ObjectLoader = function () {
|
1639
2130
|
function mayHaveChildren(value) {
|
1640
|
-
return
|
2131
|
+
return value instanceof _primitives.Ref || value instanceof _primitives.Dict || Array.isArray(value) || (0, _primitives.isStream)(value);
|
1641
2132
|
}
|
2133
|
+
|
1642
2134
|
function addChildren(node, nodesToVisit) {
|
1643
|
-
if (
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
2135
|
+
if (node instanceof _primitives.Dict || (0, _primitives.isStream)(node)) {
|
2136
|
+
const dict = node instanceof _primitives.Dict ? node : node.dict;
|
2137
|
+
const dictKeys = dict.getKeys();
|
2138
|
+
|
2139
|
+
for (let i = 0, ii = dictKeys.length; i < ii; i++) {
|
2140
|
+
const rawValue = dict.getRaw(dictKeys[i]);
|
2141
|
+
|
1648
2142
|
if (mayHaveChildren(rawValue)) {
|
1649
2143
|
nodesToVisit.push(rawValue);
|
1650
2144
|
}
|
1651
2145
|
}
|
1652
2146
|
} else if (Array.isArray(node)) {
|
1653
|
-
for (
|
1654
|
-
|
2147
|
+
for (let i = 0, ii = node.length; i < ii; i++) {
|
2148
|
+
const value = node[i];
|
2149
|
+
|
1655
2150
|
if (mayHaveChildren(value)) {
|
1656
2151
|
nodesToVisit.push(value);
|
1657
2152
|
}
|
1658
2153
|
}
|
1659
2154
|
}
|
1660
2155
|
}
|
2156
|
+
|
1661
2157
|
function ObjectLoader(dict, keys, xref) {
|
1662
2158
|
this.dict = dict;
|
1663
2159
|
this.keys = keys;
|
1664
2160
|
this.xref = xref;
|
1665
2161
|
this.refSet = null;
|
1666
|
-
this.capability = null;
|
1667
2162
|
}
|
2163
|
+
|
1668
2164
|
ObjectLoader.prototype = {
|
1669
|
-
|
1670
|
-
this.
|
1671
|
-
|
1672
|
-
this.capability.resolve();
|
1673
|
-
return this.capability.promise;
|
2165
|
+
async load() {
|
2166
|
+
if (!this.xref.stream.allChunksLoaded || this.xref.stream.allChunksLoaded()) {
|
2167
|
+
return undefined;
|
1674
2168
|
}
|
1675
|
-
var keys = this.keys,
|
1676
|
-
dict = this.dict;
|
1677
2169
|
|
2170
|
+
const {
|
2171
|
+
keys,
|
2172
|
+
dict
|
2173
|
+
} = this;
|
1678
2174
|
this.refSet = new _primitives.RefSet();
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
2175
|
+
const nodesToVisit = [];
|
2176
|
+
|
2177
|
+
for (let i = 0, ii = keys.length; i < ii; i++) {
|
2178
|
+
const rawValue = dict.getRaw(keys[i]);
|
2179
|
+
|
1682
2180
|
if (rawValue !== undefined) {
|
1683
2181
|
nodesToVisit.push(rawValue);
|
1684
2182
|
}
|
1685
2183
|
}
|
1686
|
-
|
1687
|
-
return this.
|
2184
|
+
|
2185
|
+
return this._walk(nodesToVisit);
|
1688
2186
|
},
|
1689
|
-
_walk: function _walk(nodesToVisit) {
|
1690
|
-
var _this4 = this;
|
1691
2187
|
|
1692
|
-
|
1693
|
-
|
2188
|
+
async _walk(nodesToVisit) {
|
2189
|
+
const nodesToRevisit = [];
|
2190
|
+
const pendingRequests = [];
|
2191
|
+
|
1694
2192
|
while (nodesToVisit.length) {
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
2193
|
+
let currentNode = nodesToVisit.pop();
|
2194
|
+
|
2195
|
+
if (currentNode instanceof _primitives.Ref) {
|
2196
|
+
if (this.refSet.has(currentNode)) {
|
1698
2197
|
continue;
|
1699
2198
|
}
|
2199
|
+
|
1700
2200
|
try {
|
1701
|
-
this.refSet.put(
|
1702
|
-
|
2201
|
+
this.refSet.put(currentNode);
|
2202
|
+
currentNode = this.xref.fetch(currentNode);
|
1703
2203
|
} catch (ex) {
|
1704
|
-
if (!(ex instanceof
|
2204
|
+
if (!(ex instanceof _core_utils.MissingDataException)) {
|
1705
2205
|
throw ex;
|
1706
2206
|
}
|
1707
|
-
|
2207
|
+
|
2208
|
+
nodesToRevisit.push(currentNode);
|
1708
2209
|
pendingRequests.push({
|
1709
2210
|
begin: ex.begin,
|
1710
2211
|
end: ex.end
|
1711
2212
|
});
|
1712
2213
|
}
|
1713
2214
|
}
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
2215
|
+
|
2216
|
+
if (currentNode && currentNode.getBaseStreams) {
|
2217
|
+
const baseStreams = currentNode.getBaseStreams();
|
2218
|
+
let foundMissingData = false;
|
2219
|
+
|
2220
|
+
for (let i = 0, ii = baseStreams.length; i < ii; i++) {
|
2221
|
+
const stream = baseStreams[i];
|
2222
|
+
|
2223
|
+
if (stream.allChunksLoaded && !stream.allChunksLoaded()) {
|
1720
2224
|
foundMissingData = true;
|
1721
2225
|
pendingRequests.push({
|
1722
2226
|
begin: stream.start,
|
@@ -1724,31 +2228,35 @@ var ObjectLoader = function () {
|
|
1724
2228
|
});
|
1725
2229
|
}
|
1726
2230
|
}
|
2231
|
+
|
1727
2232
|
if (foundMissingData) {
|
1728
|
-
nodesToRevisit.push(
|
2233
|
+
nodesToRevisit.push(currentNode);
|
1729
2234
|
}
|
1730
2235
|
}
|
1731
|
-
|
2236
|
+
|
2237
|
+
addChildren(currentNode, nodesToVisit);
|
1732
2238
|
}
|
2239
|
+
|
1733
2240
|
if (pendingRequests.length) {
|
1734
|
-
this.xref.stream.manager.requestRanges(pendingRequests)
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1739
|
-
|
2241
|
+
await this.xref.stream.manager.requestRanges(pendingRequests);
|
2242
|
+
|
2243
|
+
for (let i = 0, ii = nodesToRevisit.length; i < ii; i++) {
|
2244
|
+
const node = nodesToRevisit[i];
|
2245
|
+
|
2246
|
+
if (node instanceof _primitives.Ref) {
|
2247
|
+
this.refSet.remove(node);
|
1740
2248
|
}
|
1741
|
-
|
1742
|
-
|
1743
|
-
return;
|
2249
|
+
}
|
2250
|
+
|
2251
|
+
return this._walk(nodesToRevisit);
|
1744
2252
|
}
|
2253
|
+
|
1745
2254
|
this.refSet = null;
|
1746
|
-
|
2255
|
+
return undefined;
|
1747
2256
|
}
|
2257
|
+
|
1748
2258
|
};
|
1749
2259
|
return ObjectLoader;
|
1750
2260
|
}();
|
1751
|
-
|
1752
|
-
exports.ObjectLoader = ObjectLoader;
|
1753
|
-
exports.XRef = XRef;
|
1754
|
-
exports.FileSpec = FileSpec;
|
2261
|
+
|
2262
|
+
exports.ObjectLoader = ObjectLoader;
|