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/parser.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,1006 +19,1304 @@
|
|
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.Parser = exports.Linearization = exports.Lexer =
|
27
|
+
exports.Parser = exports.Linearization = exports.Lexer = void 0;
|
28
28
|
|
29
|
-
var _stream = require(
|
29
|
+
var _stream = require("./stream.js");
|
30
30
|
|
31
|
-
var _util = require(
|
31
|
+
var _util = require("../shared/util.js");
|
32
32
|
|
33
|
-
var _primitives = require(
|
33
|
+
var _primitives = require("./primitives.js");
|
34
34
|
|
35
|
-
var
|
35
|
+
var _core_utils = require("./core_utils.js");
|
36
36
|
|
37
|
-
var
|
37
|
+
var _ccitt_stream = require("./ccitt_stream.js");
|
38
38
|
|
39
|
-
var
|
39
|
+
var _jbig2_stream = require("./jbig2_stream.js");
|
40
40
|
|
41
|
-
var
|
41
|
+
var _jpeg_stream = require("./jpeg_stream.js");
|
42
|
+
|
43
|
+
var _jpx_stream = require("./jpx_stream.js");
|
44
|
+
|
45
|
+
const MAX_LENGTH_TO_CACHE = 1000;
|
46
|
+
const MAX_ADLER32_LENGTH = 5552;
|
42
47
|
|
43
|
-
var MAX_LENGTH_TO_CACHE = 1000;
|
44
|
-
var MAX_ADLER32_LENGTH = 5552;
|
45
48
|
function computeAdler32(bytes) {
|
46
|
-
|
47
|
-
|
49
|
+
const bytesLength = bytes.length;
|
50
|
+
let a = 1,
|
48
51
|
b = 0;
|
49
|
-
|
50
|
-
|
52
|
+
|
53
|
+
for (let i = 0; i < bytesLength; ++i) {
|
54
|
+
a += bytes[i] & 0xff;
|
51
55
|
b += a;
|
52
56
|
}
|
57
|
+
|
53
58
|
return b % 65521 << 16 | a % 65521;
|
54
59
|
}
|
55
|
-
|
56
|
-
|
60
|
+
|
61
|
+
class Parser {
|
62
|
+
constructor({
|
63
|
+
lexer,
|
64
|
+
xref,
|
65
|
+
allowStreams = false,
|
66
|
+
recoveryMode = false
|
67
|
+
}) {
|
57
68
|
this.lexer = lexer;
|
58
|
-
this.allowStreams = allowStreams;
|
59
69
|
this.xref = xref;
|
60
|
-
this.
|
70
|
+
this.allowStreams = allowStreams;
|
71
|
+
this.recoveryMode = recoveryMode;
|
61
72
|
this.imageCache = Object.create(null);
|
62
73
|
this.refill();
|
63
74
|
}
|
64
|
-
|
65
|
-
|
66
|
-
|
75
|
+
|
76
|
+
refill() {
|
77
|
+
this.buf1 = this.lexer.getObj();
|
78
|
+
this.buf2 = this.lexer.getObj();
|
79
|
+
}
|
80
|
+
|
81
|
+
shift() {
|
82
|
+
if (this.buf2 instanceof _primitives.Cmd && this.buf2.cmd === "ID") {
|
83
|
+
this.buf1 = this.buf2;
|
84
|
+
this.buf2 = null;
|
85
|
+
} else {
|
86
|
+
this.buf1 = this.buf2;
|
67
87
|
this.buf2 = this.lexer.getObj();
|
68
|
-
}
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
} else {
|
74
|
-
this.buf1 = this.buf2;
|
75
|
-
this.buf2 = this.lexer.getObj();
|
76
|
-
}
|
77
|
-
},
|
78
|
-
tryShift: function Parser_tryShift() {
|
79
|
-
try {
|
80
|
-
this.shift();
|
81
|
-
return true;
|
82
|
-
} catch (e) {
|
83
|
-
if (e instanceof _util.MissingDataException) {
|
84
|
-
throw e;
|
85
|
-
}
|
86
|
-
return false;
|
87
|
-
}
|
88
|
-
},
|
89
|
-
getObj: function Parser_getObj(cipherTransform) {
|
90
|
-
var buf1 = this.buf1;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
tryShift() {
|
92
|
+
try {
|
91
93
|
this.shift();
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
94
|
+
return true;
|
95
|
+
} catch (e) {
|
96
|
+
if (e instanceof _core_utils.MissingDataException) {
|
97
|
+
throw e;
|
98
|
+
}
|
99
|
+
|
100
|
+
return false;
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
getObj(cipherTransform = null) {
|
105
|
+
const buf1 = this.buf1;
|
106
|
+
this.shift();
|
107
|
+
|
108
|
+
if (buf1 instanceof _primitives.Cmd) {
|
109
|
+
switch (buf1.cmd) {
|
110
|
+
case "BI":
|
111
|
+
return this.makeInlineImage(cipherTransform);
|
112
|
+
|
113
|
+
case "[":
|
114
|
+
const array = [];
|
115
|
+
|
116
|
+
while (!(0, _primitives.isCmd)(this.buf1, "]") && !(0, _primitives.isEOF)(this.buf1)) {
|
117
|
+
array.push(this.getObj(cipherTransform));
|
118
|
+
}
|
119
|
+
|
120
|
+
if ((0, _primitives.isEOF)(this.buf1)) {
|
121
|
+
if (!this.recoveryMode) {
|
122
|
+
throw new _util.FormatError("End of file inside array");
|
106
123
|
}
|
107
|
-
|
124
|
+
|
108
125
|
return array;
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
126
|
+
}
|
127
|
+
|
128
|
+
this.shift();
|
129
|
+
return array;
|
130
|
+
|
131
|
+
case "<<":
|
132
|
+
const dict = new _primitives.Dict(this.xref);
|
133
|
+
|
134
|
+
while (!(0, _primitives.isCmd)(this.buf1, ">>") && !(0, _primitives.isEOF)(this.buf1)) {
|
135
|
+
if (!(0, _primitives.isName)(this.buf1)) {
|
136
|
+
(0, _util.info)("Malformed dictionary: key must be a name object");
|
118
137
|
this.shift();
|
119
|
-
|
120
|
-
break;
|
121
|
-
}
|
122
|
-
dict.set(key, this.getObj(cipherTransform));
|
138
|
+
continue;
|
123
139
|
}
|
140
|
+
|
141
|
+
const key = this.buf1.name;
|
142
|
+
this.shift();
|
143
|
+
|
124
144
|
if ((0, _primitives.isEOF)(this.buf1)) {
|
125
|
-
|
126
|
-
throw new _util.FormatError('End of file inside dictionary');
|
127
|
-
}
|
128
|
-
return dict;
|
145
|
+
break;
|
129
146
|
}
|
130
|
-
|
131
|
-
|
147
|
+
|
148
|
+
dict.set(key, this.getObj(cipherTransform));
|
149
|
+
}
|
150
|
+
|
151
|
+
if ((0, _primitives.isEOF)(this.buf1)) {
|
152
|
+
if (!this.recoveryMode) {
|
153
|
+
throw new _util.FormatError("End of file inside dictionary");
|
132
154
|
}
|
133
|
-
|
155
|
+
|
134
156
|
return dict;
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
if (Number.isInteger(this.buf1) && (0, _primitives.isCmd)(this.buf2, 'R')) {
|
142
|
-
var ref = new _primitives.Ref(num, this.buf1);
|
143
|
-
this.shift();
|
157
|
+
}
|
158
|
+
|
159
|
+
if ((0, _primitives.isCmd)(this.buf2, "stream")) {
|
160
|
+
return this.allowStreams ? this.makeStream(dict, cipherTransform) : dict;
|
161
|
+
}
|
162
|
+
|
144
163
|
this.shift();
|
145
|
-
return
|
146
|
-
|
147
|
-
|
164
|
+
return dict;
|
165
|
+
|
166
|
+
default:
|
167
|
+
return buf1;
|
148
168
|
}
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
169
|
+
}
|
170
|
+
|
171
|
+
if (Number.isInteger(buf1)) {
|
172
|
+
if (Number.isInteger(this.buf1) && (0, _primitives.isCmd)(this.buf2, "R")) {
|
173
|
+
const ref = _primitives.Ref.get(buf1, this.buf1);
|
174
|
+
|
175
|
+
this.shift();
|
176
|
+
this.shift();
|
177
|
+
return ref;
|
178
|
+
}
|
179
|
+
|
180
|
+
return buf1;
|
181
|
+
}
|
182
|
+
|
183
|
+
if (typeof buf1 === "string") {
|
184
|
+
if (cipherTransform) {
|
185
|
+
return cipherTransform.decryptString(buf1);
|
155
186
|
}
|
187
|
+
|
156
188
|
return buf1;
|
157
|
-
}
|
158
|
-
|
159
|
-
|
189
|
+
}
|
190
|
+
|
191
|
+
return buf1;
|
192
|
+
}
|
193
|
+
|
194
|
+
findDefaultInlineStreamEnd(stream) {
|
195
|
+
const E = 0x45,
|
160
196
|
I = 0x49,
|
161
197
|
SPACE = 0x20,
|
162
|
-
LF =
|
163
|
-
CR =
|
164
|
-
|
198
|
+
LF = 0xa,
|
199
|
+
CR = 0xd;
|
200
|
+
const n = 10,
|
165
201
|
NUL = 0x0;
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
}
|
202
|
+
const startPos = stream.pos;
|
203
|
+
let state = 0,
|
204
|
+
ch,
|
205
|
+
maybeEIPos;
|
206
|
+
|
207
|
+
while ((ch = stream.getByte()) !== -1) {
|
208
|
+
if (state === 0) {
|
209
|
+
state = ch === E ? 1 : 0;
|
210
|
+
} else if (state === 1) {
|
211
|
+
state = ch === I ? 2 : 0;
|
212
|
+
} else {
|
213
|
+
(0, _util.assert)(state === 2);
|
214
|
+
|
215
|
+
if (ch === SPACE || ch === LF || ch === CR) {
|
216
|
+
maybeEIPos = stream.pos;
|
217
|
+
const followingBytes = stream.peekBytes(n);
|
218
|
+
|
219
|
+
for (let i = 0, ii = followingBytes.length; i < ii; i++) {
|
220
|
+
ch = followingBytes[i];
|
221
|
+
|
222
|
+
if (ch === NUL && followingBytes[i + 1] !== NUL) {
|
223
|
+
continue;
|
189
224
|
}
|
190
|
-
|
225
|
+
|
226
|
+
if (ch !== LF && ch !== CR && (ch < SPACE || ch > 0x7f)) {
|
227
|
+
state = 0;
|
191
228
|
break;
|
192
229
|
}
|
193
|
-
} else {
|
194
|
-
state = 0;
|
195
230
|
}
|
231
|
+
|
232
|
+
if (state === 2) {
|
233
|
+
break;
|
234
|
+
}
|
235
|
+
} else {
|
236
|
+
state = 0;
|
196
237
|
}
|
197
238
|
}
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
239
|
+
}
|
240
|
+
|
241
|
+
if (ch === -1) {
|
242
|
+
(0, _util.warn)("findDefaultInlineStreamEnd: " + "Reached the end of the stream without finding a valid EI marker");
|
243
|
+
|
244
|
+
if (maybeEIPos) {
|
245
|
+
(0, _util.warn)('... trying to recover by using the last "EI" occurrence.');
|
246
|
+
stream.skip(-(stream.pos - maybeEIPos));
|
204
247
|
}
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
248
|
+
}
|
249
|
+
|
250
|
+
let endOffset = 4;
|
251
|
+
stream.skip(-endOffset);
|
252
|
+
ch = stream.peekByte();
|
253
|
+
stream.skip(endOffset);
|
254
|
+
|
255
|
+
if (!(0, _core_utils.isWhiteSpace)(ch)) {
|
256
|
+
endOffset--;
|
257
|
+
}
|
258
|
+
|
259
|
+
return stream.pos - endOffset - startPos;
|
260
|
+
}
|
261
|
+
|
262
|
+
findDCTDecodeInlineStreamEnd(stream) {
|
263
|
+
const startPos = stream.pos;
|
264
|
+
let foundEOI = false,
|
265
|
+
b,
|
266
|
+
markerLength;
|
267
|
+
|
268
|
+
while ((b = stream.getByte()) !== -1) {
|
269
|
+
if (b !== 0xff) {
|
270
|
+
continue;
|
271
|
+
}
|
272
|
+
|
273
|
+
switch (stream.getByte()) {
|
274
|
+
case 0x00:
|
275
|
+
break;
|
276
|
+
|
277
|
+
case 0xff:
|
278
|
+
stream.skip(-1);
|
279
|
+
break;
|
280
|
+
|
281
|
+
case 0xd9:
|
282
|
+
foundEOI = true;
|
283
|
+
break;
|
284
|
+
|
285
|
+
case 0xc0:
|
286
|
+
case 0xc1:
|
287
|
+
case 0xc2:
|
288
|
+
case 0xc3:
|
289
|
+
case 0xc5:
|
290
|
+
case 0xc6:
|
291
|
+
case 0xc7:
|
292
|
+
case 0xc9:
|
293
|
+
case 0xca:
|
294
|
+
case 0xcb:
|
295
|
+
case 0xcd:
|
296
|
+
case 0xce:
|
297
|
+
case 0xcf:
|
298
|
+
case 0xc4:
|
299
|
+
case 0xcc:
|
300
|
+
case 0xda:
|
301
|
+
case 0xdb:
|
302
|
+
case 0xdc:
|
303
|
+
case 0xdd:
|
304
|
+
case 0xde:
|
305
|
+
case 0xdf:
|
306
|
+
case 0xe0:
|
307
|
+
case 0xe1:
|
308
|
+
case 0xe2:
|
309
|
+
case 0xe3:
|
310
|
+
case 0xe4:
|
311
|
+
case 0xe5:
|
312
|
+
case 0xe6:
|
313
|
+
case 0xe7:
|
314
|
+
case 0xe8:
|
315
|
+
case 0xe9:
|
316
|
+
case 0xea:
|
317
|
+
case 0xeb:
|
318
|
+
case 0xec:
|
319
|
+
case 0xed:
|
320
|
+
case 0xee:
|
321
|
+
case 0xef:
|
322
|
+
case 0xfe:
|
323
|
+
markerLength = stream.getUint16();
|
324
|
+
|
325
|
+
if (markerLength > 2) {
|
326
|
+
stream.skip(markerLength - 2);
|
327
|
+
} else {
|
328
|
+
stream.skip(-2);
|
329
|
+
}
|
330
|
+
|
274
331
|
break;
|
275
|
-
}
|
276
332
|
}
|
277
|
-
|
278
|
-
if (
|
279
|
-
|
280
|
-
stream.skip(-length);
|
281
|
-
return this.findDefaultInlineStreamEnd(stream);
|
333
|
+
|
334
|
+
if (foundEOI) {
|
335
|
+
break;
|
282
336
|
}
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
337
|
+
}
|
338
|
+
|
339
|
+
const length = stream.pos - startPos;
|
340
|
+
|
341
|
+
if (b === -1) {
|
342
|
+
(0, _util.warn)("Inline DCTDecode image stream: " + "EOI marker not found, searching for /EI/ instead.");
|
343
|
+
stream.skip(-length);
|
344
|
+
return this.findDefaultInlineStreamEnd(stream);
|
345
|
+
}
|
346
|
+
|
347
|
+
this.inlineStreamSkipEI(stream);
|
348
|
+
return length;
|
349
|
+
}
|
350
|
+
|
351
|
+
findASCII85DecodeInlineStreamEnd(stream) {
|
352
|
+
const TILDE = 0x7e,
|
353
|
+
GT = 0x3e;
|
354
|
+
const startPos = stream.pos;
|
355
|
+
let ch;
|
356
|
+
|
357
|
+
while ((ch = stream.getByte()) !== -1) {
|
358
|
+
if (ch === TILDE) {
|
359
|
+
const tildePos = stream.pos;
|
360
|
+
ch = stream.peekByte();
|
361
|
+
|
362
|
+
while ((0, _core_utils.isWhiteSpace)(ch)) {
|
294
363
|
stream.skip();
|
295
|
-
|
364
|
+
ch = stream.peekByte();
|
296
365
|
}
|
297
|
-
|
298
|
-
length = stream.pos - startPos;
|
299
|
-
if (ch === -1) {
|
300
|
-
(0, _util.warn)('Inline ASCII85Decode image stream: ' + 'EOD marker not found, searching for /EI/ instead.');
|
301
|
-
stream.skip(-length);
|
302
|
-
return this.findDefaultInlineStreamEnd(stream);
|
303
|
-
}
|
304
|
-
this.inlineStreamSkipEI(stream);
|
305
|
-
return length;
|
306
|
-
},
|
307
|
-
findASCIIHexDecodeInlineStreamEnd: function Parser_findASCIIHexDecodeInlineStreamEnd(stream) {
|
308
|
-
var GT = 0x3E;
|
309
|
-
var startPos = stream.pos,
|
310
|
-
ch,
|
311
|
-
length;
|
312
|
-
while ((ch = stream.getByte()) !== -1) {
|
366
|
+
|
313
367
|
if (ch === GT) {
|
368
|
+
stream.skip();
|
314
369
|
break;
|
315
370
|
}
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
this.inlineStreamSkipEI(stream);
|
324
|
-
return length;
|
325
|
-
},
|
326
|
-
inlineStreamSkipEI: function Parser_inlineStreamSkipEI(stream) {
|
327
|
-
var E = 0x45,
|
328
|
-
I = 0x49;
|
329
|
-
var state = 0,
|
330
|
-
ch;
|
331
|
-
while ((ch = stream.getByte()) !== -1) {
|
332
|
-
if (state === 0) {
|
333
|
-
state = ch === E ? 1 : 0;
|
334
|
-
} else if (state === 1) {
|
335
|
-
state = ch === I ? 2 : 0;
|
336
|
-
} else if (state === 2) {
|
337
|
-
break;
|
371
|
+
|
372
|
+
if (stream.pos > tildePos) {
|
373
|
+
const maybeEI = stream.peekBytes(2);
|
374
|
+
|
375
|
+
if (maybeEI[0] === 0x45 && maybeEI[1] === 0x49) {
|
376
|
+
break;
|
377
|
+
}
|
338
378
|
}
|
339
379
|
}
|
340
|
-
}
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
380
|
+
}
|
381
|
+
|
382
|
+
const length = stream.pos - startPos;
|
383
|
+
|
384
|
+
if (ch === -1) {
|
385
|
+
(0, _util.warn)("Inline ASCII85Decode image stream: " + "EOD marker not found, searching for /EI/ instead.");
|
386
|
+
stream.skip(-length);
|
387
|
+
return this.findDefaultInlineStreamEnd(stream);
|
388
|
+
}
|
389
|
+
|
390
|
+
this.inlineStreamSkipEI(stream);
|
391
|
+
return length;
|
392
|
+
}
|
393
|
+
|
394
|
+
findASCIIHexDecodeInlineStreamEnd(stream) {
|
395
|
+
const GT = 0x3e;
|
396
|
+
const startPos = stream.pos;
|
397
|
+
let ch;
|
398
|
+
|
399
|
+
while ((ch = stream.getByte()) !== -1) {
|
400
|
+
if (ch === GT) {
|
401
|
+
break;
|
356
402
|
}
|
357
|
-
|
358
|
-
|
403
|
+
}
|
404
|
+
|
405
|
+
const length = stream.pos - startPos;
|
406
|
+
|
407
|
+
if (ch === -1) {
|
408
|
+
(0, _util.warn)("Inline ASCIIHexDecode image stream: " + "EOD marker not found, searching for /EI/ instead.");
|
409
|
+
stream.skip(-length);
|
410
|
+
return this.findDefaultInlineStreamEnd(stream);
|
411
|
+
}
|
412
|
+
|
413
|
+
this.inlineStreamSkipEI(stream);
|
414
|
+
return length;
|
415
|
+
}
|
416
|
+
|
417
|
+
inlineStreamSkipEI(stream) {
|
418
|
+
const E = 0x45,
|
419
|
+
I = 0x49;
|
420
|
+
let state = 0,
|
421
|
+
ch;
|
422
|
+
|
423
|
+
while ((ch = stream.getByte()) !== -1) {
|
424
|
+
if (state === 0) {
|
425
|
+
state = ch === E ? 1 : 0;
|
426
|
+
} else if (state === 1) {
|
427
|
+
state = ch === I ? 2 : 0;
|
428
|
+
} else if (state === 2) {
|
429
|
+
break;
|
359
430
|
}
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
431
|
+
}
|
432
|
+
}
|
433
|
+
|
434
|
+
makeInlineImage(cipherTransform) {
|
435
|
+
const lexer = this.lexer;
|
436
|
+
const stream = lexer.stream;
|
437
|
+
const dict = new _primitives.Dict(this.xref);
|
438
|
+
let dictLength;
|
439
|
+
|
440
|
+
while (!(0, _primitives.isCmd)(this.buf1, "ID") && !(0, _primitives.isEOF)(this.buf1)) {
|
441
|
+
if (!(0, _primitives.isName)(this.buf1)) {
|
442
|
+
throw new _util.FormatError("Dictionary key must be a name object");
|
369
443
|
}
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
} else if (filterName === 'ASCIIHexDecode' || filterName === 'AHx') {
|
377
|
-
length = this.findASCIIHexDecodeInlineStreamEnd(stream);
|
378
|
-
} else {
|
379
|
-
length = this.findDefaultInlineStreamEnd(stream);
|
444
|
+
|
445
|
+
const key = this.buf1.name;
|
446
|
+
this.shift();
|
447
|
+
|
448
|
+
if ((0, _primitives.isEOF)(this.buf1)) {
|
449
|
+
break;
|
380
450
|
}
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
451
|
+
|
452
|
+
dict.set(key, this.getObj(cipherTransform));
|
453
|
+
}
|
454
|
+
|
455
|
+
if (lexer.beginInlineImagePos !== -1) {
|
456
|
+
dictLength = stream.pos - lexer.beginInlineImagePos;
|
457
|
+
}
|
458
|
+
|
459
|
+
const filter = dict.get("Filter", "F");
|
460
|
+
let filterName;
|
461
|
+
|
462
|
+
if ((0, _primitives.isName)(filter)) {
|
463
|
+
filterName = filter.name;
|
464
|
+
} else if (Array.isArray(filter)) {
|
465
|
+
const filterZero = this.xref.fetchIfRef(filter[0]);
|
466
|
+
|
467
|
+
if ((0, _primitives.isName)(filterZero)) {
|
468
|
+
filterName = filterZero.name;
|
398
469
|
}
|
399
|
-
|
400
|
-
|
470
|
+
}
|
471
|
+
|
472
|
+
const startPos = stream.pos;
|
473
|
+
let length;
|
474
|
+
|
475
|
+
if (filterName === "DCTDecode" || filterName === "DCT") {
|
476
|
+
length = this.findDCTDecodeInlineStreamEnd(stream);
|
477
|
+
} else if (filterName === "ASCII85Decode" || filterName === "A85") {
|
478
|
+
length = this.findASCII85DecodeInlineStreamEnd(stream);
|
479
|
+
} else if (filterName === "ASCIIHexDecode" || filterName === "AHx") {
|
480
|
+
length = this.findASCIIHexDecodeInlineStreamEnd(stream);
|
481
|
+
} else {
|
482
|
+
length = this.findDefaultInlineStreamEnd(stream);
|
483
|
+
}
|
484
|
+
|
485
|
+
let imageStream = stream.makeSubStream(startPos, length, dict);
|
486
|
+
let cacheKey;
|
487
|
+
|
488
|
+
if (length < MAX_LENGTH_TO_CACHE && dictLength < MAX_ADLER32_LENGTH) {
|
489
|
+
const imageBytes = imageStream.getBytes();
|
490
|
+
imageStream.reset();
|
491
|
+
const initialStreamPos = stream.pos;
|
492
|
+
stream.pos = lexer.beginInlineImagePos;
|
493
|
+
const dictBytes = stream.getBytes(dictLength);
|
494
|
+
stream.pos = initialStreamPos;
|
495
|
+
cacheKey = computeAdler32(imageBytes) + "_" + computeAdler32(dictBytes);
|
496
|
+
const cacheEntry = this.imageCache[cacheKey];
|
497
|
+
|
498
|
+
if (cacheEntry !== undefined) {
|
499
|
+
this.buf2 = _primitives.Cmd.get("EI");
|
500
|
+
this.shift();
|
501
|
+
cacheEntry.reset();
|
502
|
+
return cacheEntry;
|
401
503
|
}
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
504
|
+
}
|
505
|
+
|
506
|
+
if (cipherTransform) {
|
507
|
+
imageStream = cipherTransform.createStream(imageStream, length);
|
508
|
+
}
|
509
|
+
|
510
|
+
imageStream = this.filter(imageStream, dict, length);
|
511
|
+
imageStream.dict = dict;
|
512
|
+
|
513
|
+
if (cacheKey !== undefined) {
|
514
|
+
imageStream.cacheKey = `inline_${length}_${cacheKey}`;
|
515
|
+
this.imageCache[cacheKey] = imageStream;
|
516
|
+
}
|
517
|
+
|
518
|
+
this.buf2 = _primitives.Cmd.get("EI");
|
519
|
+
this.shift();
|
520
|
+
return imageStream;
|
521
|
+
}
|
522
|
+
|
523
|
+
_findStreamLength(startPos, signature) {
|
524
|
+
const {
|
525
|
+
stream
|
526
|
+
} = this.lexer;
|
527
|
+
stream.pos = startPos;
|
528
|
+
const SCAN_BLOCK_LENGTH = 2048;
|
529
|
+
const signatureLength = signature.length;
|
530
|
+
|
531
|
+
while (stream.pos < stream.end) {
|
532
|
+
const scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH);
|
533
|
+
const scanLength = scanBytes.length - signatureLength;
|
534
|
+
|
535
|
+
if (scanLength <= 0) {
|
536
|
+
break;
|
407
537
|
}
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
var SCAN_BLOCK_LENGTH = 2048;
|
417
|
-
var signatureLength = signature.length;
|
418
|
-
while (stream.pos < stream.end) {
|
419
|
-
var scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH);
|
420
|
-
var scanLength = scanBytes.length - signatureLength;
|
421
|
-
if (scanLength <= 0) {
|
422
|
-
break;
|
538
|
+
|
539
|
+
let pos = 0;
|
540
|
+
|
541
|
+
while (pos < scanLength) {
|
542
|
+
let j = 0;
|
543
|
+
|
544
|
+
while (j < signatureLength && scanBytes[pos + j] === signature[j]) {
|
545
|
+
j++;
|
423
546
|
}
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
j++;
|
429
|
-
}
|
430
|
-
if (j >= signatureLength) {
|
431
|
-
stream.pos += pos;
|
432
|
-
return stream.pos - startPos;
|
433
|
-
}
|
434
|
-
pos++;
|
547
|
+
|
548
|
+
if (j >= signatureLength) {
|
549
|
+
stream.pos += pos;
|
550
|
+
return stream.pos - startPos;
|
435
551
|
}
|
436
|
-
|
437
|
-
|
438
|
-
return -1;
|
439
|
-
},
|
440
|
-
|
441
|
-
makeStream: function Parser_makeStream(dict, cipherTransform) {
|
442
|
-
var lexer = this.lexer;
|
443
|
-
var stream = lexer.stream;
|
444
|
-
lexer.skipToNextLine();
|
445
|
-
var startPos = stream.pos - 1;
|
446
|
-
var length = dict.get('Length');
|
447
|
-
if (!Number.isInteger(length)) {
|
448
|
-
(0, _util.info)('Bad ' + length + ' attribute in stream');
|
449
|
-
length = 0;
|
552
|
+
|
553
|
+
pos++;
|
450
554
|
}
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
555
|
+
|
556
|
+
stream.pos += scanLength;
|
557
|
+
}
|
558
|
+
|
559
|
+
return -1;
|
560
|
+
}
|
561
|
+
|
562
|
+
makeStream(dict, cipherTransform) {
|
563
|
+
const lexer = this.lexer;
|
564
|
+
let stream = lexer.stream;
|
565
|
+
lexer.skipToNextLine();
|
566
|
+
const startPos = stream.pos - 1;
|
567
|
+
let length = dict.get("Length");
|
568
|
+
|
569
|
+
if (!Number.isInteger(length)) {
|
570
|
+
(0, _util.info)(`Bad length "${length}" in stream`);
|
571
|
+
length = 0;
|
572
|
+
}
|
573
|
+
|
574
|
+
stream.pos = startPos + length;
|
575
|
+
lexer.nextChar();
|
576
|
+
|
577
|
+
if (this.tryShift() && (0, _primitives.isCmd)(this.buf2, "endstream")) {
|
578
|
+
this.shift();
|
579
|
+
} else {
|
580
|
+
const ENDSTREAM_SIGNATURE = new Uint8Array([0x65, 0x6E, 0x64, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6D]);
|
581
|
+
|
582
|
+
let actualLength = this._findStreamLength(startPos, ENDSTREAM_SIGNATURE);
|
583
|
+
|
584
|
+
if (actualLength < 0) {
|
585
|
+
const MAX_TRUNCATION = 1;
|
586
|
+
|
587
|
+
for (let i = 1; i <= MAX_TRUNCATION; i++) {
|
588
|
+
const end = ENDSTREAM_SIGNATURE.length - i;
|
589
|
+
const TRUNCATED_SIGNATURE = ENDSTREAM_SIGNATURE.slice(0, end);
|
590
|
+
|
591
|
+
const maybeLength = this._findStreamLength(startPos, TRUNCATED_SIGNATURE);
|
592
|
+
|
593
|
+
if (maybeLength >= 0) {
|
594
|
+
const lastByte = stream.peekBytes(end + 1)[end];
|
595
|
+
|
596
|
+
if (!(0, _core_utils.isWhiteSpace)(lastByte)) {
|
471
597
|
break;
|
472
598
|
}
|
599
|
+
|
600
|
+
(0, _util.info)(`Found "${(0, _util.bytesToString)(TRUNCATED_SIGNATURE)}" when ` + "searching for endstream command.");
|
601
|
+
actualLength = maybeLength;
|
602
|
+
break;
|
473
603
|
}
|
474
|
-
if (actualLength < 0) {
|
475
|
-
throw new _util.FormatError('Missing endstream command.');
|
476
|
-
}
|
477
|
-
}
|
478
|
-
length = actualLength;
|
479
|
-
lexer.nextChar();
|
480
|
-
this.shift();
|
481
|
-
this.shift();
|
482
|
-
}
|
483
|
-
this.shift();
|
484
|
-
stream = stream.makeSubStream(startPos, length, dict);
|
485
|
-
if (cipherTransform) {
|
486
|
-
stream = cipherTransform.createStream(stream, length);
|
487
|
-
}
|
488
|
-
stream = this.filter(stream, dict, length);
|
489
|
-
stream.dict = dict;
|
490
|
-
return stream;
|
491
|
-
},
|
492
|
-
filter: function Parser_filter(stream, dict, length) {
|
493
|
-
var filter = dict.get('Filter', 'F');
|
494
|
-
var params = dict.get('DecodeParms', 'DP');
|
495
|
-
if ((0, _primitives.isName)(filter)) {
|
496
|
-
if (Array.isArray(params)) {
|
497
|
-
(0, _util.warn)('/DecodeParms should not contain an Array, ' + 'when /Filter contains a Name.');
|
498
604
|
}
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
if (Array.isArray(filter)) {
|
503
|
-
var filterArray = filter;
|
504
|
-
var paramsArray = params;
|
505
|
-
for (var i = 0, ii = filterArray.length; i < ii; ++i) {
|
506
|
-
filter = this.xref.fetchIfRef(filterArray[i]);
|
507
|
-
if (!(0, _primitives.isName)(filter)) {
|
508
|
-
throw new _util.FormatError('Bad filter name: ' + filter);
|
509
|
-
}
|
510
|
-
params = null;
|
511
|
-
if (Array.isArray(paramsArray) && i in paramsArray) {
|
512
|
-
params = this.xref.fetchIfRef(paramsArray[i]);
|
513
|
-
}
|
514
|
-
stream = this.makeFilter(stream, filter.name, maybeLength, params);
|
515
|
-
maybeLength = null;
|
605
|
+
|
606
|
+
if (actualLength < 0) {
|
607
|
+
throw new _util.FormatError("Missing endstream command.");
|
516
608
|
}
|
517
609
|
}
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
}
|
561
|
-
if (name === 'CCITTFaxDecode' || name === 'CCF') {
|
562
|
-
xrefStreamStats[_util.StreamType.CCF] = true;
|
563
|
-
return new _ccitt_stream.CCITTFaxStream(stream, maybeLength, params);
|
610
|
+
|
611
|
+
length = actualLength;
|
612
|
+
lexer.nextChar();
|
613
|
+
this.shift();
|
614
|
+
this.shift();
|
615
|
+
}
|
616
|
+
|
617
|
+
this.shift();
|
618
|
+
stream = stream.makeSubStream(startPos, length, dict);
|
619
|
+
|
620
|
+
if (cipherTransform) {
|
621
|
+
stream = cipherTransform.createStream(stream, length);
|
622
|
+
}
|
623
|
+
|
624
|
+
stream = this.filter(stream, dict, length);
|
625
|
+
stream.dict = dict;
|
626
|
+
return stream;
|
627
|
+
}
|
628
|
+
|
629
|
+
filter(stream, dict, length) {
|
630
|
+
let filter = dict.get("Filter", "F");
|
631
|
+
let params = dict.get("DecodeParms", "DP");
|
632
|
+
|
633
|
+
if ((0, _primitives.isName)(filter)) {
|
634
|
+
if (Array.isArray(params)) {
|
635
|
+
(0, _util.warn)("/DecodeParms should not contain an Array, " + "when /Filter contains a Name.");
|
636
|
+
}
|
637
|
+
|
638
|
+
return this.makeFilter(stream, filter.name, length, params);
|
639
|
+
}
|
640
|
+
|
641
|
+
let maybeLength = length;
|
642
|
+
|
643
|
+
if (Array.isArray(filter)) {
|
644
|
+
const filterArray = filter;
|
645
|
+
const paramsArray = params;
|
646
|
+
|
647
|
+
for (let i = 0, ii = filterArray.length; i < ii; ++i) {
|
648
|
+
filter = this.xref.fetchIfRef(filterArray[i]);
|
649
|
+
|
650
|
+
if (!(0, _primitives.isName)(filter)) {
|
651
|
+
throw new _util.FormatError(`Bad filter name "${filter}"`);
|
564
652
|
}
|
565
|
-
|
566
|
-
|
567
|
-
|
653
|
+
|
654
|
+
params = null;
|
655
|
+
|
656
|
+
if (Array.isArray(paramsArray) && i in paramsArray) {
|
657
|
+
params = this.xref.fetchIfRef(paramsArray[i]);
|
568
658
|
}
|
569
|
-
|
570
|
-
|
571
|
-
|
659
|
+
|
660
|
+
stream = this.makeFilter(stream, filter.name, maybeLength, params);
|
661
|
+
maybeLength = null;
|
662
|
+
}
|
663
|
+
}
|
664
|
+
|
665
|
+
return stream;
|
666
|
+
}
|
667
|
+
|
668
|
+
makeFilter(stream, name, maybeLength, params) {
|
669
|
+
if (maybeLength === 0) {
|
670
|
+
(0, _util.warn)(`Empty "${name}" stream.`);
|
671
|
+
return new _stream.NullStream();
|
672
|
+
}
|
673
|
+
|
674
|
+
try {
|
675
|
+
const xrefStreamStats = this.xref.stats.streamTypes;
|
676
|
+
|
677
|
+
if (name === "FlateDecode" || name === "Fl") {
|
678
|
+
xrefStreamStats[_util.StreamType.FLATE] = true;
|
679
|
+
|
680
|
+
if (params) {
|
681
|
+
return new _stream.PredictorStream(new _stream.FlateStream(stream, maybeLength), maybeLength, params);
|
572
682
|
}
|
573
|
-
|
574
|
-
return stream;
|
575
|
-
}
|
576
|
-
|
577
|
-
|
683
|
+
|
684
|
+
return new _stream.FlateStream(stream, maybeLength);
|
685
|
+
}
|
686
|
+
|
687
|
+
if (name === "LZWDecode" || name === "LZW") {
|
688
|
+
xrefStreamStats[_util.StreamType.LZW] = true;
|
689
|
+
let earlyChange = 1;
|
690
|
+
|
691
|
+
if (params) {
|
692
|
+
if (params.has("EarlyChange")) {
|
693
|
+
earlyChange = params.get("EarlyChange");
|
694
|
+
}
|
695
|
+
|
696
|
+
return new _stream.PredictorStream(new _stream.LZWStream(stream, maybeLength, earlyChange), maybeLength, params);
|
578
697
|
}
|
579
|
-
|
580
|
-
return new _stream.
|
698
|
+
|
699
|
+
return new _stream.LZWStream(stream, maybeLength, earlyChange);
|
700
|
+
}
|
701
|
+
|
702
|
+
if (name === "DCTDecode" || name === "DCT") {
|
703
|
+
xrefStreamStats[_util.StreamType.DCT] = true;
|
704
|
+
return new _jpeg_stream.JpegStream(stream, maybeLength, stream.dict, params);
|
705
|
+
}
|
706
|
+
|
707
|
+
if (name === "JPXDecode" || name === "JPX") {
|
708
|
+
xrefStreamStats[_util.StreamType.JPX] = true;
|
709
|
+
return new _jpx_stream.JpxStream(stream, maybeLength, stream.dict, params);
|
710
|
+
}
|
711
|
+
|
712
|
+
if (name === "ASCII85Decode" || name === "A85") {
|
713
|
+
xrefStreamStats[_util.StreamType.A85] = true;
|
714
|
+
return new _stream.Ascii85Stream(stream, maybeLength);
|
715
|
+
}
|
716
|
+
|
717
|
+
if (name === "ASCIIHexDecode" || name === "AHx") {
|
718
|
+
xrefStreamStats[_util.StreamType.AHX] = true;
|
719
|
+
return new _stream.AsciiHexStream(stream, maybeLength);
|
720
|
+
}
|
721
|
+
|
722
|
+
if (name === "CCITTFaxDecode" || name === "CCF") {
|
723
|
+
xrefStreamStats[_util.StreamType.CCF] = true;
|
724
|
+
return new _ccitt_stream.CCITTFaxStream(stream, maybeLength, params);
|
581
725
|
}
|
726
|
+
|
727
|
+
if (name === "RunLengthDecode" || name === "RL") {
|
728
|
+
xrefStreamStats[_util.StreamType.RLX] = true;
|
729
|
+
return new _stream.RunLengthStream(stream, maybeLength);
|
730
|
+
}
|
731
|
+
|
732
|
+
if (name === "JBIG2Decode") {
|
733
|
+
xrefStreamStats[_util.StreamType.JBIG] = true;
|
734
|
+
return new _jbig2_stream.Jbig2Stream(stream, maybeLength, stream.dict, params);
|
735
|
+
}
|
736
|
+
|
737
|
+
(0, _util.warn)(`Filter "${name}" is not supported.`);
|
738
|
+
return stream;
|
739
|
+
} catch (ex) {
|
740
|
+
if (ex instanceof _core_utils.MissingDataException) {
|
741
|
+
throw ex;
|
742
|
+
}
|
743
|
+
|
744
|
+
(0, _util.warn)(`Invalid stream: "${ex}"`);
|
745
|
+
return new _stream.NullStream();
|
582
746
|
}
|
583
|
-
}
|
584
|
-
|
585
|
-
}
|
586
|
-
|
587
|
-
|
747
|
+
}
|
748
|
+
|
749
|
+
}
|
750
|
+
|
751
|
+
exports.Parser = Parser;
|
752
|
+
const specialChars = [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
753
|
+
|
754
|
+
function toHexDigit(ch) {
|
755
|
+
if (ch >= 0x30 && ch <= 0x39) {
|
756
|
+
return ch & 0x0f;
|
757
|
+
}
|
758
|
+
|
759
|
+
if (ch >= 0x41 && ch <= 0x46 || ch >= 0x61 && ch <= 0x66) {
|
760
|
+
return (ch & 0x0f) + 9;
|
761
|
+
}
|
762
|
+
|
763
|
+
return -1;
|
764
|
+
}
|
765
|
+
|
766
|
+
class Lexer {
|
767
|
+
constructor(stream, knownCommands = null) {
|
588
768
|
this.stream = stream;
|
589
769
|
this.nextChar();
|
590
770
|
this.strBuf = [];
|
591
771
|
this.knownCommands = knownCommands;
|
772
|
+
this._hexStringNumWarn = 0;
|
592
773
|
this.beginInlineImagePos = -1;
|
593
774
|
}
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
return ch & 0x0F;
|
598
|
-
}
|
599
|
-
if (ch >= 0x41 && ch <= 0x46 || ch >= 0x61 && ch <= 0x66) {
|
600
|
-
return (ch & 0x0F) + 9;
|
601
|
-
}
|
602
|
-
return -1;
|
775
|
+
|
776
|
+
nextChar() {
|
777
|
+
return this.currentChar = this.stream.getByte();
|
603
778
|
}
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
ch = this.nextChar();
|
621
|
-
}
|
622
|
-
} else if (ch === 0x2B) {
|
623
|
-
sign = 1;
|
779
|
+
|
780
|
+
peekChar() {
|
781
|
+
return this.stream.peekByte();
|
782
|
+
}
|
783
|
+
|
784
|
+
getNumber() {
|
785
|
+
let ch = this.currentChar;
|
786
|
+
let eNotation = false;
|
787
|
+
let divideBy = 0;
|
788
|
+
let sign = 0;
|
789
|
+
|
790
|
+
if (ch === 0x2d) {
|
791
|
+
sign = -1;
|
792
|
+
ch = this.nextChar();
|
793
|
+
|
794
|
+
if (ch === 0x2d) {
|
624
795
|
ch = this.nextChar();
|
625
796
|
}
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
797
|
+
} else if (ch === 0x2b) {
|
798
|
+
sign = 1;
|
799
|
+
ch = this.nextChar();
|
800
|
+
}
|
801
|
+
|
802
|
+
if (ch === 0x0a || ch === 0x0d) {
|
803
|
+
do {
|
633
804
|
ch = this.nextChar();
|
805
|
+
} while (ch === 0x0a || ch === 0x0d);
|
806
|
+
}
|
807
|
+
|
808
|
+
if (ch === 0x2e) {
|
809
|
+
divideBy = 10;
|
810
|
+
ch = this.nextChar();
|
811
|
+
}
|
812
|
+
|
813
|
+
if (ch < 0x30 || ch > 0x39) {
|
814
|
+
if (divideBy === 10 && sign === 0 && ((0, _core_utils.isWhiteSpace)(ch) || ch === -1)) {
|
815
|
+
(0, _util.warn)("Lexer.getNumber - treating a single decimal point as zero.");
|
816
|
+
return 0;
|
634
817
|
}
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
divideBy *= 10;
|
654
|
-
}
|
655
|
-
baseValue = baseValue * 10 + currentDigit;
|
656
|
-
}
|
657
|
-
} else if (ch === 0x2E) {
|
658
|
-
if (divideBy === 0) {
|
659
|
-
divideBy = 1;
|
660
|
-
} else {
|
661
|
-
break;
|
662
|
-
}
|
663
|
-
} else if (ch === 0x2D) {
|
664
|
-
(0, _util.warn)('Badly formatted number');
|
665
|
-
} else if (ch === 0x45 || ch === 0x65) {
|
666
|
-
ch = this.peekChar();
|
667
|
-
if (ch === 0x2B || ch === 0x2D) {
|
668
|
-
powerValueSign = ch === 0x2D ? -1 : 1;
|
669
|
-
this.nextChar();
|
670
|
-
} else if (ch < 0x30 || ch > 0x39) {
|
671
|
-
break;
|
818
|
+
|
819
|
+
throw new _util.FormatError(`Invalid number: ${String.fromCharCode(ch)} (charCode ${ch})`);
|
820
|
+
}
|
821
|
+
|
822
|
+
sign = sign || 1;
|
823
|
+
let baseValue = ch - 0x30;
|
824
|
+
let powerValue = 0;
|
825
|
+
let powerValueSign = 1;
|
826
|
+
|
827
|
+
while ((ch = this.nextChar()) >= 0) {
|
828
|
+
if (ch >= 0x30 && ch <= 0x39) {
|
829
|
+
const currentDigit = ch - 0x30;
|
830
|
+
|
831
|
+
if (eNotation) {
|
832
|
+
powerValue = powerValue * 10 + currentDigit;
|
833
|
+
} else {
|
834
|
+
if (divideBy !== 0) {
|
835
|
+
divideBy *= 10;
|
672
836
|
}
|
673
|
-
|
837
|
+
|
838
|
+
baseValue = baseValue * 10 + currentDigit;
|
839
|
+
}
|
840
|
+
} else if (ch === 0x2e) {
|
841
|
+
if (divideBy === 0) {
|
842
|
+
divideBy = 1;
|
674
843
|
} else {
|
675
844
|
break;
|
676
845
|
}
|
846
|
+
} else if (ch === 0x2d) {
|
847
|
+
(0, _util.warn)("Badly formatted number: minus sign in the middle");
|
848
|
+
} else if (ch === 0x45 || ch === 0x65) {
|
849
|
+
ch = this.peekChar();
|
850
|
+
|
851
|
+
if (ch === 0x2b || ch === 0x2d) {
|
852
|
+
powerValueSign = ch === 0x2d ? -1 : 1;
|
853
|
+
this.nextChar();
|
854
|
+
} else if (ch < 0x30 || ch > 0x39) {
|
855
|
+
break;
|
856
|
+
}
|
857
|
+
|
858
|
+
eNotation = true;
|
859
|
+
} else {
|
860
|
+
break;
|
677
861
|
}
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
862
|
+
}
|
863
|
+
|
864
|
+
if (divideBy !== 0) {
|
865
|
+
baseValue /= divideBy;
|
866
|
+
}
|
867
|
+
|
868
|
+
if (eNotation) {
|
869
|
+
baseValue *= 10 ** (powerValueSign * powerValue);
|
870
|
+
}
|
871
|
+
|
872
|
+
return sign * baseValue;
|
873
|
+
}
|
874
|
+
|
875
|
+
getString() {
|
876
|
+
let numParen = 1;
|
877
|
+
let done = false;
|
878
|
+
const strBuf = this.strBuf;
|
879
|
+
strBuf.length = 0;
|
880
|
+
let ch = this.nextChar();
|
881
|
+
|
882
|
+
while (true) {
|
883
|
+
let charBuffered = false;
|
884
|
+
|
885
|
+
switch (ch | 0) {
|
886
|
+
case -1:
|
887
|
+
(0, _util.warn)("Unterminated string");
|
888
|
+
done = true;
|
889
|
+
break;
|
890
|
+
|
891
|
+
case 0x28:
|
892
|
+
++numParen;
|
893
|
+
strBuf.push("(");
|
894
|
+
break;
|
895
|
+
|
896
|
+
case 0x29:
|
897
|
+
if (--numParen === 0) {
|
898
|
+
this.nextChar();
|
697
899
|
done = true;
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
900
|
+
} else {
|
901
|
+
strBuf.push(")");
|
902
|
+
}
|
903
|
+
|
904
|
+
break;
|
905
|
+
|
906
|
+
case 0x5c:
|
907
|
+
ch = this.nextChar();
|
908
|
+
|
909
|
+
switch (ch) {
|
910
|
+
case -1:
|
911
|
+
(0, _util.warn)("Unterminated string");
|
706
912
|
done = true;
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
913
|
+
break;
|
914
|
+
|
915
|
+
case 0x6e:
|
916
|
+
strBuf.push("\n");
|
917
|
+
break;
|
918
|
+
|
919
|
+
case 0x72:
|
920
|
+
strBuf.push("\r");
|
921
|
+
break;
|
922
|
+
|
923
|
+
case 0x74:
|
924
|
+
strBuf.push("\t");
|
925
|
+
break;
|
926
|
+
|
927
|
+
case 0x62:
|
928
|
+
strBuf.push("\b");
|
929
|
+
break;
|
930
|
+
|
931
|
+
case 0x66:
|
932
|
+
strBuf.push("\f");
|
933
|
+
break;
|
934
|
+
|
935
|
+
case 0x5c:
|
936
|
+
case 0x28:
|
937
|
+
case 0x29:
|
938
|
+
strBuf.push(String.fromCharCode(ch));
|
939
|
+
break;
|
940
|
+
|
941
|
+
case 0x30:
|
942
|
+
case 0x31:
|
943
|
+
case 0x32:
|
944
|
+
case 0x33:
|
945
|
+
case 0x34:
|
946
|
+
case 0x35:
|
947
|
+
case 0x36:
|
948
|
+
case 0x37:
|
949
|
+
let x = ch & 0x0f;
|
950
|
+
ch = this.nextChar();
|
951
|
+
charBuffered = true;
|
952
|
+
|
953
|
+
if (ch >= 0x30 && ch <= 0x37) {
|
954
|
+
x = (x << 3) + (ch & 0x0f);
|
747
955
|
ch = this.nextChar();
|
748
|
-
|
956
|
+
|
749
957
|
if (ch >= 0x30 && ch <= 0x37) {
|
750
|
-
|
751
|
-
|
752
|
-
if (ch >= 0x30 && ch <= 0x37) {
|
753
|
-
charBuffered = false;
|
754
|
-
x = (x << 3) + (ch & 0x0F);
|
755
|
-
}
|
756
|
-
}
|
757
|
-
strBuf.push(String.fromCharCode(x));
|
758
|
-
break;
|
759
|
-
case 0x0D:
|
760
|
-
if (this.peekChar() === 0x0A) {
|
761
|
-
this.nextChar();
|
958
|
+
charBuffered = false;
|
959
|
+
x = (x << 3) + (ch & 0x0f);
|
762
960
|
}
|
763
|
-
break;
|
764
|
-
case 0x0A:
|
765
|
-
break;
|
766
|
-
default:
|
767
|
-
strBuf.push(String.fromCharCode(ch));
|
768
|
-
break;
|
769
|
-
}
|
770
|
-
break;
|
771
|
-
default:
|
772
|
-
strBuf.push(String.fromCharCode(ch));
|
773
|
-
break;
|
774
|
-
}
|
775
|
-
if (done) {
|
776
|
-
break;
|
777
|
-
}
|
778
|
-
if (!charBuffered) {
|
779
|
-
ch = this.nextChar();
|
780
|
-
}
|
781
|
-
}
|
782
|
-
return strBuf.join('');
|
783
|
-
},
|
784
|
-
getName: function Lexer_getName() {
|
785
|
-
var ch, previousCh;
|
786
|
-
var strBuf = this.strBuf;
|
787
|
-
strBuf.length = 0;
|
788
|
-
while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) {
|
789
|
-
if (ch === 0x23) {
|
790
|
-
ch = this.nextChar();
|
791
|
-
if (specialChars[ch]) {
|
792
|
-
(0, _util.warn)('Lexer_getName: ' + 'NUMBER SIGN (#) should be followed by a hexadecimal number.');
|
793
|
-
strBuf.push('#');
|
794
|
-
break;
|
795
|
-
}
|
796
|
-
var x = toHexDigit(ch);
|
797
|
-
if (x !== -1) {
|
798
|
-
previousCh = ch;
|
799
|
-
ch = this.nextChar();
|
800
|
-
var x2 = toHexDigit(ch);
|
801
|
-
if (x2 === -1) {
|
802
|
-
(0, _util.warn)('Lexer_getName: Illegal digit (' + String.fromCharCode(ch) + ') in hexadecimal number.');
|
803
|
-
strBuf.push('#', String.fromCharCode(previousCh));
|
804
|
-
if (specialChars[ch]) {
|
805
|
-
break;
|
806
961
|
}
|
962
|
+
|
963
|
+
strBuf.push(String.fromCharCode(x));
|
964
|
+
break;
|
965
|
+
|
966
|
+
case 0x0d:
|
967
|
+
if (this.peekChar() === 0x0a) {
|
968
|
+
this.nextChar();
|
969
|
+
}
|
970
|
+
|
971
|
+
break;
|
972
|
+
|
973
|
+
case 0x0a:
|
974
|
+
break;
|
975
|
+
|
976
|
+
default:
|
807
977
|
strBuf.push(String.fromCharCode(ch));
|
808
|
-
|
809
|
-
}
|
810
|
-
strBuf.push(String.fromCharCode(x << 4 | x2));
|
811
|
-
} else {
|
812
|
-
strBuf.push('#', String.fromCharCode(ch));
|
978
|
+
break;
|
813
979
|
}
|
814
|
-
|
980
|
+
|
981
|
+
break;
|
982
|
+
|
983
|
+
default:
|
815
984
|
strBuf.push(String.fromCharCode(ch));
|
816
|
-
|
985
|
+
break;
|
817
986
|
}
|
818
|
-
|
819
|
-
|
987
|
+
|
988
|
+
if (done) {
|
989
|
+
break;
|
820
990
|
}
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
991
|
+
|
992
|
+
if (!charBuffered) {
|
993
|
+
ch = this.nextChar();
|
994
|
+
}
|
995
|
+
}
|
996
|
+
|
997
|
+
return strBuf.join("");
|
998
|
+
}
|
999
|
+
|
1000
|
+
getName() {
|
1001
|
+
let ch, previousCh;
|
1002
|
+
const strBuf = this.strBuf;
|
1003
|
+
strBuf.length = 0;
|
1004
|
+
|
1005
|
+
while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) {
|
1006
|
+
if (ch === 0x23) {
|
1007
|
+
ch = this.nextChar();
|
1008
|
+
|
1009
|
+
if (specialChars[ch]) {
|
1010
|
+
(0, _util.warn)("Lexer_getName: " + "NUMBER SIGN (#) should be followed by a hexadecimal number.");
|
1011
|
+
strBuf.push("#");
|
836
1012
|
break;
|
837
|
-
}
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
const x = toHexDigit(ch);
|
1016
|
+
|
1017
|
+
if (x !== -1) {
|
1018
|
+
previousCh = ch;
|
838
1019
|
ch = this.nextChar();
|
839
|
-
|
840
|
-
|
841
|
-
if (
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
}
|
848
|
-
} else {
|
849
|
-
secondDigit = toHexDigit(ch);
|
850
|
-
if (secondDigit === -1) {
|
851
|
-
(0, _util.warn)('Ignoring invalid character "' + ch + '" in hex string');
|
852
|
-
ch = this.nextChar();
|
853
|
-
continue;
|
1020
|
+
const x2 = toHexDigit(ch);
|
1021
|
+
|
1022
|
+
if (x2 === -1) {
|
1023
|
+
(0, _util.warn)(`Lexer_getName: Illegal digit (${String.fromCharCode(ch)}) ` + "in hexadecimal number.");
|
1024
|
+
strBuf.push("#", String.fromCharCode(previousCh));
|
1025
|
+
|
1026
|
+
if (specialChars[ch]) {
|
1027
|
+
break;
|
854
1028
|
}
|
855
|
-
|
1029
|
+
|
1030
|
+
strBuf.push(String.fromCharCode(ch));
|
1031
|
+
continue;
|
856
1032
|
}
|
857
|
-
|
858
|
-
|
1033
|
+
|
1034
|
+
strBuf.push(String.fromCharCode(x << 4 | x2));
|
1035
|
+
} else {
|
1036
|
+
strBuf.push("#", String.fromCharCode(ch));
|
859
1037
|
}
|
1038
|
+
} else {
|
1039
|
+
strBuf.push(String.fromCharCode(ch));
|
860
1040
|
}
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
1041
|
+
}
|
1042
|
+
|
1043
|
+
if (strBuf.length > 127) {
|
1044
|
+
(0, _util.warn)(`Name token is longer than allowed by the spec: ${strBuf.length}`);
|
1045
|
+
}
|
1046
|
+
|
1047
|
+
return _primitives.Name.get(strBuf.join(""));
|
1048
|
+
}
|
1049
|
+
|
1050
|
+
_hexStringWarn(ch) {
|
1051
|
+
const MAX_HEX_STRING_NUM_WARN = 5;
|
1052
|
+
|
1053
|
+
if (this._hexStringNumWarn++ === MAX_HEX_STRING_NUM_WARN) {
|
1054
|
+
(0, _util.warn)("getHexString - ignoring additional invalid characters.");
|
1055
|
+
return;
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
if (this._hexStringNumWarn > MAX_HEX_STRING_NUM_WARN) {
|
1059
|
+
return;
|
1060
|
+
}
|
1061
|
+
|
1062
|
+
(0, _util.warn)(`getHexString - ignoring invalid character: ${ch}`);
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
getHexString() {
|
1066
|
+
const strBuf = this.strBuf;
|
1067
|
+
strBuf.length = 0;
|
1068
|
+
let ch = this.currentChar;
|
1069
|
+
let isFirstHex = true;
|
1070
|
+
let firstDigit, secondDigit;
|
1071
|
+
this._hexStringNumWarn = 0;
|
1072
|
+
|
1073
|
+
while (true) {
|
1074
|
+
if (ch < 0) {
|
1075
|
+
(0, _util.warn)("Unterminated hex string");
|
1076
|
+
break;
|
1077
|
+
} else if (ch === 0x3e) {
|
1078
|
+
this.nextChar();
|
1079
|
+
break;
|
1080
|
+
} else if (specialChars[ch] === 1) {
|
879
1081
|
ch = this.nextChar();
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
case 0x38:
|
891
|
-
case 0x39:
|
892
|
-
case 0x2B:
|
893
|
-
case 0x2D:
|
894
|
-
case 0x2E:
|
895
|
-
return this.getNumber();
|
896
|
-
case 0x28:
|
897
|
-
return this.getString();
|
898
|
-
case 0x2F:
|
899
|
-
return this.getName();
|
900
|
-
case 0x5B:
|
901
|
-
this.nextChar();
|
902
|
-
return _primitives.Cmd.get('[');
|
903
|
-
case 0x5D:
|
904
|
-
this.nextChar();
|
905
|
-
return _primitives.Cmd.get(']');
|
906
|
-
case 0x3C:
|
907
|
-
ch = this.nextChar();
|
908
|
-
if (ch === 0x3C) {
|
909
|
-
this.nextChar();
|
910
|
-
return _primitives.Cmd.get('<<');
|
1082
|
+
continue;
|
1083
|
+
} else {
|
1084
|
+
if (isFirstHex) {
|
1085
|
+
firstDigit = toHexDigit(ch);
|
1086
|
+
|
1087
|
+
if (firstDigit === -1) {
|
1088
|
+
this._hexStringWarn(ch);
|
1089
|
+
|
1090
|
+
ch = this.nextChar();
|
1091
|
+
continue;
|
911
1092
|
}
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
if (
|
916
|
-
this.
|
917
|
-
|
1093
|
+
} else {
|
1094
|
+
secondDigit = toHexDigit(ch);
|
1095
|
+
|
1096
|
+
if (secondDigit === -1) {
|
1097
|
+
this._hexStringWarn(ch);
|
1098
|
+
|
1099
|
+
ch = this.nextChar();
|
1100
|
+
continue;
|
918
1101
|
}
|
919
|
-
|
920
|
-
|
921
|
-
this.nextChar();
|
922
|
-
return _primitives.Cmd.get('{');
|
923
|
-
case 0x7D:
|
924
|
-
this.nextChar();
|
925
|
-
return _primitives.Cmd.get('}');
|
926
|
-
case 0x29:
|
927
|
-
this.nextChar();
|
928
|
-
throw new _util.FormatError('Illegal character: ' + ch);
|
929
|
-
}
|
930
|
-
var str = String.fromCharCode(ch);
|
931
|
-
var knownCommands = this.knownCommands;
|
932
|
-
var knownCommandFound = knownCommands && knownCommands[str] !== undefined;
|
933
|
-
while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) {
|
934
|
-
var possibleCommand = str + String.fromCharCode(ch);
|
935
|
-
if (knownCommandFound && knownCommands[possibleCommand] === undefined) {
|
936
|
-
break;
|
937
|
-
}
|
938
|
-
if (str.length === 128) {
|
939
|
-
throw new _util.FormatError('Command token too long: ' + str.length);
|
1102
|
+
|
1103
|
+
strBuf.push(String.fromCharCode(firstDigit << 4 | secondDigit));
|
940
1104
|
}
|
941
|
-
|
942
|
-
|
1105
|
+
|
1106
|
+
isFirstHex = !isFirstHex;
|
1107
|
+
ch = this.nextChar();
|
943
1108
|
}
|
944
|
-
|
945
|
-
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
return strBuf.join("");
|
1112
|
+
}
|
1113
|
+
|
1114
|
+
getObj() {
|
1115
|
+
let comment = false;
|
1116
|
+
let ch = this.currentChar;
|
1117
|
+
|
1118
|
+
while (true) {
|
1119
|
+
if (ch < 0) {
|
1120
|
+
return _primitives.EOF;
|
946
1121
|
}
|
947
|
-
|
948
|
-
|
1122
|
+
|
1123
|
+
if (comment) {
|
1124
|
+
if (ch === 0x0a || ch === 0x0d) {
|
1125
|
+
comment = false;
|
1126
|
+
}
|
1127
|
+
} else if (ch === 0x25) {
|
1128
|
+
comment = true;
|
1129
|
+
} else if (specialChars[ch] !== 1) {
|
1130
|
+
break;
|
949
1131
|
}
|
950
|
-
|
951
|
-
|
1132
|
+
|
1133
|
+
ch = this.nextChar();
|
1134
|
+
}
|
1135
|
+
|
1136
|
+
switch (ch | 0) {
|
1137
|
+
case 0x30:
|
1138
|
+
case 0x31:
|
1139
|
+
case 0x32:
|
1140
|
+
case 0x33:
|
1141
|
+
case 0x34:
|
1142
|
+
case 0x35:
|
1143
|
+
case 0x36:
|
1144
|
+
case 0x37:
|
1145
|
+
case 0x38:
|
1146
|
+
case 0x39:
|
1147
|
+
case 0x2b:
|
1148
|
+
case 0x2d:
|
1149
|
+
case 0x2e:
|
1150
|
+
return this.getNumber();
|
1151
|
+
|
1152
|
+
case 0x28:
|
1153
|
+
return this.getString();
|
1154
|
+
|
1155
|
+
case 0x2f:
|
1156
|
+
return this.getName();
|
1157
|
+
|
1158
|
+
case 0x5b:
|
1159
|
+
this.nextChar();
|
1160
|
+
return _primitives.Cmd.get("[");
|
1161
|
+
|
1162
|
+
case 0x5d:
|
1163
|
+
this.nextChar();
|
1164
|
+
return _primitives.Cmd.get("]");
|
1165
|
+
|
1166
|
+
case 0x3c:
|
1167
|
+
ch = this.nextChar();
|
1168
|
+
|
1169
|
+
if (ch === 0x3c) {
|
1170
|
+
this.nextChar();
|
1171
|
+
return _primitives.Cmd.get("<<");
|
1172
|
+
}
|
1173
|
+
|
1174
|
+
return this.getHexString();
|
1175
|
+
|
1176
|
+
case 0x3e:
|
1177
|
+
ch = this.nextChar();
|
1178
|
+
|
1179
|
+
if (ch === 0x3e) {
|
1180
|
+
this.nextChar();
|
1181
|
+
return _primitives.Cmd.get(">>");
|
1182
|
+
}
|
1183
|
+
|
1184
|
+
return _primitives.Cmd.get(">");
|
1185
|
+
|
1186
|
+
case 0x7b:
|
1187
|
+
this.nextChar();
|
1188
|
+
return _primitives.Cmd.get("{");
|
1189
|
+
|
1190
|
+
case 0x7d:
|
1191
|
+
this.nextChar();
|
1192
|
+
return _primitives.Cmd.get("}");
|
1193
|
+
|
1194
|
+
case 0x29:
|
1195
|
+
this.nextChar();
|
1196
|
+
throw new _util.FormatError(`Illegal character: ${ch}`);
|
1197
|
+
}
|
1198
|
+
|
1199
|
+
let str = String.fromCharCode(ch);
|
1200
|
+
const knownCommands = this.knownCommands;
|
1201
|
+
let knownCommandFound = knownCommands && knownCommands[str] !== undefined;
|
1202
|
+
|
1203
|
+
while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) {
|
1204
|
+
const possibleCommand = str + String.fromCharCode(ch);
|
1205
|
+
|
1206
|
+
if (knownCommandFound && knownCommands[possibleCommand] === undefined) {
|
1207
|
+
break;
|
952
1208
|
}
|
953
|
-
|
954
|
-
|
1209
|
+
|
1210
|
+
if (str.length === 128) {
|
1211
|
+
throw new _util.FormatError(`Command token too long: ${str.length}`);
|
955
1212
|
}
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
1213
|
+
|
1214
|
+
str = possibleCommand;
|
1215
|
+
knownCommandFound = knownCommands && knownCommands[str] !== undefined;
|
1216
|
+
}
|
1217
|
+
|
1218
|
+
if (str === "true") {
|
1219
|
+
return true;
|
1220
|
+
}
|
1221
|
+
|
1222
|
+
if (str === "false") {
|
1223
|
+
return false;
|
1224
|
+
}
|
1225
|
+
|
1226
|
+
if (str === "null") {
|
1227
|
+
return null;
|
1228
|
+
}
|
1229
|
+
|
1230
|
+
if (str === "BI") {
|
1231
|
+
this.beginInlineImagePos = this.stream.pos;
|
1232
|
+
}
|
1233
|
+
|
1234
|
+
return _primitives.Cmd.get(str);
|
1235
|
+
}
|
1236
|
+
|
1237
|
+
skipToNextLine() {
|
1238
|
+
let ch = this.currentChar;
|
1239
|
+
|
1240
|
+
while (ch >= 0) {
|
1241
|
+
if (ch === 0x0d) {
|
1242
|
+
ch = this.nextChar();
|
1243
|
+
|
1244
|
+
if (ch === 0x0a) {
|
968
1245
|
this.nextChar();
|
969
|
-
break;
|
970
1246
|
}
|
971
|
-
|
1247
|
+
|
1248
|
+
break;
|
1249
|
+
} else if (ch === 0x0a) {
|
1250
|
+
this.nextChar();
|
1251
|
+
break;
|
972
1252
|
}
|
1253
|
+
|
1254
|
+
ch = this.nextChar();
|
973
1255
|
}
|
974
|
-
}
|
975
|
-
|
976
|
-
}
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
1256
|
+
}
|
1257
|
+
|
1258
|
+
}
|
1259
|
+
|
1260
|
+
exports.Lexer = Lexer;
|
1261
|
+
|
1262
|
+
class Linearization {
|
1263
|
+
static create(stream) {
|
1264
|
+
function getInt(linDict, name, allowZeroValue = false) {
|
1265
|
+
const obj = linDict.get(name);
|
1266
|
+
|
981
1267
|
if (Number.isInteger(obj) && (allowZeroValue ? obj >= 0 : obj > 0)) {
|
982
1268
|
return obj;
|
983
1269
|
}
|
984
|
-
|
1270
|
+
|
1271
|
+
throw new Error(`The "${name}" parameter in the linearization ` + "dictionary is invalid.");
|
985
1272
|
}
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
1273
|
+
|
1274
|
+
function getHints(linDict) {
|
1275
|
+
const hints = linDict.get("H");
|
1276
|
+
let hintsLength;
|
1277
|
+
|
990
1278
|
if (Array.isArray(hints) && ((hintsLength = hints.length) === 2 || hintsLength === 4)) {
|
991
|
-
for (
|
992
|
-
|
993
|
-
|
1279
|
+
for (let index = 0; index < hintsLength; index++) {
|
1280
|
+
const hint = hints[index];
|
1281
|
+
|
1282
|
+
if (!(Number.isInteger(hint) && hint > 0)) {
|
1283
|
+
throw new Error(`Hint (${index}) in the linearization dictionary is invalid.`);
|
994
1284
|
}
|
995
1285
|
}
|
1286
|
+
|
996
1287
|
return hints;
|
997
1288
|
}
|
998
|
-
|
1289
|
+
|
1290
|
+
throw new Error("Hint array in the linearization dictionary is invalid.");
|
999
1291
|
}
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1292
|
+
|
1293
|
+
const parser = new Parser({
|
1294
|
+
lexer: new Lexer(stream),
|
1295
|
+
xref: null
|
1296
|
+
});
|
1297
|
+
const obj1 = parser.getObj();
|
1298
|
+
const obj2 = parser.getObj();
|
1299
|
+
const obj3 = parser.getObj();
|
1300
|
+
const linDict = parser.getObj();
|
1301
|
+
let obj, length;
|
1302
|
+
|
1303
|
+
if (!(Number.isInteger(obj1) && Number.isInteger(obj2) && (0, _primitives.isCmd)(obj3, "obj") && (0, _primitives.isDict)(linDict) && (0, _util.isNum)(obj = linDict.get("Linearized")) && obj > 0)) {
|
1007
1304
|
return null;
|
1008
|
-
} else if ((length = getInt(
|
1009
|
-
throw new Error('The "L" parameter in the linearization dictionary ' +
|
1305
|
+
} else if ((length = getInt(linDict, "L")) !== stream.length) {
|
1306
|
+
throw new Error('The "L" parameter in the linearization dictionary ' + "does not equal the stream length.");
|
1010
1307
|
}
|
1308
|
+
|
1011
1309
|
return {
|
1012
|
-
length
|
1013
|
-
hints: getHints(),
|
1014
|
-
objectNumberFirst: getInt(
|
1015
|
-
endFirst: getInt(
|
1016
|
-
numPages: getInt(
|
1017
|
-
mainXRefEntriesOffset: getInt(
|
1018
|
-
pageFirst: linDict.has(
|
1310
|
+
length,
|
1311
|
+
hints: getHints(linDict),
|
1312
|
+
objectNumberFirst: getInt(linDict, "O"),
|
1313
|
+
endFirst: getInt(linDict, "E"),
|
1314
|
+
numPages: getInt(linDict, "N"),
|
1315
|
+
mainXRefEntriesOffset: getInt(linDict, "T"),
|
1316
|
+
pageFirst: linDict.has("P") ? getInt(linDict, "P", true) : 0
|
1019
1317
|
};
|
1020
1318
|
}
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
exports.
|
1319
|
+
|
1320
|
+
}
|
1321
|
+
|
1322
|
+
exports.Linearization = Linearization;
|