obj.js 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * Javascript code in this page
  4. *
  5. * Copyright 2020 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.FileSpec = exports.XRef = exports.ObjectLoader = exports.Catalog = void 0;
  27. var _util = require("../shared/util.js");
  28. var _primitives = require("./primitives.js");
  29. var _parser = require("./parser.js");
  30. var _core_utils = require("./core_utils.js");
  31. var _crypto = require("./crypto.js");
  32. var _colorspace = require("./colorspace.js");
  33. var _image_utils = require("./image_utils.js");
  34. function fetchDestination(dest) {
  35. return (0, _primitives.isDict)(dest) ? dest.get("D") : dest;
  36. }
  37. class Catalog {
  38. constructor(pdfManager, xref) {
  39. this.pdfManager = pdfManager;
  40. this.xref = xref;
  41. this._catDict = xref.getCatalogObj();
  42. if (!(0, _primitives.isDict)(this._catDict)) {
  43. throw new _util.FormatError("Catalog object is not a dictionary.");
  44. }
  45. this.fontCache = new _primitives.RefSetCache();
  46. this.builtInCMapCache = new Map();
  47. this.globalImageCache = new _image_utils.GlobalImageCache();
  48. this.pageKidsCountCache = new _primitives.RefSetCache();
  49. }
  50. get version() {
  51. const version = this._catDict.get("Version");
  52. if (!(0, _primitives.isName)(version)) {
  53. return (0, _util.shadow)(this, "version", null);
  54. }
  55. return (0, _util.shadow)(this, "version", version.name);
  56. }
  57. get collection() {
  58. let collection = null;
  59. try {
  60. const obj = this._catDict.get("Collection");
  61. if ((0, _primitives.isDict)(obj) && obj.size > 0) {
  62. collection = obj;
  63. }
  64. } catch (ex) {
  65. if (ex instanceof _core_utils.MissingDataException) {
  66. throw ex;
  67. }
  68. (0, _util.info)("Cannot fetch Collection entry; assuming no collection is present.");
  69. }
  70. return (0, _util.shadow)(this, "collection", collection);
  71. }
  72. get acroForm() {
  73. let acroForm = null;
  74. try {
  75. const obj = this._catDict.get("AcroForm");
  76. if ((0, _primitives.isDict)(obj) && obj.size > 0) {
  77. acroForm = obj;
  78. }
  79. } catch (ex) {
  80. if (ex instanceof _core_utils.MissingDataException) {
  81. throw ex;
  82. }
  83. (0, _util.info)("Cannot fetch AcroForm entry; assuming no forms are present.");
  84. }
  85. return (0, _util.shadow)(this, "acroForm", acroForm);
  86. }
  87. get metadata() {
  88. const streamRef = this._catDict.getRaw("Metadata");
  89. if (!(0, _primitives.isRef)(streamRef)) {
  90. return (0, _util.shadow)(this, "metadata", null);
  91. }
  92. const suppressEncryption = !(this.xref.encrypt && this.xref.encrypt.encryptMetadata);
  93. const stream = this.xref.fetch(streamRef, suppressEncryption);
  94. let metadata;
  95. if (stream && (0, _primitives.isDict)(stream.dict)) {
  96. const type = stream.dict.get("Type");
  97. const subtype = stream.dict.get("Subtype");
  98. if ((0, _primitives.isName)(type, "Metadata") && (0, _primitives.isName)(subtype, "XML")) {
  99. try {
  100. metadata = (0, _util.stringToUTF8String)((0, _util.bytesToString)(stream.getBytes()));
  101. } catch (e) {
  102. if (e instanceof _core_utils.MissingDataException) {
  103. throw e;
  104. }
  105. (0, _util.info)("Skipping invalid metadata.");
  106. }
  107. }
  108. }
  109. return (0, _util.shadow)(this, "metadata", metadata);
  110. }
  111. get toplevelPagesDict() {
  112. const pagesObj = this._catDict.get("Pages");
  113. if (!(0, _primitives.isDict)(pagesObj)) {
  114. throw new _util.FormatError("Invalid top-level pages dictionary.");
  115. }
  116. return (0, _util.shadow)(this, "toplevelPagesDict", pagesObj);
  117. }
  118. get documentOutline() {
  119. let obj = null;
  120. try {
  121. obj = this._readDocumentOutline();
  122. } catch (ex) {
  123. if (ex instanceof _core_utils.MissingDataException) {
  124. throw ex;
  125. }
  126. (0, _util.warn)("Unable to read document outline.");
  127. }
  128. return (0, _util.shadow)(this, "documentOutline", obj);
  129. }
  130. _readDocumentOutline() {
  131. let obj = this._catDict.get("Outlines");
  132. if (!(0, _primitives.isDict)(obj)) {
  133. return null;
  134. }
  135. obj = obj.getRaw("First");
  136. if (!(0, _primitives.isRef)(obj)) {
  137. return null;
  138. }
  139. const root = {
  140. items: []
  141. };
  142. const queue = [{
  143. obj,
  144. parent: root
  145. }];
  146. const processed = new _primitives.RefSet();
  147. processed.put(obj);
  148. const xref = this.xref,
  149. blackColor = new Uint8ClampedArray(3);
  150. while (queue.length > 0) {
  151. const i = queue.shift();
  152. const outlineDict = xref.fetchIfRef(i.obj);
  153. if (outlineDict === null) {
  154. continue;
  155. }
  156. if (!outlineDict.has("Title")) {
  157. throw new _util.FormatError("Invalid outline item encountered.");
  158. }
  159. const data = {
  160. url: null,
  161. dest: null
  162. };
  163. Catalog.parseDestDictionary({
  164. destDict: outlineDict,
  165. resultObj: data,
  166. docBaseUrl: this.pdfManager.docBaseUrl
  167. });
  168. const title = outlineDict.get("Title");
  169. const flags = outlineDict.get("F") || 0;
  170. const color = outlineDict.getArray("C");
  171. const count = outlineDict.get("Count");
  172. let rgbColor = blackColor;
  173. if (Array.isArray(color) && color.length === 3 && (color[0] !== 0 || color[1] !== 0 || color[2] !== 0)) {
  174. rgbColor = _colorspace.ColorSpace.singletons.rgb.getRgb(color, 0);
  175. }
  176. const outlineItem = {
  177. dest: data.dest,
  178. url: data.url,
  179. unsafeUrl: data.unsafeUrl,
  180. newWindow: data.newWindow,
  181. title: (0, _util.stringToPDFString)(title),
  182. color: rgbColor,
  183. count: Number.isInteger(count) ? count : undefined,
  184. bold: !!(flags & 2),
  185. italic: !!(flags & 1),
  186. items: []
  187. };
  188. i.parent.items.push(outlineItem);
  189. obj = outlineDict.getRaw("First");
  190. if ((0, _primitives.isRef)(obj) && !processed.has(obj)) {
  191. queue.push({
  192. obj,
  193. parent: outlineItem
  194. });
  195. processed.put(obj);
  196. }
  197. obj = outlineDict.getRaw("Next");
  198. if ((0, _primitives.isRef)(obj) && !processed.has(obj)) {
  199. queue.push({
  200. obj,
  201. parent: i.parent
  202. });
  203. processed.put(obj);
  204. }
  205. }
  206. return root.items.length > 0 ? root.items : null;
  207. }
  208. get permissions() {
  209. let permissions = null;
  210. try {
  211. permissions = this._readPermissions();
  212. } catch (ex) {
  213. if (ex instanceof _core_utils.MissingDataException) {
  214. throw ex;
  215. }
  216. (0, _util.warn)("Unable to read permissions.");
  217. }
  218. return (0, _util.shadow)(this, "permissions", permissions);
  219. }
  220. _readPermissions() {
  221. const encrypt = this.xref.trailer.get("Encrypt");
  222. if (!(0, _primitives.isDict)(encrypt)) {
  223. return null;
  224. }
  225. let flags = encrypt.get("P");
  226. if (!(0, _util.isNum)(flags)) {
  227. return null;
  228. }
  229. flags += 2 ** 32;
  230. const permissions = [];
  231. for (const key in _util.PermissionFlag) {
  232. const value = _util.PermissionFlag[key];
  233. if (flags & value) {
  234. permissions.push(value);
  235. }
  236. }
  237. return permissions;
  238. }
  239. get optionalContentConfig() {
  240. let config = null;
  241. try {
  242. const properties = this._catDict.get("OCProperties");
  243. if (!properties) {
  244. return (0, _util.shadow)(this, "optionalContentConfig", null);
  245. }
  246. const defaultConfig = properties.get("D");
  247. if (!defaultConfig) {
  248. return (0, _util.shadow)(this, "optionalContentConfig", null);
  249. }
  250. const groupsData = properties.get("OCGs");
  251. if (!Array.isArray(groupsData)) {
  252. return (0, _util.shadow)(this, "optionalContentConfig", null);
  253. }
  254. const groups = [];
  255. const groupRefs = [];
  256. for (const groupRef of groupsData) {
  257. if (!(0, _primitives.isRef)(groupRef)) {
  258. continue;
  259. }
  260. groupRefs.push(groupRef);
  261. const group = this.xref.fetchIfRef(groupRef);
  262. groups.push({
  263. id: groupRef.toString(),
  264. name: (0, _util.isString)(group.get("Name")) ? (0, _util.stringToPDFString)(group.get("Name")) : null,
  265. intent: (0, _util.isString)(group.get("Intent")) ? (0, _util.stringToPDFString)(group.get("Intent")) : null
  266. });
  267. }
  268. config = this._readOptionalContentConfig(defaultConfig, groupRefs);
  269. config.groups = groups;
  270. } catch (ex) {
  271. if (ex instanceof _core_utils.MissingDataException) {
  272. throw ex;
  273. }
  274. (0, _util.warn)(`Unable to read optional content config: ${ex}`);
  275. }
  276. return (0, _util.shadow)(this, "optionalContentConfig", config);
  277. }
  278. _readOptionalContentConfig(config, contentGroupRefs) {
  279. function parseOnOff(refs) {
  280. const onParsed = [];
  281. if (Array.isArray(refs)) {
  282. for (const value of refs) {
  283. if (!(0, _primitives.isRef)(value)) {
  284. continue;
  285. }
  286. if (contentGroupRefs.includes(value)) {
  287. onParsed.push(value.toString());
  288. }
  289. }
  290. }
  291. return onParsed;
  292. }
  293. function parseOrder(refs, nestedLevels = 0) {
  294. if (!Array.isArray(refs)) {
  295. return null;
  296. }
  297. const order = [];
  298. for (const value of refs) {
  299. if ((0, _primitives.isRef)(value) && contentGroupRefs.includes(value)) {
  300. parsedOrderRefs.put(value);
  301. order.push(value.toString());
  302. continue;
  303. }
  304. const nestedOrder = parseNestedOrder(value, nestedLevels);
  305. if (nestedOrder) {
  306. order.push(nestedOrder);
  307. }
  308. }
  309. if (nestedLevels > 0) {
  310. return order;
  311. }
  312. const hiddenGroups = [];
  313. for (const groupRef of contentGroupRefs) {
  314. if (parsedOrderRefs.has(groupRef)) {
  315. continue;
  316. }
  317. hiddenGroups.push(groupRef.toString());
  318. }
  319. if (hiddenGroups.length) {
  320. order.push({
  321. name: null,
  322. order: hiddenGroups
  323. });
  324. }
  325. return order;
  326. }
  327. function parseNestedOrder(ref, nestedLevels) {
  328. if (++nestedLevels > MAX_NESTED_LEVELS) {
  329. (0, _util.warn)("parseNestedOrder - reached MAX_NESTED_LEVELS.");
  330. return null;
  331. }
  332. const value = xref.fetchIfRef(ref);
  333. if (!Array.isArray(value)) {
  334. return null;
  335. }
  336. const nestedName = xref.fetchIfRef(value[0]);
  337. if (typeof nestedName !== "string") {
  338. return null;
  339. }
  340. const nestedOrder = parseOrder(value.slice(1), nestedLevels);
  341. if (!nestedOrder || !nestedOrder.length) {
  342. return null;
  343. }
  344. return {
  345. name: (0, _util.stringToPDFString)(nestedName),
  346. order: nestedOrder
  347. };
  348. }
  349. const xref = this.xref,
  350. parsedOrderRefs = new _primitives.RefSet(),
  351. MAX_NESTED_LEVELS = 10;
  352. return {
  353. name: (0, _util.isString)(config.get("Name")) ? (0, _util.stringToPDFString)(config.get("Name")) : null,
  354. creator: (0, _util.isString)(config.get("Creator")) ? (0, _util.stringToPDFString)(config.get("Creator")) : null,
  355. baseState: (0, _primitives.isName)(config.get("BaseState")) ? config.get("BaseState").name : null,
  356. on: parseOnOff(config.get("ON")),
  357. off: parseOnOff(config.get("OFF")),
  358. order: parseOrder(config.get("Order")),
  359. groups: null
  360. };
  361. }
  362. get numPages() {
  363. const obj = this.toplevelPagesDict.get("Count");
  364. if (!Number.isInteger(obj)) {
  365. throw new _util.FormatError("Page count in top-level pages dictionary is not an integer.");
  366. }
  367. return (0, _util.shadow)(this, "numPages", obj);
  368. }
  369. get destinations() {
  370. const obj = this._readDests(),
  371. dests = Object.create(null);
  372. if (obj instanceof NameTree) {
  373. const names = obj.getAll();
  374. for (const name in names) {
  375. dests[name] = fetchDestination(names[name]);
  376. }
  377. } else if (obj instanceof _primitives.Dict) {
  378. obj.forEach(function (key, value) {
  379. if (value) {
  380. dests[key] = fetchDestination(value);
  381. }
  382. });
  383. }
  384. return (0, _util.shadow)(this, "destinations", dests);
  385. }
  386. getDestination(destinationId) {
  387. const obj = this._readDests();
  388. if (obj instanceof NameTree || obj instanceof _primitives.Dict) {
  389. return fetchDestination(obj.get(destinationId) || null);
  390. }
  391. return null;
  392. }
  393. _readDests() {
  394. const obj = this._catDict.get("Names");
  395. if (obj && obj.has("Dests")) {
  396. return new NameTree(obj.getRaw("Dests"), this.xref);
  397. } else if (this._catDict.has("Dests")) {
  398. return this._catDict.get("Dests");
  399. }
  400. return undefined;
  401. }
  402. get pageLabels() {
  403. let obj = null;
  404. try {
  405. obj = this._readPageLabels();
  406. } catch (ex) {
  407. if (ex instanceof _core_utils.MissingDataException) {
  408. throw ex;
  409. }
  410. (0, _util.warn)("Unable to read page labels.");
  411. }
  412. return (0, _util.shadow)(this, "pageLabels", obj);
  413. }
  414. _readPageLabels() {
  415. const obj = this._catDict.getRaw("PageLabels");
  416. if (!obj) {
  417. return null;
  418. }
  419. const pageLabels = new Array(this.numPages);
  420. let style = null,
  421. prefix = "";
  422. const numberTree = new NumberTree(obj, this.xref);
  423. const nums = numberTree.getAll();
  424. let currentLabel = "",
  425. currentIndex = 1;
  426. for (let i = 0, ii = this.numPages; i < ii; i++) {
  427. if (i in nums) {
  428. const labelDict = nums[i];
  429. if (!(0, _primitives.isDict)(labelDict)) {
  430. throw new _util.FormatError("PageLabel is not a dictionary.");
  431. }
  432. if (labelDict.has("Type") && !(0, _primitives.isName)(labelDict.get("Type"), "PageLabel")) {
  433. throw new _util.FormatError("Invalid type in PageLabel dictionary.");
  434. }
  435. if (labelDict.has("S")) {
  436. const s = labelDict.get("S");
  437. if (!(0, _primitives.isName)(s)) {
  438. throw new _util.FormatError("Invalid style in PageLabel dictionary.");
  439. }
  440. style = s.name;
  441. } else {
  442. style = null;
  443. }
  444. if (labelDict.has("P")) {
  445. const p = labelDict.get("P");
  446. if (!(0, _util.isString)(p)) {
  447. throw new _util.FormatError("Invalid prefix in PageLabel dictionary.");
  448. }
  449. prefix = (0, _util.stringToPDFString)(p);
  450. } else {
  451. prefix = "";
  452. }
  453. if (labelDict.has("St")) {
  454. const st = labelDict.get("St");
  455. if (!(Number.isInteger(st) && st >= 1)) {
  456. throw new _util.FormatError("Invalid start in PageLabel dictionary.");
  457. }
  458. currentIndex = st;
  459. } else {
  460. currentIndex = 1;
  461. }
  462. }
  463. switch (style) {
  464. case "D":
  465. currentLabel = currentIndex;
  466. break;
  467. case "R":
  468. case "r":
  469. currentLabel = (0, _core_utils.toRomanNumerals)(currentIndex, style === "r");
  470. break;
  471. case "A":
  472. case "a":
  473. const LIMIT = 26;
  474. const A_UPPER_CASE = 0x41,
  475. A_LOWER_CASE = 0x61;
  476. const baseCharCode = style === "a" ? A_LOWER_CASE : A_UPPER_CASE;
  477. const letterIndex = currentIndex - 1;
  478. const character = String.fromCharCode(baseCharCode + letterIndex % LIMIT);
  479. const charBuf = [];
  480. for (let j = 0, jj = letterIndex / LIMIT | 0; j <= jj; j++) {
  481. charBuf.push(character);
  482. }
  483. currentLabel = charBuf.join("");
  484. break;
  485. default:
  486. if (style) {
  487. throw new _util.FormatError(`Invalid style "${style}" in PageLabel dictionary.`);
  488. }
  489. currentLabel = "";
  490. }
  491. pageLabels[i] = prefix + currentLabel;
  492. currentIndex++;
  493. }
  494. return pageLabels;
  495. }
  496. get pageLayout() {
  497. const obj = this._catDict.get("PageLayout");
  498. let pageLayout = "";
  499. if ((0, _primitives.isName)(obj)) {
  500. switch (obj.name) {
  501. case "SinglePage":
  502. case "OneColumn":
  503. case "TwoColumnLeft":
  504. case "TwoColumnRight":
  505. case "TwoPageLeft":
  506. case "TwoPageRight":
  507. pageLayout = obj.name;
  508. }
  509. }
  510. return (0, _util.shadow)(this, "pageLayout", pageLayout);
  511. }
  512. get pageMode() {
  513. const obj = this._catDict.get("PageMode");
  514. let pageMode = "UseNone";
  515. if ((0, _primitives.isName)(obj)) {
  516. switch (obj.name) {
  517. case "UseNone":
  518. case "UseOutlines":
  519. case "UseThumbs":
  520. case "FullScreen":
  521. case "UseOC":
  522. case "UseAttachments":
  523. pageMode = obj.name;
  524. }
  525. }
  526. return (0, _util.shadow)(this, "pageMode", pageMode);
  527. }
  528. get viewerPreferences() {
  529. const ViewerPreferencesValidators = {
  530. HideToolbar: _util.isBool,
  531. HideMenubar: _util.isBool,
  532. HideWindowUI: _util.isBool,
  533. FitWindow: _util.isBool,
  534. CenterWindow: _util.isBool,
  535. DisplayDocTitle: _util.isBool,
  536. NonFullScreenPageMode: _primitives.isName,
  537. Direction: _primitives.isName,
  538. ViewArea: _primitives.isName,
  539. ViewClip: _primitives.isName,
  540. PrintArea: _primitives.isName,
  541. PrintClip: _primitives.isName,
  542. PrintScaling: _primitives.isName,
  543. Duplex: _primitives.isName,
  544. PickTrayByPDFSize: _util.isBool,
  545. PrintPageRange: Array.isArray,
  546. NumCopies: Number.isInteger
  547. };
  548. const obj = this._catDict.get("ViewerPreferences");
  549. let prefs = null;
  550. if ((0, _primitives.isDict)(obj)) {
  551. for (const key in ViewerPreferencesValidators) {
  552. if (!obj.has(key)) {
  553. continue;
  554. }
  555. const value = obj.get(key);
  556. if (!ViewerPreferencesValidators[key](value)) {
  557. (0, _util.info)(`Bad value in ViewerPreferences for "${key}".`);
  558. continue;
  559. }
  560. let prefValue;
  561. switch (key) {
  562. case "NonFullScreenPageMode":
  563. switch (value.name) {
  564. case "UseNone":
  565. case "UseOutlines":
  566. case "UseThumbs":
  567. case "UseOC":
  568. prefValue = value.name;
  569. break;
  570. default:
  571. prefValue = "UseNone";
  572. }
  573. break;
  574. case "Direction":
  575. switch (value.name) {
  576. case "L2R":
  577. case "R2L":
  578. prefValue = value.name;
  579. break;
  580. default:
  581. prefValue = "L2R";
  582. }
  583. break;
  584. case "ViewArea":
  585. case "ViewClip":
  586. case "PrintArea":
  587. case "PrintClip":
  588. switch (value.name) {
  589. case "MediaBox":
  590. case "CropBox":
  591. case "BleedBox":
  592. case "TrimBox":
  593. case "ArtBox":
  594. prefValue = value.name;
  595. break;
  596. default:
  597. prefValue = "CropBox";
  598. }
  599. break;
  600. case "PrintScaling":
  601. switch (value.name) {
  602. case "None":
  603. case "AppDefault":
  604. prefValue = value.name;
  605. break;
  606. default:
  607. prefValue = "AppDefault";
  608. }
  609. break;
  610. case "Duplex":
  611. switch (value.name) {
  612. case "Simplex":
  613. case "DuplexFlipShortEdge":
  614. case "DuplexFlipLongEdge":
  615. prefValue = value.name;
  616. break;
  617. default:
  618. prefValue = "None";
  619. }
  620. break;
  621. case "PrintPageRange":
  622. const length = value.length;
  623. if (length % 2 !== 0) {
  624. break;
  625. }
  626. const isValid = value.every((page, i, arr) => {
  627. return Number.isInteger(page) && page > 0 && (i === 0 || page >= arr[i - 1]) && page <= this.numPages;
  628. });
  629. if (isValid) {
  630. prefValue = value;
  631. }
  632. break;
  633. case "NumCopies":
  634. if (value > 0) {
  635. prefValue = value;
  636. }
  637. break;
  638. default:
  639. if (typeof value !== "boolean") {
  640. throw new _util.FormatError(`viewerPreferences - expected a boolean value for: ${key}`);
  641. }
  642. prefValue = value;
  643. }
  644. if (prefValue !== undefined) {
  645. if (!prefs) {
  646. prefs = Object.create(null);
  647. }
  648. prefs[key] = prefValue;
  649. } else {
  650. (0, _util.info)(`Bad value in ViewerPreferences for "${key}".`);
  651. }
  652. }
  653. }
  654. return (0, _util.shadow)(this, "viewerPreferences", prefs);
  655. }
  656. get openAction() {
  657. const obj = this._catDict.get("OpenAction");
  658. let openAction = null;
  659. if ((0, _primitives.isDict)(obj)) {
  660. const destDict = new _primitives.Dict(this.xref);
  661. destDict.set("A", obj);
  662. const resultObj = {
  663. url: null,
  664. dest: null,
  665. action: null
  666. };
  667. Catalog.parseDestDictionary({
  668. destDict,
  669. resultObj
  670. });
  671. if (Array.isArray(resultObj.dest)) {
  672. if (!openAction) {
  673. openAction = Object.create(null);
  674. }
  675. openAction.dest = resultObj.dest;
  676. } else if (resultObj.action) {
  677. if (!openAction) {
  678. openAction = Object.create(null);
  679. }
  680. openAction.action = resultObj.action;
  681. }
  682. } else if (Array.isArray(obj)) {
  683. if (!openAction) {
  684. openAction = Object.create(null);
  685. }
  686. openAction.dest = obj;
  687. }
  688. return (0, _util.shadow)(this, "openAction", openAction);
  689. }
  690. get attachments() {
  691. const obj = this._catDict.get("Names");
  692. let attachments = null;
  693. if (obj && obj.has("EmbeddedFiles")) {
  694. const nameTree = new NameTree(obj.getRaw("EmbeddedFiles"), this.xref);
  695. const names = nameTree.getAll();
  696. for (const name in names) {
  697. const fs = new FileSpec(names[name], this.xref);
  698. if (!attachments) {
  699. attachments = Object.create(null);
  700. }
  701. attachments[(0, _util.stringToPDFString)(name)] = fs.serializable;
  702. }
  703. }
  704. return (0, _util.shadow)(this, "attachments", attachments);
  705. }
  706. get javaScript() {
  707. const obj = this._catDict.get("Names");
  708. let javaScript = null;
  709. function appendIfJavaScriptDict(jsDict) {
  710. const type = jsDict.get("S");
  711. if (!(0, _primitives.isName)(type, "JavaScript")) {
  712. return;
  713. }
  714. let js = jsDict.get("JS");
  715. if ((0, _primitives.isStream)(js)) {
  716. js = (0, _util.bytesToString)(js.getBytes());
  717. } else if (!(0, _util.isString)(js)) {
  718. return;
  719. }
  720. if (!javaScript) {
  721. javaScript = [];
  722. }
  723. javaScript.push((0, _util.stringToPDFString)(js));
  724. }
  725. if (obj && obj.has("JavaScript")) {
  726. const nameTree = new NameTree(obj.getRaw("JavaScript"), this.xref);
  727. const names = nameTree.getAll();
  728. for (const name in names) {
  729. const jsDict = names[name];
  730. if ((0, _primitives.isDict)(jsDict)) {
  731. appendIfJavaScriptDict(jsDict);
  732. }
  733. }
  734. }
  735. const openAction = this._catDict.get("OpenAction");
  736. if ((0, _primitives.isDict)(openAction) && (0, _primitives.isName)(openAction.get("S"), "JavaScript")) {
  737. appendIfJavaScriptDict(openAction);
  738. }
  739. return (0, _util.shadow)(this, "javaScript", javaScript);
  740. }
  741. fontFallback(id, handler) {
  742. const promises = [];
  743. this.fontCache.forEach(function (promise) {
  744. promises.push(promise);
  745. });
  746. return Promise.all(promises).then(translatedFonts => {
  747. for (const translatedFont of translatedFonts) {
  748. if (translatedFont.loadedName === id) {
  749. translatedFont.fallback(handler);
  750. return;
  751. }
  752. }
  753. });
  754. }
  755. cleanup(manuallyTriggered = false) {
  756. (0, _primitives.clearPrimitiveCaches)();
  757. this.globalImageCache.clear(manuallyTriggered);
  758. this.pageKidsCountCache.clear();
  759. const promises = [];
  760. this.fontCache.forEach(function (promise) {
  761. promises.push(promise);
  762. });
  763. return Promise.all(promises).then(translatedFonts => {
  764. for (const {
  765. dict
  766. } of translatedFonts) {
  767. delete dict.translated;
  768. }
  769. this.fontCache.clear();
  770. this.builtInCMapCache.clear();
  771. });
  772. }
  773. getPageDict(pageIndex) {
  774. const capability = (0, _util.createPromiseCapability)();
  775. const nodesToVisit = [this._catDict.getRaw("Pages")];
  776. const visitedNodes = new _primitives.RefSet();
  777. const xref = this.xref,
  778. pageKidsCountCache = this.pageKidsCountCache;
  779. let count,
  780. currentPageIndex = 0;
  781. function next() {
  782. while (nodesToVisit.length) {
  783. const currentNode = nodesToVisit.pop();
  784. if ((0, _primitives.isRef)(currentNode)) {
  785. count = pageKidsCountCache.get(currentNode);
  786. if (count > 0 && currentPageIndex + count < pageIndex) {
  787. currentPageIndex += count;
  788. continue;
  789. }
  790. if (visitedNodes.has(currentNode)) {
  791. capability.reject(new _util.FormatError("Pages tree contains circular reference."));
  792. return;
  793. }
  794. visitedNodes.put(currentNode);
  795. xref.fetchAsync(currentNode).then(function (obj) {
  796. if ((0, _primitives.isDict)(obj, "Page") || (0, _primitives.isDict)(obj) && !obj.has("Kids")) {
  797. if (pageIndex === currentPageIndex) {
  798. if (currentNode && !pageKidsCountCache.has(currentNode)) {
  799. pageKidsCountCache.put(currentNode, 1);
  800. }
  801. capability.resolve([obj, currentNode]);
  802. } else {
  803. currentPageIndex++;
  804. next();
  805. }
  806. return;
  807. }
  808. nodesToVisit.push(obj);
  809. next();
  810. }, capability.reject);
  811. return;
  812. }
  813. if (!(0, _primitives.isDict)(currentNode)) {
  814. capability.reject(new _util.FormatError("Page dictionary kid reference points to wrong type of object."));
  815. return;
  816. }
  817. count = currentNode.get("Count");
  818. if (Number.isInteger(count) && count >= 0) {
  819. const objId = currentNode.objId;
  820. if (objId && !pageKidsCountCache.has(objId)) {
  821. pageKidsCountCache.put(objId, count);
  822. }
  823. if (currentPageIndex + count <= pageIndex) {
  824. currentPageIndex += count;
  825. continue;
  826. }
  827. }
  828. const kids = currentNode.get("Kids");
  829. if (!Array.isArray(kids)) {
  830. if ((0, _primitives.isName)(currentNode.get("Type"), "Page") || !currentNode.has("Type") && currentNode.has("Contents")) {
  831. if (currentPageIndex === pageIndex) {
  832. capability.resolve([currentNode, null]);
  833. return;
  834. }
  835. currentPageIndex++;
  836. continue;
  837. }
  838. capability.reject(new _util.FormatError("Page dictionary kids object is not an array."));
  839. return;
  840. }
  841. for (let last = kids.length - 1; last >= 0; last--) {
  842. nodesToVisit.push(kids[last]);
  843. }
  844. }
  845. capability.reject(new Error(`Page index ${pageIndex} not found.`));
  846. }
  847. next();
  848. return capability.promise;
  849. }
  850. getPageIndex(pageRef) {
  851. const xref = this.xref;
  852. function pagesBeforeRef(kidRef) {
  853. let total = 0,
  854. parentRef;
  855. return xref.fetchAsync(kidRef).then(function (node) {
  856. if ((0, _primitives.isRefsEqual)(kidRef, pageRef) && !(0, _primitives.isDict)(node, "Page") && !((0, _primitives.isDict)(node) && !node.has("Type") && node.has("Contents"))) {
  857. throw new _util.FormatError("The reference does not point to a /Page dictionary.");
  858. }
  859. if (!node) {
  860. return null;
  861. }
  862. if (!(0, _primitives.isDict)(node)) {
  863. throw new _util.FormatError("Node must be a dictionary.");
  864. }
  865. parentRef = node.getRaw("Parent");
  866. return node.getAsync("Parent");
  867. }).then(function (parent) {
  868. if (!parent) {
  869. return null;
  870. }
  871. if (!(0, _primitives.isDict)(parent)) {
  872. throw new _util.FormatError("Parent must be a dictionary.");
  873. }
  874. return parent.getAsync("Kids");
  875. }).then(function (kids) {
  876. if (!kids) {
  877. return null;
  878. }
  879. const kidPromises = [];
  880. let found = false;
  881. for (let i = 0, ii = kids.length; i < ii; i++) {
  882. const kid = kids[i];
  883. if (!(0, _primitives.isRef)(kid)) {
  884. throw new _util.FormatError("Kid must be a reference.");
  885. }
  886. if ((0, _primitives.isRefsEqual)(kid, kidRef)) {
  887. found = true;
  888. break;
  889. }
  890. kidPromises.push(xref.fetchAsync(kid).then(function (obj) {
  891. if (!(0, _primitives.isDict)(obj)) {
  892. throw new _util.FormatError("Kid node must be a dictionary.");
  893. }
  894. if (obj.has("Count")) {
  895. total += obj.get("Count");
  896. } else {
  897. total++;
  898. }
  899. }));
  900. }
  901. if (!found) {
  902. throw new _util.FormatError("Kid reference not found in parent's kids.");
  903. }
  904. return Promise.all(kidPromises).then(function () {
  905. return [total, parentRef];
  906. });
  907. });
  908. }
  909. let total = 0;
  910. function next(ref) {
  911. return pagesBeforeRef(ref).then(function (args) {
  912. if (!args) {
  913. return total;
  914. }
  915. const [count, parentRef] = args;
  916. total += count;
  917. return next(parentRef);
  918. });
  919. }
  920. return next(pageRef);
  921. }
  922. static parseDestDictionary(params) {
  923. function addDefaultProtocolToUrl(url) {
  924. return url.startsWith("www.") ? `http://${url}` : url;
  925. }
  926. function tryConvertUrlEncoding(url) {
  927. try {
  928. return (0, _util.stringToUTF8String)(url);
  929. } catch (e) {
  930. return url;
  931. }
  932. }
  933. const destDict = params.destDict;
  934. if (!(0, _primitives.isDict)(destDict)) {
  935. (0, _util.warn)("parseDestDictionary: `destDict` must be a dictionary.");
  936. return;
  937. }
  938. const resultObj = params.resultObj;
  939. if (typeof resultObj !== "object") {
  940. (0, _util.warn)("parseDestDictionary: `resultObj` must be an object.");
  941. return;
  942. }
  943. const docBaseUrl = params.docBaseUrl || null;
  944. let action = destDict.get("A"),
  945. url,
  946. dest;
  947. if (!(0, _primitives.isDict)(action) && destDict.has("Dest")) {
  948. action = destDict.get("Dest");
  949. }
  950. if ((0, _primitives.isDict)(action)) {
  951. const actionType = action.get("S");
  952. if (!(0, _primitives.isName)(actionType)) {
  953. (0, _util.warn)("parseDestDictionary: Invalid type in Action dictionary.");
  954. return;
  955. }
  956. const actionName = actionType.name;
  957. switch (actionName) {
  958. case "URI":
  959. url = action.get("URI");
  960. if ((0, _primitives.isName)(url)) {
  961. url = "/" + url.name;
  962. } else if ((0, _util.isString)(url)) {
  963. url = addDefaultProtocolToUrl(url);
  964. }
  965. break;
  966. case "GoTo":
  967. dest = action.get("D");
  968. break;
  969. case "Launch":
  970. case "GoToR":
  971. const urlDict = action.get("F");
  972. if ((0, _primitives.isDict)(urlDict)) {
  973. url = urlDict.get("F") || null;
  974. } else if ((0, _util.isString)(urlDict)) {
  975. url = urlDict;
  976. }
  977. let remoteDest = action.get("D");
  978. if (remoteDest) {
  979. if ((0, _primitives.isName)(remoteDest)) {
  980. remoteDest = remoteDest.name;
  981. }
  982. if ((0, _util.isString)(url)) {
  983. const baseUrl = url.split("#")[0];
  984. if ((0, _util.isString)(remoteDest)) {
  985. url = baseUrl + "#" + remoteDest;
  986. } else if (Array.isArray(remoteDest)) {
  987. url = baseUrl + "#" + JSON.stringify(remoteDest);
  988. }
  989. }
  990. }
  991. const newWindow = action.get("NewWindow");
  992. if ((0, _util.isBool)(newWindow)) {
  993. resultObj.newWindow = newWindow;
  994. }
  995. break;
  996. case "Named":
  997. const namedAction = action.get("N");
  998. if ((0, _primitives.isName)(namedAction)) {
  999. resultObj.action = namedAction.name;
  1000. }
  1001. break;
  1002. case "JavaScript":
  1003. const jsAction = action.get("JS");
  1004. let js;
  1005. if ((0, _primitives.isStream)(jsAction)) {
  1006. js = (0, _util.bytesToString)(jsAction.getBytes());
  1007. } else if ((0, _util.isString)(jsAction)) {
  1008. js = jsAction;
  1009. }
  1010. if (js) {
  1011. const URL_OPEN_METHODS = ["app.launchURL", "window.open"];
  1012. const regex = new RegExp("^\\s*(" + URL_OPEN_METHODS.join("|").split(".").join("\\.") + ")\\((?:'|\")([^'\"]*)(?:'|\")(?:,\\s*(\\w+)\\)|\\))", "i");
  1013. const jsUrl = regex.exec((0, _util.stringToPDFString)(js));
  1014. if (jsUrl && jsUrl[2]) {
  1015. url = jsUrl[2];
  1016. if (jsUrl[3] === "true" && jsUrl[1] === "app.launchURL") {
  1017. resultObj.newWindow = true;
  1018. }
  1019. break;
  1020. }
  1021. }
  1022. default:
  1023. (0, _util.warn)(`parseDestDictionary: unsupported action type "${actionName}".`);
  1024. break;
  1025. }
  1026. } else if (destDict.has("Dest")) {
  1027. dest = destDict.get("Dest");
  1028. }
  1029. if ((0, _util.isString)(url)) {
  1030. url = tryConvertUrlEncoding(url);
  1031. const absoluteUrl = (0, _util.createValidAbsoluteUrl)(url, docBaseUrl);
  1032. if (absoluteUrl) {
  1033. resultObj.url = absoluteUrl.href;
  1034. }
  1035. resultObj.unsafeUrl = url;
  1036. }
  1037. if (dest) {
  1038. if ((0, _primitives.isName)(dest)) {
  1039. dest = dest.name;
  1040. }
  1041. if ((0, _util.isString)(dest) || Array.isArray(dest)) {
  1042. resultObj.dest = dest;
  1043. }
  1044. }
  1045. }
  1046. }
  1047. exports.Catalog = Catalog;
  1048. var XRef = function XRefClosure() {
  1049. function XRef(stream, pdfManager) {
  1050. this.stream = stream;
  1051. this.pdfManager = pdfManager;
  1052. this.entries = [];
  1053. this.xrefstms = Object.create(null);
  1054. this._cacheMap = new Map();
  1055. this.stats = {
  1056. streamTypes: Object.create(null),
  1057. fontTypes: Object.create(null)
  1058. };
  1059. this._newRefNum = null;
  1060. }
  1061. XRef.prototype = {
  1062. getNewRef: function XRef_getNewRef() {
  1063. if (this._newRefNum === null) {
  1064. this._newRefNum = this.entries.length;
  1065. }
  1066. return _primitives.Ref.get(this._newRefNum++, 0);
  1067. },
  1068. resetNewRef: function XRef_resetNewRef() {
  1069. this._newRefNum = null;
  1070. },
  1071. setStartXRef: function XRef_setStartXRef(startXRef) {
  1072. this.startXRefQueue = [startXRef];
  1073. },
  1074. parse: function XRef_parse(recoveryMode) {
  1075. var trailerDict;
  1076. if (!recoveryMode) {
  1077. trailerDict = this.readXRef();
  1078. } else {
  1079. (0, _util.warn)("Indexing all PDF objects");
  1080. trailerDict = this.indexObjects();
  1081. }
  1082. trailerDict.assignXref(this);
  1083. this.trailer = trailerDict;
  1084. let encrypt;
  1085. try {
  1086. encrypt = trailerDict.get("Encrypt");
  1087. } catch (ex) {
  1088. if (ex instanceof _core_utils.MissingDataException) {
  1089. throw ex;
  1090. }
  1091. (0, _util.warn)(`XRef.parse - Invalid "Encrypt" reference: "${ex}".`);
  1092. }
  1093. if ((0, _primitives.isDict)(encrypt)) {
  1094. var ids = trailerDict.get("ID");
  1095. var fileId = ids && ids.length ? ids[0] : "";
  1096. encrypt.suppressEncryption = true;
  1097. this.encrypt = new _crypto.CipherTransformFactory(encrypt, fileId, this.pdfManager.password);
  1098. }
  1099. let root;
  1100. try {
  1101. root = trailerDict.get("Root");
  1102. } catch (ex) {
  1103. if (ex instanceof _core_utils.MissingDataException) {
  1104. throw ex;
  1105. }
  1106. (0, _util.warn)(`XRef.parse - Invalid "Root" reference: "${ex}".`);
  1107. }
  1108. if ((0, _primitives.isDict)(root) && root.has("Pages")) {
  1109. this.root = root;
  1110. } else {
  1111. if (!recoveryMode) {
  1112. throw new _core_utils.XRefParseException();
  1113. }
  1114. throw new _util.FormatError("Invalid root reference");
  1115. }
  1116. },
  1117. processXRefTable: function XRef_processXRefTable(parser) {
  1118. if (!("tableState" in this)) {
  1119. this.tableState = {
  1120. entryNum: 0,
  1121. streamPos: parser.lexer.stream.pos,
  1122. parserBuf1: parser.buf1,
  1123. parserBuf2: parser.buf2
  1124. };
  1125. }
  1126. var obj = this.readXRefTable(parser);
  1127. if (!(0, _primitives.isCmd)(obj, "trailer")) {
  1128. throw new _util.FormatError("Invalid XRef table: could not find trailer dictionary");
  1129. }
  1130. var dict = parser.getObj();
  1131. if (!(0, _primitives.isDict)(dict) && dict.dict) {
  1132. dict = dict.dict;
  1133. }
  1134. if (!(0, _primitives.isDict)(dict)) {
  1135. throw new _util.FormatError("Invalid XRef table: could not parse trailer dictionary");
  1136. }
  1137. delete this.tableState;
  1138. return dict;
  1139. },
  1140. readXRefTable: function XRef_readXRefTable(parser) {
  1141. var stream = parser.lexer.stream;
  1142. var tableState = this.tableState;
  1143. stream.pos = tableState.streamPos;
  1144. parser.buf1 = tableState.parserBuf1;
  1145. parser.buf2 = tableState.parserBuf2;
  1146. var obj;
  1147. while (true) {
  1148. if (!("firstEntryNum" in tableState) || !("entryCount" in tableState)) {
  1149. if ((0, _primitives.isCmd)(obj = parser.getObj(), "trailer")) {
  1150. break;
  1151. }
  1152. tableState.firstEntryNum = obj;
  1153. tableState.entryCount = parser.getObj();
  1154. }
  1155. var first = tableState.firstEntryNum;
  1156. var count = tableState.entryCount;
  1157. if (!Number.isInteger(first) || !Number.isInteger(count)) {
  1158. throw new _util.FormatError("Invalid XRef table: wrong types in subsection header");
  1159. }
  1160. for (var i = tableState.entryNum; i < count; i++) {
  1161. tableState.streamPos = stream.pos;
  1162. tableState.entryNum = i;
  1163. tableState.parserBuf1 = parser.buf1;
  1164. tableState.parserBuf2 = parser.buf2;
  1165. var entry = {};
  1166. entry.offset = parser.getObj();
  1167. entry.gen = parser.getObj();
  1168. var type = parser.getObj();
  1169. if (type instanceof _primitives.Cmd) {
  1170. switch (type.cmd) {
  1171. case "f":
  1172. entry.free = true;
  1173. break;
  1174. case "n":
  1175. entry.uncompressed = true;
  1176. break;
  1177. }
  1178. }
  1179. if (!Number.isInteger(entry.offset) || !Number.isInteger(entry.gen) || !(entry.free || entry.uncompressed)) {
  1180. throw new _util.FormatError(`Invalid entry in XRef subsection: ${first}, ${count}`);
  1181. }
  1182. if (i === 0 && entry.free && first === 1) {
  1183. first = 0;
  1184. }
  1185. if (!this.entries[i + first]) {
  1186. this.entries[i + first] = entry;
  1187. }
  1188. }
  1189. tableState.entryNum = 0;
  1190. tableState.streamPos = stream.pos;
  1191. tableState.parserBuf1 = parser.buf1;
  1192. tableState.parserBuf2 = parser.buf2;
  1193. delete tableState.firstEntryNum;
  1194. delete tableState.entryCount;
  1195. }
  1196. if (this.entries[0] && !this.entries[0].free) {
  1197. throw new _util.FormatError("Invalid XRef table: unexpected first object");
  1198. }
  1199. return obj;
  1200. },
  1201. processXRefStream: function XRef_processXRefStream(stream) {
  1202. if (!("streamState" in this)) {
  1203. var streamParameters = stream.dict;
  1204. var byteWidths = streamParameters.get("W");
  1205. var range = streamParameters.get("Index");
  1206. if (!range) {
  1207. range = [0, streamParameters.get("Size")];
  1208. }
  1209. this.streamState = {
  1210. entryRanges: range,
  1211. byteWidths,
  1212. entryNum: 0,
  1213. streamPos: stream.pos
  1214. };
  1215. }
  1216. this.readXRefStream(stream);
  1217. delete this.streamState;
  1218. return stream.dict;
  1219. },
  1220. readXRefStream: function XRef_readXRefStream(stream) {
  1221. var i, j;
  1222. var streamState = this.streamState;
  1223. stream.pos = streamState.streamPos;
  1224. var byteWidths = streamState.byteWidths;
  1225. var typeFieldWidth = byteWidths[0];
  1226. var offsetFieldWidth = byteWidths[1];
  1227. var generationFieldWidth = byteWidths[2];
  1228. var entryRanges = streamState.entryRanges;
  1229. while (entryRanges.length > 0) {
  1230. var first = entryRanges[0];
  1231. var n = entryRanges[1];
  1232. if (!Number.isInteger(first) || !Number.isInteger(n)) {
  1233. throw new _util.FormatError(`Invalid XRef range fields: ${first}, ${n}`);
  1234. }
  1235. if (!Number.isInteger(typeFieldWidth) || !Number.isInteger(offsetFieldWidth) || !Number.isInteger(generationFieldWidth)) {
  1236. throw new _util.FormatError(`Invalid XRef entry fields length: ${first}, ${n}`);
  1237. }
  1238. for (i = streamState.entryNum; i < n; ++i) {
  1239. streamState.entryNum = i;
  1240. streamState.streamPos = stream.pos;
  1241. var type = 0,
  1242. offset = 0,
  1243. generation = 0;
  1244. for (j = 0; j < typeFieldWidth; ++j) {
  1245. type = type << 8 | stream.getByte();
  1246. }
  1247. if (typeFieldWidth === 0) {
  1248. type = 1;
  1249. }
  1250. for (j = 0; j < offsetFieldWidth; ++j) {
  1251. offset = offset << 8 | stream.getByte();
  1252. }
  1253. for (j = 0; j < generationFieldWidth; ++j) {
  1254. generation = generation << 8 | stream.getByte();
  1255. }
  1256. var entry = {};
  1257. entry.offset = offset;
  1258. entry.gen = generation;
  1259. switch (type) {
  1260. case 0:
  1261. entry.free = true;
  1262. break;
  1263. case 1:
  1264. entry.uncompressed = true;
  1265. break;
  1266. case 2:
  1267. break;
  1268. default:
  1269. throw new _util.FormatError(`Invalid XRef entry type: ${type}`);
  1270. }
  1271. if (!this.entries[first + i]) {
  1272. this.entries[first + i] = entry;
  1273. }
  1274. }
  1275. streamState.entryNum = 0;
  1276. streamState.streamPos = stream.pos;
  1277. entryRanges.splice(0, 2);
  1278. }
  1279. },
  1280. indexObjects: function XRef_indexObjects() {
  1281. var TAB = 0x9,
  1282. LF = 0xa,
  1283. CR = 0xd,
  1284. SPACE = 0x20;
  1285. var PERCENT = 0x25,
  1286. LT = 0x3c;
  1287. function readToken(data, offset) {
  1288. var token = "",
  1289. ch = data[offset];
  1290. while (ch !== LF && ch !== CR && ch !== LT) {
  1291. if (++offset >= data.length) {
  1292. break;
  1293. }
  1294. token += String.fromCharCode(ch);
  1295. ch = data[offset];
  1296. }
  1297. return token;
  1298. }
  1299. function skipUntil(data, offset, what) {
  1300. var length = what.length,
  1301. dataLength = data.length;
  1302. var skipped = 0;
  1303. while (offset < dataLength) {
  1304. var i = 0;
  1305. while (i < length && data[offset + i] === what[i]) {
  1306. ++i;
  1307. }
  1308. if (i >= length) {
  1309. break;
  1310. }
  1311. offset++;
  1312. skipped++;
  1313. }
  1314. return skipped;
  1315. }
  1316. var objRegExp = /^(\d+)\s+(\d+)\s+obj\b/;
  1317. const endobjRegExp = /\bendobj[\b\s]$/;
  1318. const nestedObjRegExp = /\s+(\d+\s+\d+\s+obj[\b\s<])$/;
  1319. const CHECK_CONTENT_LENGTH = 25;
  1320. var trailerBytes = new Uint8Array([116, 114, 97, 105, 108, 101, 114]);
  1321. var startxrefBytes = new Uint8Array([115, 116, 97, 114, 116, 120, 114, 101, 102]);
  1322. const objBytes = new Uint8Array([111, 98, 106]);
  1323. var xrefBytes = new Uint8Array([47, 88, 82, 101, 102]);
  1324. this.entries.length = 0;
  1325. var stream = this.stream;
  1326. stream.pos = 0;
  1327. var buffer = stream.getBytes();
  1328. var position = stream.start,
  1329. length = buffer.length;
  1330. var trailers = [],
  1331. xrefStms = [];
  1332. while (position < length) {
  1333. var ch = buffer[position];
  1334. if (ch === TAB || ch === LF || ch === CR || ch === SPACE) {
  1335. ++position;
  1336. continue;
  1337. }
  1338. if (ch === PERCENT) {
  1339. do {
  1340. ++position;
  1341. if (position >= length) {
  1342. break;
  1343. }
  1344. ch = buffer[position];
  1345. } while (ch !== LF && ch !== CR);
  1346. continue;
  1347. }
  1348. var token = readToken(buffer, position);
  1349. var m;
  1350. if (token.startsWith("xref") && (token.length === 4 || /\s/.test(token[4]))) {
  1351. position += skipUntil(buffer, position, trailerBytes);
  1352. trailers.push(position);
  1353. position += skipUntil(buffer, position, startxrefBytes);
  1354. } else if (m = objRegExp.exec(token)) {
  1355. const num = m[1] | 0,
  1356. gen = m[2] | 0;
  1357. if (!this.entries[num] || this.entries[num].gen === gen) {
  1358. this.entries[num] = {
  1359. offset: position - stream.start,
  1360. gen,
  1361. uncompressed: true
  1362. };
  1363. }
  1364. let contentLength,
  1365. startPos = position + token.length;
  1366. while (startPos < buffer.length) {
  1367. const endPos = startPos + skipUntil(buffer, startPos, objBytes) + 4;
  1368. contentLength = endPos - position;
  1369. const checkPos = Math.max(endPos - CHECK_CONTENT_LENGTH, startPos);
  1370. const tokenStr = (0, _util.bytesToString)(buffer.subarray(checkPos, endPos));
  1371. if (endobjRegExp.test(tokenStr)) {
  1372. break;
  1373. } else {
  1374. const objToken = nestedObjRegExp.exec(tokenStr);
  1375. if (objToken && objToken[1]) {
  1376. (0, _util.warn)('indexObjects: Found new "obj" inside of another "obj", ' + 'caused by missing "endobj" -- trying to recover.');
  1377. contentLength -= objToken[1].length;
  1378. break;
  1379. }
  1380. }
  1381. startPos = endPos;
  1382. }
  1383. const content = buffer.subarray(position, position + contentLength);
  1384. var xrefTagOffset = skipUntil(content, 0, xrefBytes);
  1385. if (xrefTagOffset < contentLength && content[xrefTagOffset + 5] < 64) {
  1386. xrefStms.push(position - stream.start);
  1387. this.xrefstms[position - stream.start] = 1;
  1388. }
  1389. position += contentLength;
  1390. } else if (token.startsWith("trailer") && (token.length === 7 || /\s/.test(token[7]))) {
  1391. trailers.push(position);
  1392. position += skipUntil(buffer, position, startxrefBytes);
  1393. } else {
  1394. position += token.length + 1;
  1395. }
  1396. }
  1397. var i, ii;
  1398. for (i = 0, ii = xrefStms.length; i < ii; ++i) {
  1399. this.startXRefQueue.push(xrefStms[i]);
  1400. this.readXRef(true);
  1401. }
  1402. let trailerDict;
  1403. for (i = 0, ii = trailers.length; i < ii; ++i) {
  1404. stream.pos = trailers[i];
  1405. const parser = new _parser.Parser({
  1406. lexer: new _parser.Lexer(stream),
  1407. xref: this,
  1408. allowStreams: true,
  1409. recoveryMode: true
  1410. });
  1411. var obj = parser.getObj();
  1412. if (!(0, _primitives.isCmd)(obj, "trailer")) {
  1413. continue;
  1414. }
  1415. const dict = parser.getObj();
  1416. if (!(0, _primitives.isDict)(dict)) {
  1417. continue;
  1418. }
  1419. let rootDict;
  1420. try {
  1421. rootDict = dict.get("Root");
  1422. } catch (ex) {
  1423. if (ex instanceof _core_utils.MissingDataException) {
  1424. throw ex;
  1425. }
  1426. continue;
  1427. }
  1428. if (!(0, _primitives.isDict)(rootDict) || !rootDict.has("Pages")) {
  1429. continue;
  1430. }
  1431. if (dict.has("ID")) {
  1432. return dict;
  1433. }
  1434. trailerDict = dict;
  1435. }
  1436. if (trailerDict) {
  1437. return trailerDict;
  1438. }
  1439. throw new _util.InvalidPDFException("Invalid PDF structure.");
  1440. },
  1441. readXRef: function XRef_readXRef(recoveryMode) {
  1442. var stream = this.stream;
  1443. const startXRefParsedCache = Object.create(null);
  1444. try {
  1445. while (this.startXRefQueue.length) {
  1446. var startXRef = this.startXRefQueue[0];
  1447. if (startXRefParsedCache[startXRef]) {
  1448. (0, _util.warn)("readXRef - skipping XRef table since it was already parsed.");
  1449. this.startXRefQueue.shift();
  1450. continue;
  1451. }
  1452. startXRefParsedCache[startXRef] = true;
  1453. stream.pos = startXRef + stream.start;
  1454. const parser = new _parser.Parser({
  1455. lexer: new _parser.Lexer(stream),
  1456. xref: this,
  1457. allowStreams: true
  1458. });
  1459. var obj = parser.getObj();
  1460. var dict;
  1461. if ((0, _primitives.isCmd)(obj, "xref")) {
  1462. dict = this.processXRefTable(parser);
  1463. if (!this.topDict) {
  1464. this.topDict = dict;
  1465. }
  1466. obj = dict.get("XRefStm");
  1467. if (Number.isInteger(obj)) {
  1468. var pos = obj;
  1469. if (!(pos in this.xrefstms)) {
  1470. this.xrefstms[pos] = 1;
  1471. this.startXRefQueue.push(pos);
  1472. }
  1473. }
  1474. } else if (Number.isInteger(obj)) {
  1475. if (!Number.isInteger(parser.getObj()) || !(0, _primitives.isCmd)(parser.getObj(), "obj") || !(0, _primitives.isStream)(obj = parser.getObj())) {
  1476. throw new _util.FormatError("Invalid XRef stream");
  1477. }
  1478. dict = this.processXRefStream(obj);
  1479. if (!this.topDict) {
  1480. this.topDict = dict;
  1481. }
  1482. if (!dict) {
  1483. throw new _util.FormatError("Failed to read XRef stream");
  1484. }
  1485. } else {
  1486. throw new _util.FormatError("Invalid XRef stream header");
  1487. }
  1488. obj = dict.get("Prev");
  1489. if (Number.isInteger(obj)) {
  1490. this.startXRefQueue.push(obj);
  1491. } else if ((0, _primitives.isRef)(obj)) {
  1492. this.startXRefQueue.push(obj.num);
  1493. }
  1494. this.startXRefQueue.shift();
  1495. }
  1496. return this.topDict;
  1497. } catch (e) {
  1498. if (e instanceof _core_utils.MissingDataException) {
  1499. throw e;
  1500. }
  1501. (0, _util.info)("(while reading XRef): " + e);
  1502. }
  1503. if (recoveryMode) {
  1504. return undefined;
  1505. }
  1506. throw new _core_utils.XRefParseException();
  1507. },
  1508. getEntry: function XRef_getEntry(i) {
  1509. var xrefEntry = this.entries[i];
  1510. if (xrefEntry && !xrefEntry.free && xrefEntry.offset) {
  1511. return xrefEntry;
  1512. }
  1513. return null;
  1514. },
  1515. fetchIfRef: function XRef_fetchIfRef(obj, suppressEncryption) {
  1516. if (obj instanceof _primitives.Ref) {
  1517. return this.fetch(obj, suppressEncryption);
  1518. }
  1519. return obj;
  1520. },
  1521. fetch: function XRef_fetch(ref, suppressEncryption) {
  1522. if (!(ref instanceof _primitives.Ref)) {
  1523. throw new Error("ref object is not a reference");
  1524. }
  1525. const num = ref.num;
  1526. const cacheEntry = this._cacheMap.get(num);
  1527. if (cacheEntry !== undefined) {
  1528. if (cacheEntry instanceof _primitives.Dict && !cacheEntry.objId) {
  1529. cacheEntry.objId = ref.toString();
  1530. }
  1531. return cacheEntry;
  1532. }
  1533. let xrefEntry = this.getEntry(num);
  1534. if (xrefEntry === null) {
  1535. this._cacheMap.set(num, xrefEntry);
  1536. return xrefEntry;
  1537. }
  1538. if (xrefEntry.uncompressed) {
  1539. xrefEntry = this.fetchUncompressed(ref, xrefEntry, suppressEncryption);
  1540. } else {
  1541. xrefEntry = this.fetchCompressed(ref, xrefEntry, suppressEncryption);
  1542. }
  1543. if ((0, _primitives.isDict)(xrefEntry)) {
  1544. xrefEntry.objId = ref.toString();
  1545. } else if ((0, _primitives.isStream)(xrefEntry)) {
  1546. xrefEntry.dict.objId = ref.toString();
  1547. }
  1548. return xrefEntry;
  1549. },
  1550. fetchUncompressed(ref, xrefEntry, suppressEncryption = false) {
  1551. var gen = ref.gen;
  1552. var num = ref.num;
  1553. if (xrefEntry.gen !== gen) {
  1554. throw new _core_utils.XRefEntryException(`Inconsistent generation in XRef: ${ref}`);
  1555. }
  1556. var stream = this.stream.makeSubStream(xrefEntry.offset + this.stream.start);
  1557. const parser = new _parser.Parser({
  1558. lexer: new _parser.Lexer(stream),
  1559. xref: this,
  1560. allowStreams: true
  1561. });
  1562. var obj1 = parser.getObj();
  1563. var obj2 = parser.getObj();
  1564. var obj3 = parser.getObj();
  1565. if (obj1 !== num || obj2 !== gen || !(obj3 instanceof _primitives.Cmd)) {
  1566. throw new _core_utils.XRefEntryException(`Bad (uncompressed) XRef entry: ${ref}`);
  1567. }
  1568. if (obj3.cmd !== "obj") {
  1569. if (obj3.cmd.startsWith("obj")) {
  1570. num = parseInt(obj3.cmd.substring(3), 10);
  1571. if (!Number.isNaN(num)) {
  1572. return num;
  1573. }
  1574. }
  1575. throw new _core_utils.XRefEntryException(`Bad (uncompressed) XRef entry: ${ref}`);
  1576. }
  1577. if (this.encrypt && !suppressEncryption) {
  1578. xrefEntry = parser.getObj(this.encrypt.createCipherTransform(num, gen));
  1579. } else {
  1580. xrefEntry = parser.getObj();
  1581. }
  1582. if (!(0, _primitives.isStream)(xrefEntry)) {
  1583. this._cacheMap.set(num, xrefEntry);
  1584. }
  1585. return xrefEntry;
  1586. },
  1587. fetchCompressed(ref, xrefEntry, suppressEncryption = false) {
  1588. const tableOffset = xrefEntry.offset;
  1589. const stream = this.fetch(_primitives.Ref.get(tableOffset, 0));
  1590. if (!(0, _primitives.isStream)(stream)) {
  1591. throw new _util.FormatError("bad ObjStm stream");
  1592. }
  1593. const first = stream.dict.get("First");
  1594. const n = stream.dict.get("N");
  1595. if (!Number.isInteger(first) || !Number.isInteger(n)) {
  1596. throw new _util.FormatError("invalid first and n parameters for ObjStm stream");
  1597. }
  1598. const parser = new _parser.Parser({
  1599. lexer: new _parser.Lexer(stream),
  1600. xref: this,
  1601. allowStreams: true
  1602. });
  1603. const nums = new Array(n);
  1604. for (let i = 0; i < n; ++i) {
  1605. const num = parser.getObj();
  1606. if (!Number.isInteger(num)) {
  1607. throw new _util.FormatError(`invalid object number in the ObjStm stream: ${num}`);
  1608. }
  1609. const offset = parser.getObj();
  1610. if (!Number.isInteger(offset)) {
  1611. throw new _util.FormatError(`invalid object offset in the ObjStm stream: ${offset}`);
  1612. }
  1613. nums[i] = num;
  1614. }
  1615. const entries = new Array(n);
  1616. for (let i = 0; i < n; ++i) {
  1617. const obj = parser.getObj();
  1618. entries[i] = obj;
  1619. if (parser.buf1 instanceof _primitives.Cmd && parser.buf1.cmd === "endobj") {
  1620. parser.shift();
  1621. }
  1622. if ((0, _primitives.isStream)(obj)) {
  1623. continue;
  1624. }
  1625. const num = nums[i],
  1626. entry = this.entries[num];
  1627. if (entry && entry.offset === tableOffset && entry.gen === i) {
  1628. this._cacheMap.set(num, obj);
  1629. }
  1630. }
  1631. xrefEntry = entries[xrefEntry.gen];
  1632. if (xrefEntry === undefined) {
  1633. throw new _core_utils.XRefEntryException(`Bad (compressed) XRef entry: ${ref}`);
  1634. }
  1635. return xrefEntry;
  1636. },
  1637. async fetchIfRefAsync(obj, suppressEncryption) {
  1638. if (obj instanceof _primitives.Ref) {
  1639. return this.fetchAsync(obj, suppressEncryption);
  1640. }
  1641. return obj;
  1642. },
  1643. async fetchAsync(ref, suppressEncryption) {
  1644. try {
  1645. return this.fetch(ref, suppressEncryption);
  1646. } catch (ex) {
  1647. if (!(ex instanceof _core_utils.MissingDataException)) {
  1648. throw ex;
  1649. }
  1650. await this.pdfManager.requestRange(ex.begin, ex.end);
  1651. return this.fetchAsync(ref, suppressEncryption);
  1652. }
  1653. },
  1654. getCatalogObj: function XRef_getCatalogObj() {
  1655. return this.root;
  1656. }
  1657. };
  1658. return XRef;
  1659. }();
  1660. exports.XRef = XRef;
  1661. class NameOrNumberTree {
  1662. constructor(root, xref, type) {
  1663. if (this.constructor === NameOrNumberTree) {
  1664. (0, _util.unreachable)("Cannot initialize NameOrNumberTree.");
  1665. }
  1666. this.root = root;
  1667. this.xref = xref;
  1668. this._type = type;
  1669. }
  1670. getAll() {
  1671. const dict = Object.create(null);
  1672. if (!this.root) {
  1673. return dict;
  1674. }
  1675. const xref = this.xref;
  1676. const processed = new _primitives.RefSet();
  1677. processed.put(this.root);
  1678. const queue = [this.root];
  1679. while (queue.length > 0) {
  1680. const obj = xref.fetchIfRef(queue.shift());
  1681. if (!(0, _primitives.isDict)(obj)) {
  1682. continue;
  1683. }
  1684. if (obj.has("Kids")) {
  1685. const kids = obj.get("Kids");
  1686. for (let i = 0, ii = kids.length; i < ii; i++) {
  1687. const kid = kids[i];
  1688. if (processed.has(kid)) {
  1689. throw new _util.FormatError(`Duplicate entry in "${this._type}" tree.`);
  1690. }
  1691. queue.push(kid);
  1692. processed.put(kid);
  1693. }
  1694. continue;
  1695. }
  1696. const entries = obj.get(this._type);
  1697. if (Array.isArray(entries)) {
  1698. for (let i = 0, ii = entries.length; i < ii; i += 2) {
  1699. dict[xref.fetchIfRef(entries[i])] = xref.fetchIfRef(entries[i + 1]);
  1700. }
  1701. }
  1702. }
  1703. return dict;
  1704. }
  1705. get(key) {
  1706. if (!this.root) {
  1707. return null;
  1708. }
  1709. const xref = this.xref;
  1710. let kidsOrEntries = xref.fetchIfRef(this.root);
  1711. let loopCount = 0;
  1712. const MAX_LEVELS = 10;
  1713. while (kidsOrEntries.has("Kids")) {
  1714. if (++loopCount > MAX_LEVELS) {
  1715. (0, _util.warn)(`Search depth limit reached for "${this._type}" tree.`);
  1716. return null;
  1717. }
  1718. const kids = kidsOrEntries.get("Kids");
  1719. if (!Array.isArray(kids)) {
  1720. return null;
  1721. }
  1722. let l = 0,
  1723. r = kids.length - 1;
  1724. while (l <= r) {
  1725. const m = l + r >> 1;
  1726. const kid = xref.fetchIfRef(kids[m]);
  1727. const limits = kid.get("Limits");
  1728. if (key < xref.fetchIfRef(limits[0])) {
  1729. r = m - 1;
  1730. } else if (key > xref.fetchIfRef(limits[1])) {
  1731. l = m + 1;
  1732. } else {
  1733. kidsOrEntries = xref.fetchIfRef(kids[m]);
  1734. break;
  1735. }
  1736. }
  1737. if (l > r) {
  1738. return null;
  1739. }
  1740. }
  1741. const entries = kidsOrEntries.get(this._type);
  1742. if (Array.isArray(entries)) {
  1743. let l = 0,
  1744. r = entries.length - 2;
  1745. while (l <= r) {
  1746. const tmp = l + r >> 1,
  1747. m = tmp + (tmp & 1);
  1748. const currentKey = xref.fetchIfRef(entries[m]);
  1749. if (key < currentKey) {
  1750. r = m - 2;
  1751. } else if (key > currentKey) {
  1752. l = m + 2;
  1753. } else {
  1754. return xref.fetchIfRef(entries[m + 1]);
  1755. }
  1756. }
  1757. (0, _util.info)(`Falling back to an exhaustive search, for key "${key}", ` + `in "${this._type}" tree.`);
  1758. for (let m = 0, mm = entries.length; m < mm; m += 2) {
  1759. const currentKey = xref.fetchIfRef(entries[m]);
  1760. if (currentKey === key) {
  1761. (0, _util.warn)(`The "${key}" key was found at an incorrect, ` + `i.e. out-of-order, position in "${this._type}" tree.`);
  1762. return xref.fetchIfRef(entries[m + 1]);
  1763. }
  1764. }
  1765. }
  1766. return null;
  1767. }
  1768. }
  1769. class NameTree extends NameOrNumberTree {
  1770. constructor(root, xref) {
  1771. super(root, xref, "Names");
  1772. }
  1773. }
  1774. class NumberTree extends NameOrNumberTree {
  1775. constructor(root, xref) {
  1776. super(root, xref, "Nums");
  1777. }
  1778. }
  1779. var FileSpec = function FileSpecClosure() {
  1780. function FileSpec(root, xref) {
  1781. if (!root || !(0, _primitives.isDict)(root)) {
  1782. return;
  1783. }
  1784. this.xref = xref;
  1785. this.root = root;
  1786. if (root.has("FS")) {
  1787. this.fs = root.get("FS");
  1788. }
  1789. this.description = root.has("Desc") ? (0, _util.stringToPDFString)(root.get("Desc")) : "";
  1790. if (root.has("RF")) {
  1791. (0, _util.warn)("Related file specifications are not supported");
  1792. }
  1793. this.contentAvailable = true;
  1794. if (!root.has("EF")) {
  1795. this.contentAvailable = false;
  1796. (0, _util.warn)("Non-embedded file specifications are not supported");
  1797. }
  1798. }
  1799. function pickPlatformItem(dict) {
  1800. if (dict.has("UF")) {
  1801. return dict.get("UF");
  1802. } else if (dict.has("F")) {
  1803. return dict.get("F");
  1804. } else if (dict.has("Unix")) {
  1805. return dict.get("Unix");
  1806. } else if (dict.has("Mac")) {
  1807. return dict.get("Mac");
  1808. } else if (dict.has("DOS")) {
  1809. return dict.get("DOS");
  1810. }
  1811. return null;
  1812. }
  1813. FileSpec.prototype = {
  1814. get filename() {
  1815. if (!this._filename && this.root) {
  1816. var filename = pickPlatformItem(this.root) || "unnamed";
  1817. this._filename = (0, _util.stringToPDFString)(filename).replace(/\\\\/g, "\\").replace(/\\\//g, "/").replace(/\\/g, "/");
  1818. }
  1819. return this._filename;
  1820. },
  1821. get content() {
  1822. if (!this.contentAvailable) {
  1823. return null;
  1824. }
  1825. if (!this.contentRef && this.root) {
  1826. this.contentRef = pickPlatformItem(this.root.get("EF"));
  1827. }
  1828. var content = null;
  1829. if (this.contentRef) {
  1830. var xref = this.xref;
  1831. var fileObj = xref.fetchIfRef(this.contentRef);
  1832. if (fileObj && (0, _primitives.isStream)(fileObj)) {
  1833. content = fileObj.getBytes();
  1834. } else {
  1835. (0, _util.warn)("Embedded file specification points to non-existing/invalid " + "content");
  1836. }
  1837. } else {
  1838. (0, _util.warn)("Embedded file specification does not have a content");
  1839. }
  1840. return content;
  1841. },
  1842. get serializable() {
  1843. return {
  1844. filename: this.filename,
  1845. content: this.content
  1846. };
  1847. }
  1848. };
  1849. return FileSpec;
  1850. }();
  1851. exports.FileSpec = FileSpec;
  1852. const ObjectLoader = function () {
  1853. function mayHaveChildren(value) {
  1854. return value instanceof _primitives.Ref || value instanceof _primitives.Dict || Array.isArray(value) || (0, _primitives.isStream)(value);
  1855. }
  1856. function addChildren(node, nodesToVisit) {
  1857. if (node instanceof _primitives.Dict) {
  1858. node = node.getRawValues();
  1859. } else if ((0, _primitives.isStream)(node)) {
  1860. node = node.dict.getRawValues();
  1861. } else if (!Array.isArray(node)) {
  1862. return;
  1863. }
  1864. for (const rawValue of node) {
  1865. if (mayHaveChildren(rawValue)) {
  1866. nodesToVisit.push(rawValue);
  1867. }
  1868. }
  1869. }
  1870. function ObjectLoader(dict, keys, xref) {
  1871. this.dict = dict;
  1872. this.keys = keys;
  1873. this.xref = xref;
  1874. this.refSet = null;
  1875. }
  1876. ObjectLoader.prototype = {
  1877. async load() {
  1878. if (!this.xref.stream.allChunksLoaded || this.xref.stream.allChunksLoaded()) {
  1879. return undefined;
  1880. }
  1881. const {
  1882. keys,
  1883. dict
  1884. } = this;
  1885. this.refSet = new _primitives.RefSet();
  1886. const nodesToVisit = [];
  1887. for (let i = 0, ii = keys.length; i < ii; i++) {
  1888. const rawValue = dict.getRaw(keys[i]);
  1889. if (rawValue !== undefined) {
  1890. nodesToVisit.push(rawValue);
  1891. }
  1892. }
  1893. return this._walk(nodesToVisit);
  1894. },
  1895. async _walk(nodesToVisit) {
  1896. const nodesToRevisit = [];
  1897. const pendingRequests = [];
  1898. while (nodesToVisit.length) {
  1899. let currentNode = nodesToVisit.pop();
  1900. if (currentNode instanceof _primitives.Ref) {
  1901. if (this.refSet.has(currentNode)) {
  1902. continue;
  1903. }
  1904. try {
  1905. this.refSet.put(currentNode);
  1906. currentNode = this.xref.fetch(currentNode);
  1907. } catch (ex) {
  1908. if (!(ex instanceof _core_utils.MissingDataException)) {
  1909. throw ex;
  1910. }
  1911. nodesToRevisit.push(currentNode);
  1912. pendingRequests.push({
  1913. begin: ex.begin,
  1914. end: ex.end
  1915. });
  1916. }
  1917. }
  1918. if (currentNode && currentNode.getBaseStreams) {
  1919. const baseStreams = currentNode.getBaseStreams();
  1920. let foundMissingData = false;
  1921. for (let i = 0, ii = baseStreams.length; i < ii; i++) {
  1922. const stream = baseStreams[i];
  1923. if (stream.allChunksLoaded && !stream.allChunksLoaded()) {
  1924. foundMissingData = true;
  1925. pendingRequests.push({
  1926. begin: stream.start,
  1927. end: stream.end
  1928. });
  1929. }
  1930. }
  1931. if (foundMissingData) {
  1932. nodesToRevisit.push(currentNode);
  1933. }
  1934. }
  1935. addChildren(currentNode, nodesToVisit);
  1936. }
  1937. if (pendingRequests.length) {
  1938. await this.xref.stream.manager.requestRanges(pendingRequests);
  1939. for (let i = 0, ii = nodesToRevisit.length; i < ii; i++) {
  1940. const node = nodesToRevisit[i];
  1941. if (node instanceof _primitives.Ref) {
  1942. this.refSet.remove(node);
  1943. }
  1944. }
  1945. return this._walk(nodesToRevisit);
  1946. }
  1947. this.refSet = null;
  1948. return undefined;
  1949. }
  1950. };
  1951. return ObjectLoader;
  1952. }();
  1953. exports.ObjectLoader = ObjectLoader;