2
0

parser.js 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * Javascript code in this page
  4. *
  5. * Copyright 2018 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 _stream = require("./stream");
  28. var _util = require("../shared/util");
  29. var _primitives = require("./primitives");
  30. var _ccitt_stream = require("./ccitt_stream");
  31. var _jbig2_stream = require("./jbig2_stream");
  32. var _jpeg_stream = require("./jpeg_stream");
  33. var _jpx_stream = require("./jpx_stream");
  34. var MAX_LENGTH_TO_CACHE = 1000;
  35. var MAX_ADLER32_LENGTH = 5552;
  36. function computeAdler32(bytes) {
  37. var bytesLength = bytes.length;
  38. var a = 1,
  39. b = 0;
  40. for (var i = 0; i < bytesLength; ++i) {
  41. a += bytes[i] & 0xFF;
  42. b += a;
  43. }
  44. return b % 65521 << 16 | a % 65521;
  45. }
  46. var Parser = function ParserClosure() {
  47. function Parser(lexer, allowStreams, xref, recoveryMode) {
  48. this.lexer = lexer;
  49. this.allowStreams = allowStreams;
  50. this.xref = xref;
  51. this.recoveryMode = recoveryMode || false;
  52. this.imageCache = Object.create(null);
  53. this.refill();
  54. }
  55. Parser.prototype = {
  56. refill: function Parser_refill() {
  57. this.buf1 = this.lexer.getObj();
  58. this.buf2 = this.lexer.getObj();
  59. },
  60. shift: function Parser_shift() {
  61. if ((0, _primitives.isCmd)(this.buf2, 'ID')) {
  62. this.buf1 = this.buf2;
  63. this.buf2 = null;
  64. } else {
  65. this.buf1 = this.buf2;
  66. this.buf2 = this.lexer.getObj();
  67. }
  68. },
  69. tryShift: function Parser_tryShift() {
  70. try {
  71. this.shift();
  72. return true;
  73. } catch (e) {
  74. if (e instanceof _util.MissingDataException) {
  75. throw e;
  76. }
  77. return false;
  78. }
  79. },
  80. getObj: function Parser_getObj(cipherTransform) {
  81. var buf1 = this.buf1;
  82. this.shift();
  83. if (buf1 instanceof _primitives.Cmd) {
  84. switch (buf1.cmd) {
  85. case 'BI':
  86. return this.makeInlineImage(cipherTransform);
  87. case '[':
  88. var array = [];
  89. while (!(0, _primitives.isCmd)(this.buf1, ']') && !(0, _primitives.isEOF)(this.buf1)) {
  90. array.push(this.getObj(cipherTransform));
  91. }
  92. if ((0, _primitives.isEOF)(this.buf1)) {
  93. if (!this.recoveryMode) {
  94. throw new _util.FormatError('End of file inside array');
  95. }
  96. return array;
  97. }
  98. this.shift();
  99. return array;
  100. case '<<':
  101. var dict = new _primitives.Dict(this.xref);
  102. while (!(0, _primitives.isCmd)(this.buf1, '>>') && !(0, _primitives.isEOF)(this.buf1)) {
  103. if (!(0, _primitives.isName)(this.buf1)) {
  104. (0, _util.info)('Malformed dictionary: key must be a name object');
  105. this.shift();
  106. continue;
  107. }
  108. var key = this.buf1.name;
  109. this.shift();
  110. if ((0, _primitives.isEOF)(this.buf1)) {
  111. break;
  112. }
  113. dict.set(key, this.getObj(cipherTransform));
  114. }
  115. if ((0, _primitives.isEOF)(this.buf1)) {
  116. if (!this.recoveryMode) {
  117. throw new _util.FormatError('End of file inside dictionary');
  118. }
  119. return dict;
  120. }
  121. if ((0, _primitives.isCmd)(this.buf2, 'stream')) {
  122. return this.allowStreams ? this.makeStream(dict, cipherTransform) : dict;
  123. }
  124. this.shift();
  125. return dict;
  126. default:
  127. return buf1;
  128. }
  129. }
  130. if (Number.isInteger(buf1)) {
  131. var num = buf1;
  132. if (Number.isInteger(this.buf1) && (0, _primitives.isCmd)(this.buf2, 'R')) {
  133. var ref = new _primitives.Ref(num, this.buf1);
  134. this.shift();
  135. this.shift();
  136. return ref;
  137. }
  138. return num;
  139. }
  140. if ((0, _util.isString)(buf1)) {
  141. var str = buf1;
  142. if (cipherTransform) {
  143. str = cipherTransform.decryptString(str);
  144. }
  145. return str;
  146. }
  147. return buf1;
  148. },
  149. findDefaultInlineStreamEnd: function findDefaultInlineStreamEnd(stream) {
  150. var E = 0x45,
  151. I = 0x49,
  152. SPACE = 0x20,
  153. LF = 0xA,
  154. CR = 0xD;
  155. var n = 10,
  156. NUL = 0x0;
  157. var startPos = stream.pos,
  158. state = 0,
  159. ch,
  160. maybeEIPos;
  161. while ((ch = stream.getByte()) !== -1) {
  162. if (state === 0) {
  163. state = ch === E ? 1 : 0;
  164. } else if (state === 1) {
  165. state = ch === I ? 2 : 0;
  166. } else {
  167. (0, _util.assert)(state === 2);
  168. if (ch === SPACE || ch === LF || ch === CR) {
  169. maybeEIPos = stream.pos;
  170. var followingBytes = stream.peekBytes(n);
  171. for (var i = 0, ii = followingBytes.length; i < ii; i++) {
  172. ch = followingBytes[i];
  173. if (ch === NUL && followingBytes[i + 1] !== NUL) {
  174. continue;
  175. }
  176. if (ch !== LF && ch !== CR && (ch < SPACE || ch > 0x7F)) {
  177. state = 0;
  178. break;
  179. }
  180. }
  181. if (state === 2) {
  182. break;
  183. }
  184. } else {
  185. state = 0;
  186. }
  187. }
  188. }
  189. if (ch === -1) {
  190. (0, _util.warn)('findDefaultInlineStreamEnd: ' + 'Reached the end of the stream without finding a valid EI marker');
  191. if (maybeEIPos) {
  192. (0, _util.warn)('... trying to recover by using the last "EI" occurrence.');
  193. stream.skip(-(stream.pos - maybeEIPos));
  194. }
  195. }
  196. var endOffset = 4;
  197. stream.skip(-endOffset);
  198. ch = stream.peekByte();
  199. stream.skip(endOffset);
  200. if (!(0, _util.isSpace)(ch)) {
  201. endOffset--;
  202. }
  203. return stream.pos - endOffset - startPos;
  204. },
  205. findDCTDecodeInlineStreamEnd: function Parser_findDCTDecodeInlineStreamEnd(stream) {
  206. var startPos = stream.pos,
  207. foundEOI = false,
  208. b,
  209. markerLength,
  210. length;
  211. while ((b = stream.getByte()) !== -1) {
  212. if (b !== 0xFF) {
  213. continue;
  214. }
  215. switch (stream.getByte()) {
  216. case 0x00:
  217. break;
  218. case 0xFF:
  219. stream.skip(-1);
  220. break;
  221. case 0xD9:
  222. foundEOI = true;
  223. break;
  224. case 0xC0:
  225. case 0xC1:
  226. case 0xC2:
  227. case 0xC3:
  228. case 0xC5:
  229. case 0xC6:
  230. case 0xC7:
  231. case 0xC9:
  232. case 0xCA:
  233. case 0xCB:
  234. case 0xCD:
  235. case 0xCE:
  236. case 0xCF:
  237. case 0xC4:
  238. case 0xCC:
  239. case 0xDA:
  240. case 0xDB:
  241. case 0xDC:
  242. case 0xDD:
  243. case 0xDE:
  244. case 0xDF:
  245. case 0xE0:
  246. case 0xE1:
  247. case 0xE2:
  248. case 0xE3:
  249. case 0xE4:
  250. case 0xE5:
  251. case 0xE6:
  252. case 0xE7:
  253. case 0xE8:
  254. case 0xE9:
  255. case 0xEA:
  256. case 0xEB:
  257. case 0xEC:
  258. case 0xED:
  259. case 0xEE:
  260. case 0xEF:
  261. case 0xFE:
  262. markerLength = stream.getUint16();
  263. if (markerLength > 2) {
  264. stream.skip(markerLength - 2);
  265. } else {
  266. stream.skip(-2);
  267. }
  268. break;
  269. }
  270. if (foundEOI) {
  271. break;
  272. }
  273. }
  274. length = stream.pos - startPos;
  275. if (b === -1) {
  276. (0, _util.warn)('Inline DCTDecode image stream: ' + 'EOI marker not found, searching for /EI/ instead.');
  277. stream.skip(-length);
  278. return this.findDefaultInlineStreamEnd(stream);
  279. }
  280. this.inlineStreamSkipEI(stream);
  281. return length;
  282. },
  283. findASCII85DecodeInlineStreamEnd: function Parser_findASCII85DecodeInlineStreamEnd(stream) {
  284. var TILDE = 0x7E,
  285. GT = 0x3E;
  286. var startPos = stream.pos,
  287. ch,
  288. length;
  289. while ((ch = stream.getByte()) !== -1) {
  290. if (ch === TILDE && stream.peekByte() === GT) {
  291. stream.skip();
  292. break;
  293. }
  294. }
  295. length = stream.pos - startPos;
  296. if (ch === -1) {
  297. (0, _util.warn)('Inline ASCII85Decode image stream: ' + 'EOD marker not found, searching for /EI/ instead.');
  298. stream.skip(-length);
  299. return this.findDefaultInlineStreamEnd(stream);
  300. }
  301. this.inlineStreamSkipEI(stream);
  302. return length;
  303. },
  304. findASCIIHexDecodeInlineStreamEnd: function Parser_findASCIIHexDecodeInlineStreamEnd(stream) {
  305. var GT = 0x3E;
  306. var startPos = stream.pos,
  307. ch,
  308. length;
  309. while ((ch = stream.getByte()) !== -1) {
  310. if (ch === GT) {
  311. break;
  312. }
  313. }
  314. length = stream.pos - startPos;
  315. if (ch === -1) {
  316. (0, _util.warn)('Inline ASCIIHexDecode image stream: ' + 'EOD marker not found, searching for /EI/ instead.');
  317. stream.skip(-length);
  318. return this.findDefaultInlineStreamEnd(stream);
  319. }
  320. this.inlineStreamSkipEI(stream);
  321. return length;
  322. },
  323. inlineStreamSkipEI: function Parser_inlineStreamSkipEI(stream) {
  324. var E = 0x45,
  325. I = 0x49;
  326. var state = 0,
  327. ch;
  328. while ((ch = stream.getByte()) !== -1) {
  329. if (state === 0) {
  330. state = ch === E ? 1 : 0;
  331. } else if (state === 1) {
  332. state = ch === I ? 2 : 0;
  333. } else if (state === 2) {
  334. break;
  335. }
  336. }
  337. },
  338. makeInlineImage: function Parser_makeInlineImage(cipherTransform) {
  339. var lexer = this.lexer;
  340. var stream = lexer.stream;
  341. var dict = new _primitives.Dict(this.xref),
  342. dictLength;
  343. while (!(0, _primitives.isCmd)(this.buf1, 'ID') && !(0, _primitives.isEOF)(this.buf1)) {
  344. if (!(0, _primitives.isName)(this.buf1)) {
  345. throw new _util.FormatError('Dictionary key must be a name object');
  346. }
  347. var key = this.buf1.name;
  348. this.shift();
  349. if ((0, _primitives.isEOF)(this.buf1)) {
  350. break;
  351. }
  352. dict.set(key, this.getObj(cipherTransform));
  353. }
  354. if (lexer.beginInlineImagePos !== -1) {
  355. dictLength = stream.pos - lexer.beginInlineImagePos;
  356. }
  357. var filter = dict.get('Filter', 'F'),
  358. filterName;
  359. if ((0, _primitives.isName)(filter)) {
  360. filterName = filter.name;
  361. } else if (Array.isArray(filter)) {
  362. var filterZero = this.xref.fetchIfRef(filter[0]);
  363. if ((0, _primitives.isName)(filterZero)) {
  364. filterName = filterZero.name;
  365. }
  366. }
  367. var startPos = stream.pos,
  368. length;
  369. if (filterName === 'DCTDecode' || filterName === 'DCT') {
  370. length = this.findDCTDecodeInlineStreamEnd(stream);
  371. } else if (filterName === 'ASCII85Decode' || filterName === 'A85') {
  372. length = this.findASCII85DecodeInlineStreamEnd(stream);
  373. } else if (filterName === 'ASCIIHexDecode' || filterName === 'AHx') {
  374. length = this.findASCIIHexDecodeInlineStreamEnd(stream);
  375. } else {
  376. length = this.findDefaultInlineStreamEnd(stream);
  377. }
  378. var imageStream = stream.makeSubStream(startPos, length, dict);
  379. var cacheKey;
  380. if (length < MAX_LENGTH_TO_CACHE && dictLength < MAX_ADLER32_LENGTH) {
  381. var imageBytes = imageStream.getBytes();
  382. imageStream.reset();
  383. var initialStreamPos = stream.pos;
  384. stream.pos = lexer.beginInlineImagePos;
  385. var dictBytes = stream.getBytes(dictLength);
  386. stream.pos = initialStreamPos;
  387. cacheKey = computeAdler32(imageBytes) + '_' + computeAdler32(dictBytes);
  388. var cacheEntry = this.imageCache[cacheKey];
  389. if (cacheEntry !== undefined) {
  390. this.buf2 = _primitives.Cmd.get('EI');
  391. this.shift();
  392. cacheEntry.reset();
  393. return cacheEntry;
  394. }
  395. }
  396. if (cipherTransform) {
  397. imageStream = cipherTransform.createStream(imageStream, length);
  398. }
  399. imageStream = this.filter(imageStream, dict, length);
  400. imageStream.dict = dict;
  401. if (cacheKey !== undefined) {
  402. imageStream.cacheKey = 'inline_' + length + '_' + cacheKey;
  403. this.imageCache[cacheKey] = imageStream;
  404. }
  405. this.buf2 = _primitives.Cmd.get('EI');
  406. this.shift();
  407. return imageStream;
  408. },
  409. _findStreamLength: function _findStreamLength(startPos, signature) {
  410. var stream = this.lexer.stream;
  411. stream.pos = startPos;
  412. var SCAN_BLOCK_LENGTH = 2048;
  413. var signatureLength = signature.length;
  414. while (stream.pos < stream.end) {
  415. var scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH);
  416. var scanLength = scanBytes.length - signatureLength;
  417. if (scanLength <= 0) {
  418. break;
  419. }
  420. var pos = 0;
  421. while (pos < scanLength) {
  422. var j = 0;
  423. while (j < signatureLength && scanBytes[pos + j] === signature[j]) {
  424. j++;
  425. }
  426. if (j >= signatureLength) {
  427. stream.pos += pos;
  428. return stream.pos - startPos;
  429. }
  430. pos++;
  431. }
  432. stream.pos += scanLength;
  433. }
  434. return -1;
  435. },
  436. makeStream: function Parser_makeStream(dict, cipherTransform) {
  437. var lexer = this.lexer;
  438. var stream = lexer.stream;
  439. lexer.skipToNextLine();
  440. var startPos = stream.pos - 1;
  441. var length = dict.get('Length');
  442. if (!Number.isInteger(length)) {
  443. (0, _util.info)('Bad ' + length + ' attribute in stream');
  444. length = 0;
  445. }
  446. stream.pos = startPos + length;
  447. lexer.nextChar();
  448. if (this.tryShift() && (0, _primitives.isCmd)(this.buf2, 'endstream')) {
  449. this.shift();
  450. } else {
  451. var ENDSTREAM_SIGNATURE = new Uint8Array([0x65, 0x6E, 0x64, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6D]);
  452. var actualLength = this._findStreamLength(startPos, ENDSTREAM_SIGNATURE);
  453. if (actualLength < 0) {
  454. var MAX_TRUNCATION = 1;
  455. for (var i = 1; i <= MAX_TRUNCATION; i++) {
  456. var end = ENDSTREAM_SIGNATURE.length - i;
  457. var TRUNCATED_SIGNATURE = ENDSTREAM_SIGNATURE.slice(0, end);
  458. var maybeLength = this._findStreamLength(startPos, TRUNCATED_SIGNATURE);
  459. if (maybeLength >= 0) {
  460. var lastByte = stream.peekBytes(end + 1)[end];
  461. if (!(0, _util.isSpace)(lastByte)) {
  462. break;
  463. }
  464. (0, _util.info)("Found \"".concat((0, _util.bytesToString)(TRUNCATED_SIGNATURE), "\" when ") + 'searching for endstream command.');
  465. actualLength = maybeLength;
  466. break;
  467. }
  468. }
  469. if (actualLength < 0) {
  470. throw new _util.FormatError('Missing endstream command.');
  471. }
  472. }
  473. length = actualLength;
  474. lexer.nextChar();
  475. this.shift();
  476. this.shift();
  477. }
  478. this.shift();
  479. stream = stream.makeSubStream(startPos, length, dict);
  480. if (cipherTransform) {
  481. stream = cipherTransform.createStream(stream, length);
  482. }
  483. stream = this.filter(stream, dict, length);
  484. stream.dict = dict;
  485. return stream;
  486. },
  487. filter: function Parser_filter(stream, dict, length) {
  488. var filter = dict.get('Filter', 'F');
  489. var params = dict.get('DecodeParms', 'DP');
  490. if ((0, _primitives.isName)(filter)) {
  491. if (Array.isArray(params)) {
  492. (0, _util.warn)('/DecodeParms should not contain an Array, ' + 'when /Filter contains a Name.');
  493. }
  494. return this.makeFilter(stream, filter.name, length, params);
  495. }
  496. var maybeLength = length;
  497. if (Array.isArray(filter)) {
  498. var filterArray = filter;
  499. var paramsArray = params;
  500. for (var i = 0, ii = filterArray.length; i < ii; ++i) {
  501. filter = this.xref.fetchIfRef(filterArray[i]);
  502. if (!(0, _primitives.isName)(filter)) {
  503. throw new _util.FormatError('Bad filter name: ' + filter);
  504. }
  505. params = null;
  506. if (Array.isArray(paramsArray) && i in paramsArray) {
  507. params = this.xref.fetchIfRef(paramsArray[i]);
  508. }
  509. stream = this.makeFilter(stream, filter.name, maybeLength, params);
  510. maybeLength = null;
  511. }
  512. }
  513. return stream;
  514. },
  515. makeFilter: function Parser_makeFilter(stream, name, maybeLength, params) {
  516. if (maybeLength === 0) {
  517. (0, _util.warn)('Empty "' + name + '" stream.');
  518. return new _stream.NullStream();
  519. }
  520. try {
  521. var xrefStreamStats = this.xref.stats.streamTypes;
  522. if (name === 'FlateDecode' || name === 'Fl') {
  523. xrefStreamStats[_util.StreamType.FLATE] = true;
  524. if (params) {
  525. return new _stream.PredictorStream(new _stream.FlateStream(stream, maybeLength), maybeLength, params);
  526. }
  527. return new _stream.FlateStream(stream, maybeLength);
  528. }
  529. if (name === 'LZWDecode' || name === 'LZW') {
  530. xrefStreamStats[_util.StreamType.LZW] = true;
  531. var earlyChange = 1;
  532. if (params) {
  533. if (params.has('EarlyChange')) {
  534. earlyChange = params.get('EarlyChange');
  535. }
  536. return new _stream.PredictorStream(new _stream.LZWStream(stream, maybeLength, earlyChange), maybeLength, params);
  537. }
  538. return new _stream.LZWStream(stream, maybeLength, earlyChange);
  539. }
  540. if (name === 'DCTDecode' || name === 'DCT') {
  541. xrefStreamStats[_util.StreamType.DCT] = true;
  542. return new _jpeg_stream.JpegStream(stream, maybeLength, stream.dict, params);
  543. }
  544. if (name === 'JPXDecode' || name === 'JPX') {
  545. xrefStreamStats[_util.StreamType.JPX] = true;
  546. return new _jpx_stream.JpxStream(stream, maybeLength, stream.dict, params);
  547. }
  548. if (name === 'ASCII85Decode' || name === 'A85') {
  549. xrefStreamStats[_util.StreamType.A85] = true;
  550. return new _stream.Ascii85Stream(stream, maybeLength);
  551. }
  552. if (name === 'ASCIIHexDecode' || name === 'AHx') {
  553. xrefStreamStats[_util.StreamType.AHX] = true;
  554. return new _stream.AsciiHexStream(stream, maybeLength);
  555. }
  556. if (name === 'CCITTFaxDecode' || name === 'CCF') {
  557. xrefStreamStats[_util.StreamType.CCF] = true;
  558. return new _ccitt_stream.CCITTFaxStream(stream, maybeLength, params);
  559. }
  560. if (name === 'RunLengthDecode' || name === 'RL') {
  561. xrefStreamStats[_util.StreamType.RL] = true;
  562. return new _stream.RunLengthStream(stream, maybeLength);
  563. }
  564. if (name === 'JBIG2Decode') {
  565. xrefStreamStats[_util.StreamType.JBIG] = true;
  566. return new _jbig2_stream.Jbig2Stream(stream, maybeLength, stream.dict, params);
  567. }
  568. (0, _util.warn)('filter "' + name + '" not supported yet');
  569. return stream;
  570. } catch (ex) {
  571. if (ex instanceof _util.MissingDataException) {
  572. throw ex;
  573. }
  574. (0, _util.warn)('Invalid stream: \"' + ex + '\"');
  575. return new _stream.NullStream();
  576. }
  577. }
  578. };
  579. return Parser;
  580. }();
  581. exports.Parser = Parser;
  582. var Lexer = function LexerClosure() {
  583. function Lexer(stream, knownCommands) {
  584. this.stream = stream;
  585. this.nextChar();
  586. this.strBuf = [];
  587. this.knownCommands = knownCommands;
  588. this.beginInlineImagePos = -1;
  589. }
  590. var 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];
  591. function toHexDigit(ch) {
  592. if (ch >= 0x30 && ch <= 0x39) {
  593. return ch & 0x0F;
  594. }
  595. if (ch >= 0x41 && ch <= 0x46 || ch >= 0x61 && ch <= 0x66) {
  596. return (ch & 0x0F) + 9;
  597. }
  598. return -1;
  599. }
  600. Lexer.prototype = {
  601. nextChar: function Lexer_nextChar() {
  602. return this.currentChar = this.stream.getByte();
  603. },
  604. peekChar: function Lexer_peekChar() {
  605. return this.stream.peekByte();
  606. },
  607. getNumber: function Lexer_getNumber() {
  608. var ch = this.currentChar;
  609. var eNotation = false;
  610. var divideBy = 0;
  611. var sign = 0;
  612. if (ch === 0x2D) {
  613. sign = -1;
  614. ch = this.nextChar();
  615. if (ch === 0x2D) {
  616. ch = this.nextChar();
  617. }
  618. } else if (ch === 0x2B) {
  619. sign = 1;
  620. ch = this.nextChar();
  621. }
  622. if (ch === 0x0A || ch === 0x0D) {
  623. do {
  624. ch = this.nextChar();
  625. } while (ch === 0x0A || ch === 0x0D);
  626. }
  627. if (ch === 0x2E) {
  628. divideBy = 10;
  629. ch = this.nextChar();
  630. }
  631. if (ch < 0x30 || ch > 0x39) {
  632. if (divideBy === 10 && sign === 0 && ((0, _util.isSpace)(ch) || ch === -1)) {
  633. (0, _util.warn)('Lexer.getNumber - treating a single decimal point as zero.');
  634. return 0;
  635. }
  636. throw new _util.FormatError("Invalid number: ".concat(String.fromCharCode(ch), " (charCode ").concat(ch, ")"));
  637. }
  638. sign = sign || 1;
  639. var baseValue = ch - 0x30;
  640. var powerValue = 0;
  641. var powerValueSign = 1;
  642. while ((ch = this.nextChar()) >= 0) {
  643. if (0x30 <= ch && ch <= 0x39) {
  644. var currentDigit = ch - 0x30;
  645. if (eNotation) {
  646. powerValue = powerValue * 10 + currentDigit;
  647. } else {
  648. if (divideBy !== 0) {
  649. divideBy *= 10;
  650. }
  651. baseValue = baseValue * 10 + currentDigit;
  652. }
  653. } else if (ch === 0x2E) {
  654. if (divideBy === 0) {
  655. divideBy = 1;
  656. } else {
  657. break;
  658. }
  659. } else if (ch === 0x2D) {
  660. (0, _util.warn)('Badly formatted number');
  661. } else if (ch === 0x45 || ch === 0x65) {
  662. ch = this.peekChar();
  663. if (ch === 0x2B || ch === 0x2D) {
  664. powerValueSign = ch === 0x2D ? -1 : 1;
  665. this.nextChar();
  666. } else if (ch < 0x30 || ch > 0x39) {
  667. break;
  668. }
  669. eNotation = true;
  670. } else {
  671. break;
  672. }
  673. }
  674. if (divideBy !== 0) {
  675. baseValue /= divideBy;
  676. }
  677. if (eNotation) {
  678. baseValue *= Math.pow(10, powerValueSign * powerValue);
  679. }
  680. return sign * baseValue;
  681. },
  682. getString: function Lexer_getString() {
  683. var numParen = 1;
  684. var done = false;
  685. var strBuf = this.strBuf;
  686. strBuf.length = 0;
  687. var ch = this.nextChar();
  688. while (true) {
  689. var charBuffered = false;
  690. switch (ch | 0) {
  691. case -1:
  692. (0, _util.warn)('Unterminated string');
  693. done = true;
  694. break;
  695. case 0x28:
  696. ++numParen;
  697. strBuf.push('(');
  698. break;
  699. case 0x29:
  700. if (--numParen === 0) {
  701. this.nextChar();
  702. done = true;
  703. } else {
  704. strBuf.push(')');
  705. }
  706. break;
  707. case 0x5C:
  708. ch = this.nextChar();
  709. switch (ch) {
  710. case -1:
  711. (0, _util.warn)('Unterminated string');
  712. done = true;
  713. break;
  714. case 0x6E:
  715. strBuf.push('\n');
  716. break;
  717. case 0x72:
  718. strBuf.push('\r');
  719. break;
  720. case 0x74:
  721. strBuf.push('\t');
  722. break;
  723. case 0x62:
  724. strBuf.push('\b');
  725. break;
  726. case 0x66:
  727. strBuf.push('\f');
  728. break;
  729. case 0x5C:
  730. case 0x28:
  731. case 0x29:
  732. strBuf.push(String.fromCharCode(ch));
  733. break;
  734. case 0x30:
  735. case 0x31:
  736. case 0x32:
  737. case 0x33:
  738. case 0x34:
  739. case 0x35:
  740. case 0x36:
  741. case 0x37:
  742. var x = ch & 0x0F;
  743. ch = this.nextChar();
  744. charBuffered = true;
  745. if (ch >= 0x30 && ch <= 0x37) {
  746. x = (x << 3) + (ch & 0x0F);
  747. ch = this.nextChar();
  748. if (ch >= 0x30 && ch <= 0x37) {
  749. charBuffered = false;
  750. x = (x << 3) + (ch & 0x0F);
  751. }
  752. }
  753. strBuf.push(String.fromCharCode(x));
  754. break;
  755. case 0x0D:
  756. if (this.peekChar() === 0x0A) {
  757. this.nextChar();
  758. }
  759. break;
  760. case 0x0A:
  761. break;
  762. default:
  763. strBuf.push(String.fromCharCode(ch));
  764. break;
  765. }
  766. break;
  767. default:
  768. strBuf.push(String.fromCharCode(ch));
  769. break;
  770. }
  771. if (done) {
  772. break;
  773. }
  774. if (!charBuffered) {
  775. ch = this.nextChar();
  776. }
  777. }
  778. return strBuf.join('');
  779. },
  780. getName: function Lexer_getName() {
  781. var ch, previousCh;
  782. var strBuf = this.strBuf;
  783. strBuf.length = 0;
  784. while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) {
  785. if (ch === 0x23) {
  786. ch = this.nextChar();
  787. if (specialChars[ch]) {
  788. (0, _util.warn)('Lexer_getName: ' + 'NUMBER SIGN (#) should be followed by a hexadecimal number.');
  789. strBuf.push('#');
  790. break;
  791. }
  792. var x = toHexDigit(ch);
  793. if (x !== -1) {
  794. previousCh = ch;
  795. ch = this.nextChar();
  796. var x2 = toHexDigit(ch);
  797. if (x2 === -1) {
  798. (0, _util.warn)('Lexer_getName: Illegal digit (' + String.fromCharCode(ch) + ') in hexadecimal number.');
  799. strBuf.push('#', String.fromCharCode(previousCh));
  800. if (specialChars[ch]) {
  801. break;
  802. }
  803. strBuf.push(String.fromCharCode(ch));
  804. continue;
  805. }
  806. strBuf.push(String.fromCharCode(x << 4 | x2));
  807. } else {
  808. strBuf.push('#', String.fromCharCode(ch));
  809. }
  810. } else {
  811. strBuf.push(String.fromCharCode(ch));
  812. }
  813. }
  814. if (strBuf.length > 127) {
  815. (0, _util.warn)('name token is longer than allowed by the spec: ' + strBuf.length);
  816. }
  817. return _primitives.Name.get(strBuf.join(''));
  818. },
  819. getHexString: function Lexer_getHexString() {
  820. var strBuf = this.strBuf;
  821. strBuf.length = 0;
  822. var ch = this.currentChar;
  823. var isFirstHex = true;
  824. var firstDigit;
  825. var secondDigit;
  826. while (true) {
  827. if (ch < 0) {
  828. (0, _util.warn)('Unterminated hex string');
  829. break;
  830. } else if (ch === 0x3E) {
  831. this.nextChar();
  832. break;
  833. } else if (specialChars[ch] === 1) {
  834. ch = this.nextChar();
  835. continue;
  836. } else {
  837. if (isFirstHex) {
  838. firstDigit = toHexDigit(ch);
  839. if (firstDigit === -1) {
  840. (0, _util.warn)('Ignoring invalid character "' + ch + '" in hex string');
  841. ch = this.nextChar();
  842. continue;
  843. }
  844. } else {
  845. secondDigit = toHexDigit(ch);
  846. if (secondDigit === -1) {
  847. (0, _util.warn)('Ignoring invalid character "' + ch + '" in hex string');
  848. ch = this.nextChar();
  849. continue;
  850. }
  851. strBuf.push(String.fromCharCode(firstDigit << 4 | secondDigit));
  852. }
  853. isFirstHex = !isFirstHex;
  854. ch = this.nextChar();
  855. }
  856. }
  857. return strBuf.join('');
  858. },
  859. getObj: function Lexer_getObj() {
  860. var comment = false;
  861. var ch = this.currentChar;
  862. while (true) {
  863. if (ch < 0) {
  864. return _primitives.EOF;
  865. }
  866. if (comment) {
  867. if (ch === 0x0A || ch === 0x0D) {
  868. comment = false;
  869. }
  870. } else if (ch === 0x25) {
  871. comment = true;
  872. } else if (specialChars[ch] !== 1) {
  873. break;
  874. }
  875. ch = this.nextChar();
  876. }
  877. switch (ch | 0) {
  878. case 0x30:
  879. case 0x31:
  880. case 0x32:
  881. case 0x33:
  882. case 0x34:
  883. case 0x35:
  884. case 0x36:
  885. case 0x37:
  886. case 0x38:
  887. case 0x39:
  888. case 0x2B:
  889. case 0x2D:
  890. case 0x2E:
  891. return this.getNumber();
  892. case 0x28:
  893. return this.getString();
  894. case 0x2F:
  895. return this.getName();
  896. case 0x5B:
  897. this.nextChar();
  898. return _primitives.Cmd.get('[');
  899. case 0x5D:
  900. this.nextChar();
  901. return _primitives.Cmd.get(']');
  902. case 0x3C:
  903. ch = this.nextChar();
  904. if (ch === 0x3C) {
  905. this.nextChar();
  906. return _primitives.Cmd.get('<<');
  907. }
  908. return this.getHexString();
  909. case 0x3E:
  910. ch = this.nextChar();
  911. if (ch === 0x3E) {
  912. this.nextChar();
  913. return _primitives.Cmd.get('>>');
  914. }
  915. return _primitives.Cmd.get('>');
  916. case 0x7B:
  917. this.nextChar();
  918. return _primitives.Cmd.get('{');
  919. case 0x7D:
  920. this.nextChar();
  921. return _primitives.Cmd.get('}');
  922. case 0x29:
  923. this.nextChar();
  924. throw new _util.FormatError("Illegal character: ".concat(ch));
  925. }
  926. var str = String.fromCharCode(ch);
  927. var knownCommands = this.knownCommands;
  928. var knownCommandFound = knownCommands && knownCommands[str] !== undefined;
  929. while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) {
  930. var possibleCommand = str + String.fromCharCode(ch);
  931. if (knownCommandFound && knownCommands[possibleCommand] === undefined) {
  932. break;
  933. }
  934. if (str.length === 128) {
  935. throw new _util.FormatError("Command token too long: ".concat(str.length));
  936. }
  937. str = possibleCommand;
  938. knownCommandFound = knownCommands && knownCommands[str] !== undefined;
  939. }
  940. if (str === 'true') {
  941. return true;
  942. }
  943. if (str === 'false') {
  944. return false;
  945. }
  946. if (str === 'null') {
  947. return null;
  948. }
  949. if (str === 'BI') {
  950. this.beginInlineImagePos = this.stream.pos;
  951. }
  952. return _primitives.Cmd.get(str);
  953. },
  954. skipToNextLine: function Lexer_skipToNextLine() {
  955. var ch = this.currentChar;
  956. while (ch >= 0) {
  957. if (ch === 0x0D) {
  958. ch = this.nextChar();
  959. if (ch === 0x0A) {
  960. this.nextChar();
  961. }
  962. break;
  963. } else if (ch === 0x0A) {
  964. this.nextChar();
  965. break;
  966. }
  967. ch = this.nextChar();
  968. }
  969. }
  970. };
  971. return Lexer;
  972. }();
  973. exports.Lexer = Lexer;
  974. var Linearization = {
  975. create: function LinearizationCreate(stream) {
  976. function getInt(name, allowZeroValue) {
  977. var obj = linDict.get(name);
  978. if (Number.isInteger(obj) && (allowZeroValue ? obj >= 0 : obj > 0)) {
  979. return obj;
  980. }
  981. throw new Error('The "' + name + '" parameter in the linearization ' + 'dictionary is invalid.');
  982. }
  983. function getHints() {
  984. var hints = linDict.get('H'),
  985. hintsLength,
  986. item;
  987. if (Array.isArray(hints) && ((hintsLength = hints.length) === 2 || hintsLength === 4)) {
  988. for (var index = 0; index < hintsLength; index++) {
  989. if (!(Number.isInteger(item = hints[index]) && item > 0)) {
  990. throw new Error('Hint (' + index + ') in the linearization dictionary is invalid.');
  991. }
  992. }
  993. return hints;
  994. }
  995. throw new Error('Hint array in the linearization dictionary is invalid.');
  996. }
  997. var parser = new Parser(new Lexer(stream), false, null);
  998. var obj1 = parser.getObj();
  999. var obj2 = parser.getObj();
  1000. var obj3 = parser.getObj();
  1001. var linDict = parser.getObj();
  1002. var obj, length;
  1003. 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)) {
  1004. return null;
  1005. } else if ((length = getInt('L')) !== stream.length) {
  1006. throw new Error('The "L" parameter in the linearization dictionary ' + 'does not equal the stream length.');
  1007. }
  1008. return {
  1009. length: length,
  1010. hints: getHints(),
  1011. objectNumberFirst: getInt('O'),
  1012. endFirst: getInt('E'),
  1013. numPages: getInt('N'),
  1014. mainXRefEntriesOffset: getInt('T'),
  1015. pageFirst: linDict.has('P') ? getInt('P', true) : 0
  1016. };
  1017. }
  1018. };
  1019. exports.Linearization = Linearization;