parser.js 34 KB

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