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