modern-pdf-lib 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_pdfPage = require('./pdfPage-BebMv6fN.cjs');
3
- const require_pdfCatalog = require('./pdfCatalog-y_XG8Hq1.cjs');
2
+ const require_pdfPage = require('./pdfPage-DBfdinTR.cjs');
3
+ const require_pdfCatalog = require('./pdfCatalog-COKoYQ8C.cjs');
4
4
  const require_libdeflateWasm = require('./libdeflateWasm-OkNoqBnO.cjs');
5
5
  const require_fontSubset = require('./fontSubset-pFc8Dueu.cjs');
6
6
  const require_pngEmbed = require('./pngEmbed-OYyOe_W0.cjs');
@@ -200,20 +200,19 @@ var PdfWriter = class {
200
200
  */
201
201
  writeObjectStream(entries, xrefEntries) {
202
202
  const serializedObjects = [];
203
- new StringByteWriter();
204
203
  for (const entry of entries) {
205
204
  const objWriter = new StringByteWriter();
206
205
  entry.object.serialize(objWriter);
207
206
  serializedObjects.push(objWriter.toUint8Array());
208
207
  }
209
- let headerStr = "";
208
+ const headerParts = [];
210
209
  let dataOffset = 0;
211
210
  for (let i = 0; i < entries.length; i++) {
212
- if (i > 0) headerStr += " ";
213
- headerStr += `${entries[i].ref.objectNumber} ${dataOffset}`;
211
+ headerParts.push(`${entries[i].ref.objectNumber} ${dataOffset}`);
214
212
  dataOffset += serializedObjects[i].length;
215
213
  if (i < entries.length - 1) dataOffset += 1;
216
214
  }
215
+ const headerStr = headerParts.join(" ");
217
216
  const headerBytes = encoder$5.encode(headerStr + " ");
218
217
  const firstOffset = headerBytes.length;
219
218
  let totalDataLen = firstOffset;
@@ -3755,7 +3754,7 @@ const isDelimiter = /* @__PURE__ */ (() => {
3755
3754
  * `hexVal[b]` is the numeric value (0-15) of a hex character, or -1 if
3756
3755
  * the byte is not a valid hex digit.
3757
3756
  */
3758
- const hexVal = /* @__PURE__ */ (() => {
3757
+ const hexVal$1 = /* @__PURE__ */ (() => {
3759
3758
  const t = new Int8Array(256).fill(-1);
3760
3759
  for (let i = 0; i <= 9; i++) t[CH_0 + i] = i;
3761
3760
  for (let i = 0; i < 6; i++) {
@@ -4052,7 +4051,7 @@ var PdfLexer = class {
4052
4051
  const d = this._data;
4053
4052
  let pos = startPos + 1;
4054
4053
  let depth = 1;
4055
- let result = "";
4054
+ const parts = [];
4056
4055
  while (pos < this.len && depth > 0) {
4057
4056
  const c = d[pos];
4058
4057
  if (c === CH_BACKSLASH) {
@@ -4061,35 +4060,35 @@ var PdfLexer = class {
4061
4060
  const esc = d[pos];
4062
4061
  switch (esc) {
4063
4062
  case 110:
4064
- result += "\n";
4063
+ parts.push("\n");
4065
4064
  pos++;
4066
4065
  break;
4067
4066
  case 114:
4068
- result += "\r";
4067
+ parts.push("\r");
4069
4068
  pos++;
4070
4069
  break;
4071
4070
  case 116:
4072
- result += " ";
4071
+ parts.push(" ");
4073
4072
  pos++;
4074
4073
  break;
4075
4074
  case 98:
4076
- result += "\b";
4075
+ parts.push("\b");
4077
4076
  pos++;
4078
4077
  break;
4079
4078
  case 102:
4080
- result += "\f";
4079
+ parts.push("\f");
4081
4080
  pos++;
4082
4081
  break;
4083
4082
  case CH_LPAREN:
4084
- result += "(";
4083
+ parts.push("(");
4085
4084
  pos++;
4086
4085
  break;
4087
4086
  case CH_RPAREN:
4088
- result += ")";
4087
+ parts.push(")");
4089
4088
  pos++;
4090
4089
  break;
4091
4090
  case CH_BACKSLASH:
4092
- result += "\\";
4091
+ parts.push("\\");
4093
4092
  pos++;
4094
4093
  break;
4095
4094
  case WS_LF:
@@ -4111,9 +4110,9 @@ var PdfLexer = class {
4111
4110
  pos++;
4112
4111
  }
4113
4112
  }
4114
- result += String.fromCharCode(octal & 255);
4113
+ parts.push(String.fromCharCode(octal & 255));
4115
4114
  } else {
4116
- result += String.fromCharCode(esc);
4115
+ parts.push(String.fromCharCode(esc));
4117
4116
  pos++;
4118
4117
  }
4119
4118
  break;
@@ -4122,23 +4121,23 @@ var PdfLexer = class {
4122
4121
  }
4123
4122
  if (c === CH_LPAREN) {
4124
4123
  depth++;
4125
- result += "(";
4124
+ parts.push("(");
4126
4125
  pos++;
4127
4126
  continue;
4128
4127
  }
4129
4128
  if (c === CH_RPAREN) {
4130
4129
  depth--;
4131
- if (depth > 0) result += ")";
4130
+ if (depth > 0) parts.push(")");
4132
4131
  pos++;
4133
4132
  continue;
4134
4133
  }
4135
4134
  if (c === WS_CR) {
4136
- result += "\n";
4135
+ parts.push("\n");
4137
4136
  pos++;
4138
4137
  if (pos < this.len && d[pos] === WS_LF) pos++;
4139
4138
  continue;
4140
4139
  }
4141
- result += String.fromCharCode(c);
4140
+ parts.push(String.fromCharCode(c));
4142
4141
  pos++;
4143
4142
  }
4144
4143
  if (depth !== 0) throw new PdfParseError({
@@ -4151,7 +4150,7 @@ var PdfLexer = class {
4151
4150
  this.position = pos;
4152
4151
  return {
4153
4152
  type: TokenType$1.LiteralString,
4154
- value: result,
4153
+ value: parts.join(""),
4155
4154
  offset: startPos
4156
4155
  };
4157
4156
  }
@@ -4164,7 +4163,8 @@ var PdfLexer = class {
4164
4163
  readHexString(startPos) {
4165
4164
  const d = this._data;
4166
4165
  let pos = startPos + 1;
4167
- let hex = "";
4166
+ const bytes = [];
4167
+ let hi = -1;
4168
4168
  while (pos < this.len) {
4169
4169
  const c = d[pos];
4170
4170
  if (c === CH_GT) {
@@ -4175,27 +4175,26 @@ var PdfLexer = class {
4175
4175
  pos++;
4176
4176
  continue;
4177
4177
  }
4178
- if (hexVal[c] === -1) throw new PdfParseError({
4178
+ const v = hexVal$1[c];
4179
+ if (v === -1) throw new PdfParseError({
4179
4180
  message: `PdfLexer: invalid hex digit 0x${c.toString(16).padStart(2, "0")} at offset ${pos} in hex string starting at ${startPos}`,
4180
4181
  offset: pos,
4181
4182
  expected: "hex digit (0-9, a-f, A-F)",
4182
4183
  actual: `0x${c.toString(16).padStart(2, "0")}`,
4183
4184
  data: this._data
4184
4185
  });
4185
- hex += String.fromCharCode(c);
4186
+ if (hi === -1) hi = v;
4187
+ else {
4188
+ bytes.push(hi << 4 | v);
4189
+ hi = -1;
4190
+ }
4186
4191
  pos++;
4187
4192
  }
4188
- if (hex.length % 2 !== 0) hex += "0";
4189
- let result = "";
4190
- for (let i = 0; i < hex.length; i += 2) {
4191
- const hi = hexVal[hex.charCodeAt(i)];
4192
- const lo = hexVal[hex.charCodeAt(i + 1)];
4193
- result += String.fromCharCode(hi << 4 | lo);
4194
- }
4193
+ if (hi !== -1) bytes.push(hi << 4);
4195
4194
  this.position = pos;
4196
4195
  return {
4197
4196
  type: TokenType$1.HexString,
4198
- value: result,
4197
+ value: String.fromCharCode.apply(null, bytes),
4199
4198
  offset: startPos
4200
4199
  };
4201
4200
  }
@@ -4208,7 +4207,7 @@ var PdfLexer = class {
4208
4207
  readName(startPos) {
4209
4208
  const d = this._data;
4210
4209
  let pos = startPos + 1;
4211
- let name = "/";
4210
+ const parts = ["/"];
4212
4211
  while (pos < this.len) {
4213
4212
  const c = d[pos];
4214
4213
  if (isWhitespace[c] || isDelimiter[c]) break;
@@ -4220,8 +4219,8 @@ var PdfLexer = class {
4220
4219
  actual: "end of input",
4221
4220
  data: this._data
4222
4221
  });
4223
- const hi = hexVal[d[pos + 1]];
4224
- const lo = hexVal[d[pos + 2]];
4222
+ const hi = hexVal$1[d[pos + 1]];
4223
+ const lo = hexVal$1[d[pos + 2]];
4225
4224
  if (hi === -1 || lo === -1) throw new PdfParseError({
4226
4225
  message: `PdfLexer: invalid #XX escape in name at offset ${pos}`,
4227
4226
  offset: pos,
@@ -4229,17 +4228,17 @@ var PdfLexer = class {
4229
4228
  actual: `#${String.fromCharCode(d[pos + 1])}${String.fromCharCode(d[pos + 2])}`,
4230
4229
  data: this._data
4231
4230
  });
4232
- name += String.fromCharCode(hi << 4 | lo);
4231
+ parts.push(String.fromCharCode(hi << 4 | lo));
4233
4232
  pos += 3;
4234
4233
  continue;
4235
4234
  }
4236
- name += String.fromCharCode(c);
4235
+ parts.push(String.fromCharCode(c));
4237
4236
  pos++;
4238
4237
  }
4239
4238
  this.position = pos;
4240
4239
  return {
4241
4240
  type: TokenType$1.Name,
4242
- value: name,
4241
+ value: parts.join(""),
4243
4242
  offset: startPos
4244
4243
  };
4245
4244
  }
@@ -4354,10 +4353,7 @@ var PdfLexer = class {
4354
4353
  * because it avoids the per-call overhead of the streaming decoder.
4355
4354
  */
4356
4355
  bytesToAscii(from, to) {
4357
- const d = this._data;
4358
- let s = "";
4359
- for (let i = from; i < to; i++) s += String.fromCharCode(d[i]);
4360
- return s;
4356
+ return String.fromCharCode.apply(null, this._data.subarray(from, to));
4361
4357
  }
4362
4358
  };
4363
4359
 
@@ -5251,18 +5247,20 @@ var XrefParser = class {
5251
5247
  parseTraditionalXref(offset) {
5252
5248
  const entries = [];
5253
5249
  let pos = offset;
5254
- const xrefTag = TEXT_DECODER$1.decode(this.data.subarray(pos, pos + 4));
5255
- if (xrefTag !== "xref") throw new PdfParseError({
5256
- message: `Invalid PDF: expected "xref" keyword at offset ${offset}, found "${xrefTag}".`,
5257
- offset,
5258
- expected: "\"xref\" keyword",
5259
- actual: `"${xrefTag}"`,
5260
- data: this.data
5261
- });
5250
+ if (!this.isTraditionalXref(pos)) {
5251
+ const xrefTag = TEXT_DECODER$1.decode(this.data.subarray(pos, pos + 4));
5252
+ throw new PdfParseError({
5253
+ message: `Invalid PDF: expected "xref" keyword at offset ${offset}, found "${xrefTag}".`,
5254
+ offset,
5255
+ expected: "\"xref\" keyword",
5256
+ actual: `"${xrefTag}"`,
5257
+ data: this.data
5258
+ });
5259
+ }
5262
5260
  pos += 4;
5263
5261
  pos = this.skipWhitespaceAt(pos);
5264
5262
  while (pos < this.data.length) {
5265
- if (TEXT_DECODER$1.decode(this.data.subarray(pos, Math.min(pos + 7, this.data.length))).startsWith("trailer")) break;
5263
+ if (this.matchesBytes(pos, 116, 114, 97, 105, 108, 101, 114)) break;
5266
5264
  const headerLine = this.readLineAt(pos);
5267
5265
  const headerMatch = headerLine.text.trim().match(/^(\d+)\s+(\d+)/);
5268
5266
  if (!headerMatch) throw new PdfParseError({
@@ -5277,35 +5275,45 @@ var XrefParser = class {
5277
5275
  pos = headerLine.nextPos;
5278
5276
  for (let i = 0; i < count; i++) {
5279
5277
  const objectNumber = firstObjNum + i;
5280
- const entryText = this.readXrefEntryAt(pos);
5281
- const entryMatch = entryText.text.trim().match(/^(\d{10})\s+(\d{5})\s+([fn])/);
5282
- if (!entryMatch) throw new PdfParseError({
5283
- message: `Invalid PDF: malformed xref entry at offset ${pos} for object ${objectNumber}: "${entryText.text.trim()}"`,
5284
- offset: pos,
5285
- expected: "xref entry \"OOOOOOOOOO GGGGG f/n\"",
5286
- actual: `"${entryText.text.trim()}"`,
5287
- data: this.data
5288
- });
5289
- const entryOffset = parseInt(entryMatch[1], 10);
5290
- const gen = parseInt(entryMatch[2], 10);
5291
- const marker = entryMatch[3];
5292
- entries.push({
5293
- objectNumber,
5294
- generationNumber: gen,
5295
- offset: entryOffset,
5296
- type: marker === "n" ? "in-use" : "free"
5297
- });
5298
- pos = entryText.nextPos;
5278
+ const parsed = this.parseXrefEntryDirect(pos);
5279
+ if (parsed) {
5280
+ entries.push({
5281
+ objectNumber,
5282
+ generationNumber: parsed.gen,
5283
+ offset: parsed.offset,
5284
+ type: parsed.type
5285
+ });
5286
+ pos = parsed.nextPos;
5287
+ } else {
5288
+ const entryText = this.readXrefEntryAt(pos);
5289
+ const entryMatch = entryText.text.trim().match(/^(\d{10})\s+(\d{5})\s+([fn])/);
5290
+ if (!entryMatch) throw new PdfParseError({
5291
+ message: `Invalid PDF: malformed xref entry at offset ${pos} for object ${objectNumber}: "${entryText.text.trim()}"`,
5292
+ offset: pos,
5293
+ expected: "xref entry \"OOOOOOOOOO GGGGG f/n\"",
5294
+ actual: `"${entryText.text.trim()}"`,
5295
+ data: this.data
5296
+ });
5297
+ entries.push({
5298
+ objectNumber,
5299
+ generationNumber: parseInt(entryMatch[2], 10),
5300
+ offset: parseInt(entryMatch[1], 10),
5301
+ type: entryMatch[3] === "n" ? "in-use" : "free"
5302
+ });
5303
+ pos = entryText.nextPos;
5304
+ }
5299
5305
  }
5300
5306
  }
5301
- const trailerTag = TEXT_DECODER$1.decode(this.data.subarray(pos, pos + 7));
5302
- if (trailerTag !== "trailer") throw new PdfParseError({
5303
- message: `Invalid PDF: expected "trailer" keyword at offset ${pos}, found "${trailerTag}".`,
5304
- offset: pos,
5305
- expected: "\"trailer\" keyword",
5306
- actual: `"${trailerTag}"`,
5307
- data: this.data
5308
- });
5307
+ if (!this.matchesBytes(pos, 116, 114, 97, 105, 108, 101, 114)) {
5308
+ const trailerTag = TEXT_DECODER$1.decode(this.data.subarray(pos, pos + 7));
5309
+ throw new PdfParseError({
5310
+ message: `Invalid PDF: expected "trailer" keyword at offset ${pos}, found "${trailerTag}".`,
5311
+ offset: pos,
5312
+ expected: "\"trailer\" keyword",
5313
+ actual: `"${trailerTag}"`,
5314
+ data: this.data
5315
+ });
5316
+ }
5309
5317
  pos += 7;
5310
5318
  const trailerObj = this.objectParser.parseObjectAt(pos);
5311
5319
  if (trailerObj.kind !== "dict") throw new PdfParseError({
@@ -5460,17 +5468,33 @@ var XrefParser = class {
5460
5468
  */
5461
5469
  rebuildXrefFromScan() {
5462
5470
  const entries = /* @__PURE__ */ new Map();
5463
- const fileText = TEXT_DECODER$1.decode(this.data);
5464
- const objPattern = /(\d+)\s+(\d+)\s+obj\b/g;
5465
- let match;
5466
- while ((match = objPattern.exec(fileText)) !== null) {
5467
- const objectNumber = parseInt(match[1], 10);
5468
- const gen = parseInt(match[2], 10);
5469
- const offset = match.index;
5471
+ const d = this.data;
5472
+ const len = d.length;
5473
+ for (let i = 0; i < len - 2; i++) {
5474
+ if (d[i] !== 111 || d[i + 1] !== 98 || d[i + 2] !== 106) continue;
5475
+ if (i + 3 < len) {
5476
+ const after = d[i + 3];
5477
+ if (after > 32 && after !== 37 && after !== 40 && after !== 41 && after !== 47 && after !== 60 && after !== 62 && after !== 91 && after !== 93 && after !== 123 && after !== 125) continue;
5478
+ }
5479
+ let j = i - 1;
5480
+ while (j >= 0 && (d[j] === 32 || d[j] === 10 || d[j] === 13 || d[j] === 9 || d[j] === 0)) j--;
5481
+ const genEnd = j + 1;
5482
+ while (j >= 0 && d[j] >= 48 && d[j] <= 57) j--;
5483
+ const genStart = j + 1;
5484
+ if (genStart >= genEnd) continue;
5485
+ while (j >= 0 && (d[j] === 32 || d[j] === 10 || d[j] === 13 || d[j] === 9 || d[j] === 0)) j--;
5486
+ const objEnd = j + 1;
5487
+ while (j >= 0 && d[j] >= 48 && d[j] <= 57) j--;
5488
+ const objStart = j + 1;
5489
+ if (objStart >= objEnd) continue;
5490
+ let objectNumber = 0;
5491
+ for (let k = objStart; k < objEnd; k++) objectNumber = objectNumber * 10 + (d[k] - 48);
5492
+ let gen = 0;
5493
+ for (let k = genStart; k < genEnd; k++) gen = gen * 10 + (d[k] - 48);
5470
5494
  entries.set(objectNumber, {
5471
5495
  objectNumber,
5472
5496
  generationNumber: gen,
5473
- offset,
5497
+ offset: objStart,
5474
5498
  type: "in-use"
5475
5499
  });
5476
5500
  }
@@ -5483,7 +5507,11 @@ var XrefParser = class {
5483
5507
  });
5484
5508
  let rootRef;
5485
5509
  let infoRef;
5486
- const trailerIdx = fileText.lastIndexOf("trailer");
5510
+ let trailerIdx = -1;
5511
+ for (let i = len - 7; i >= 0; i--) if (d[i] === 116 && d[i + 1] === 114 && d[i + 2] === 97 && d[i + 3] === 105 && d[i + 4] === 108 && d[i + 5] === 101 && d[i + 6] === 114) {
5512
+ trailerIdx = i;
5513
+ break;
5514
+ }
5487
5515
  if (trailerIdx !== -1) try {
5488
5516
  const trailerObj = this.objectParser.parseObjectAt(trailerIdx + 7);
5489
5517
  if (trailerObj.kind === "dict") {
@@ -5524,6 +5552,48 @@ var XrefParser = class {
5524
5552
  * Determine whether the data at the given offset starts with the
5525
5553
  * "xref" keyword (indicating a traditional xref table).
5526
5554
  */
5555
+ /**
5556
+ * Check if the bytes at `pos` match the given byte values.
5557
+ */
5558
+ matchesBytes(pos, ...bytes) {
5559
+ if (pos + bytes.length > this.data.length) return false;
5560
+ for (let i = 0; i < bytes.length; i++) if (this.data[pos + i] !== bytes[i]) return false;
5561
+ return true;
5562
+ }
5563
+ /**
5564
+ * Parse a standard xref entry directly from bytes, avoiding TextDecoder
5565
+ * and regex. Returns null if the bytes don't form a valid entry.
5566
+ *
5567
+ * Standard format: `OOOOOOOOOO GGGGG f/n` (18 significant bytes)
5568
+ */
5569
+ parseXrefEntryDirect(pos) {
5570
+ const d = this.data;
5571
+ if (pos + 18 > d.length) return null;
5572
+ let offset = 0;
5573
+ for (let k = 0; k < 10; k++) {
5574
+ const b = d[pos + k];
5575
+ if (b < 48 || b > 57) return null;
5576
+ offset = offset * 10 + (b - 48);
5577
+ }
5578
+ if (d[pos + 10] !== 32) return null;
5579
+ let gen = 0;
5580
+ for (let k = 0; k < 5; k++) {
5581
+ const b = d[pos + 11 + k];
5582
+ if (b < 48 || b > 57) return null;
5583
+ gen = gen * 10 + (b - 48);
5584
+ }
5585
+ if (d[pos + 16] !== 32) return null;
5586
+ const marker = d[pos + 17];
5587
+ if (marker !== 110 && marker !== 102) return null;
5588
+ let nextPos = pos + 18;
5589
+ while (nextPos < d.length && (d[nextPos] === 32 || d[nextPos] === 13 || d[nextPos] === 10)) nextPos++;
5590
+ return {
5591
+ offset,
5592
+ gen,
5593
+ type: marker === 110 ? "in-use" : "free",
5594
+ nextPos
5595
+ };
5596
+ }
5527
5597
  isTraditionalXref(offset) {
5528
5598
  if (offset + 4 > this.data.length) return false;
5529
5599
  return this.data[offset] === 120 && this.data[offset + 1] === 114 && this.data[offset + 2] === 101 && this.data[offset + 3] === 102;
@@ -6321,10 +6391,12 @@ function computeOwnerPasswordValue(ownerPassword, userPassword, revision, keyLen
6321
6391
  if (revision >= 3) for (let i = 0; i < 50; i++) hash = md5(hash.subarray(0, keyByteLength));
6322
6392
  const rc4Key = hash.subarray(0, keyByteLength);
6323
6393
  let encrypted = rc4(rc4Key, padPassword(userPassword));
6324
- if (revision >= 3) for (let i = 1; i <= 19; i++) {
6394
+ if (revision >= 3) {
6325
6395
  const modKey = new Uint8Array(rc4Key.length);
6326
- for (let j = 0; j < rc4Key.length; j++) modKey[j] = (rc4Key[j] ^ i) & 255;
6327
- encrypted = rc4(modKey, encrypted);
6396
+ for (let i = 1; i <= 19; i++) {
6397
+ for (let j = 0; j < rc4Key.length; j++) modKey[j] = (rc4Key[j] ^ i) & 255;
6398
+ encrypted = rc4(modKey, encrypted);
6399
+ }
6328
6400
  }
6329
6401
  return encrypted;
6330
6402
  }
@@ -6354,10 +6426,12 @@ function computeUserPasswordR2(fileKey) {
6354
6426
  */
6355
6427
  function computeUserPasswordR3R4(fileKey, fileId) {
6356
6428
  let encrypted = rc4(fileKey, md5(concat$1(PASSWORD_PADDING, fileId)));
6357
- for (let i = 1; i <= 19; i++) {
6429
+ {
6358
6430
  const modKey = new Uint8Array(fileKey.length);
6359
- for (let j = 0; j < fileKey.length; j++) modKey[j] = (fileKey[j] ^ i) & 255;
6360
- encrypted = rc4(modKey, encrypted);
6431
+ for (let i = 1; i <= 19; i++) {
6432
+ for (let j = 0; j < fileKey.length; j++) modKey[j] = (fileKey[j] ^ i) & 255;
6433
+ encrypted = rc4(modKey, encrypted);
6434
+ }
6361
6435
  }
6362
6436
  const result = new Uint8Array(32);
6363
6437
  result.set(encrypted.subarray(0, 16));
@@ -6423,9 +6497,17 @@ async function algorithm2B(password, salt, uKey) {
6423
6497
  let K = await sha256(uKey ? concat$1(password, salt, uKey) : concat$1(password, salt));
6424
6498
  let round = 0;
6425
6499
  while (true) {
6426
- const K1block = uKey ? concat$1(password, K, uKey) : concat$1(password, K);
6427
- const K1 = new Uint8Array(K1block.length * 64);
6428
- for (let i = 0; i < 64; i++) K1.set(K1block, i * K1block.length);
6500
+ const pLen = password.length;
6501
+ const kLen = K.length;
6502
+ const uLen = uKey ? uKey.length : 0;
6503
+ const blockLen = pLen + kLen + uLen;
6504
+ const K1 = new Uint8Array(blockLen * 64);
6505
+ for (let i = 0; i < 64; i++) {
6506
+ const base = i * blockLen;
6507
+ K1.set(password, base);
6508
+ K1.set(K, base + pLen);
6509
+ if (uKey) K1.set(uKey, base + pLen + kLen);
6510
+ }
6429
6511
  const E = await aesEncryptCBCNoPad(K.subarray(0, 16), K.subarray(16, 32), K1);
6430
6512
  let bigModVal = 0;
6431
6513
  for (let i = 0; i < 16; i++) bigModVal = (bigModVal * 256 + E[i]) % 3;
@@ -8577,7 +8659,17 @@ const NS_PDFAID = "http://www.aiim.org/pdfa/ns/id/";
8577
8659
  * @internal
8578
8660
  */
8579
8661
  function escapeXml(str) {
8580
- return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
8662
+ const parts = [];
8663
+ for (let i = 0; i < str.length; i++) {
8664
+ const c = str.charCodeAt(i);
8665
+ if (c === 38) parts.push("&amp;");
8666
+ else if (c === 60) parts.push("&lt;");
8667
+ else if (c === 62) parts.push("&gt;");
8668
+ else if (c === 34) parts.push("&quot;");
8669
+ else if (c === 39) parts.push("&apos;");
8670
+ else parts.push(str[i]);
8671
+ }
8672
+ return parts.join("");
8581
8673
  }
8582
8674
  /**
8583
8675
  * Format a Date as an ISO 8601 string for XMP.
@@ -9880,9 +9972,10 @@ function remapRef$1(sourceRef, context) {
9880
9972
  context.refMap.set(sourceRef.objectNumber, placeholderRef);
9881
9973
  return placeholderRef;
9882
9974
  }
9975
+ let streamHash;
9883
9976
  if (sourceObj.kind === "stream") {
9884
- const hash = hashBytes(sourceObj.data);
9885
- const dedup = context.hashMap.get(hash);
9977
+ streamHash = hashBytes(sourceObj.data);
9978
+ const dedup = context.hashMap.get(streamHash);
9886
9979
  if (dedup) {
9887
9980
  context.refMap.set(sourceRef.objectNumber, dedup);
9888
9981
  return dedup;
@@ -9892,10 +9985,7 @@ function remapRef$1(sourceRef, context) {
9892
9985
  context.refMap.set(sourceRef.objectNumber, targetRef);
9893
9986
  const clonedObj = deepClone$1(sourceObj, context);
9894
9987
  context.targetRegistry.assign(targetRef, clonedObj);
9895
- if (sourceObj.kind === "stream") {
9896
- const hash = hashBytes(sourceObj.data);
9897
- context.hashMap.set(hash, targetRef);
9898
- }
9988
+ if (streamHash !== void 0) context.hashMap.set(streamHash, targetRef);
9899
9989
  return targetRef;
9900
9990
  }
9901
9991
  /**
@@ -14474,7 +14564,6 @@ function read2DMode(reader) {
14474
14564
  if (bit === 1) {
14475
14565
  bit = reader.readBit();
14476
14566
  if (bit < 0) return Mode2D.EOL;
14477
- if (bit === 1) return Mode2D.HORIZONTAL;
14478
14567
  if (bit === 0) return Mode2D.VERTICAL_MINUS_1;
14479
14568
  return Mode2D.VERTICAL_PLUS_1;
14480
14569
  }
@@ -17605,9 +17694,28 @@ function hexValue(ch) {
17605
17694
  * `~>` marks end-of-data.
17606
17695
  */
17607
17696
  function decodeASCII85(data) {
17608
- const result = [];
17609
- const group = [];
17697
+ let out = new Uint8Array(Math.max(data.length * 4 / 5 | 0, 256));
17698
+ let outPos = 0;
17699
+ const group = new Uint8Array(5);
17700
+ let groupLen = 0;
17610
17701
  let i = 0;
17702
+ function ensureOut(needed) {
17703
+ if (outPos + needed > out.length) {
17704
+ const newBuf = new Uint8Array(Math.max(out.length * 2, outPos + needed));
17705
+ newBuf.set(out.subarray(0, outPos));
17706
+ out = newBuf;
17707
+ }
17708
+ }
17709
+ function decodeGroup(count) {
17710
+ for (let k = count; k < 5; k++) group[k] = 84;
17711
+ const val = group[0] * 85 * 85 * 85 * 85 + group[1] * 85 * 85 * 85 + group[2] * 85 * 85 + group[3] * 85 + group[4];
17712
+ const numBytes = count === 5 ? 4 : count - 1;
17713
+ ensureOut(numBytes);
17714
+ if (numBytes >= 1) out[outPos++] = val >>> 24 & 255;
17715
+ if (numBytes >= 2) out[outPos++] = val >>> 16 & 255;
17716
+ if (numBytes >= 3) out[outPos++] = val >>> 8 & 255;
17717
+ if (numBytes >= 4) out[outPos++] = val & 255;
17718
+ }
17611
17719
  while (i < data.length) {
17612
17720
  const ch = data[i];
17613
17721
  if (ch === 126) break;
@@ -17616,8 +17724,12 @@ function decodeASCII85(data) {
17616
17724
  continue;
17617
17725
  }
17618
17726
  if (ch === 122) {
17619
- if (group.length > 0) throw new Error("ASCII85Decode: \"z\" inside a group");
17620
- result.push(0, 0, 0, 0);
17727
+ if (groupLen > 0) throw new Error("ASCII85Decode: \"z\" inside a group");
17728
+ ensureOut(4);
17729
+ out[outPos++] = 0;
17730
+ out[outPos++] = 0;
17731
+ out[outPos++] = 0;
17732
+ out[outPos++] = 0;
17621
17733
  i++;
17622
17734
  continue;
17623
17735
  }
@@ -17625,24 +17737,15 @@ function decodeASCII85(data) {
17625
17737
  i++;
17626
17738
  continue;
17627
17739
  }
17628
- group.push(ch - 33);
17629
- if (group.length === 5) {
17630
- const val = group[0] * 85 * 85 * 85 * 85 + group[1] * 85 * 85 * 85 + group[2] * 85 * 85 + group[3] * 85 + group[4];
17631
- result.push(val >>> 24 & 255, val >>> 16 & 255, val >>> 8 & 255, val & 255);
17632
- group.length = 0;
17740
+ group[groupLen++] = ch - 33;
17741
+ if (groupLen === 5) {
17742
+ decodeGroup(5);
17743
+ groupLen = 0;
17633
17744
  }
17634
17745
  i++;
17635
17746
  }
17636
- if (group.length >= 2) {
17637
- const origLen = group.length;
17638
- while (group.length < 5) group.push(84);
17639
- const val = group[0] * 85 * 85 * 85 * 85 + group[1] * 85 * 85 * 85 + group[2] * 85 * 85 + group[3] * 85 + group[4];
17640
- const numBytes = origLen - 1;
17641
- if (numBytes >= 1) result.push(val >>> 24 & 255);
17642
- if (numBytes >= 2) result.push(val >>> 16 & 255);
17643
- if (numBytes >= 3) result.push(val >>> 8 & 255);
17644
- }
17645
- return new Uint8Array(result);
17747
+ if (groupLen >= 2) decodeGroup(groupLen);
17748
+ return out.subarray(0, outPos);
17646
17749
  }
17647
17750
  /**
17648
17751
  * Decode an LZWDecode stream.
@@ -17662,6 +17765,10 @@ function decodeLZW(data, parms) {
17662
17765
  }
17663
17766
  /**
17664
17767
  * Core LZW decompression.
17768
+ *
17769
+ * Uses a flat pooled buffer for the code table instead of per-entry
17770
+ * Uint8Array allocations, and a pre-allocated output buffer with
17771
+ * manual growth instead of `number[]` + push.
17665
17772
  */
17666
17773
  function lzwDecompress(data, earlyChange) {
17667
17774
  const CLEAR_TABLE = 256;
@@ -17686,71 +17793,88 @@ function lzwDecompress(data, earlyChange) {
17686
17793
  }
17687
17794
  return result;
17688
17795
  }
17689
- let table = [];
17796
+ let tableBuf = new Uint8Array(65536);
17797
+ const tableOff = new Int32Array(4096);
17798
+ const tableLen = new Int32Array(4096);
17799
+ let tableBufUsed = 256;
17690
17800
  let codeSize = 9;
17691
17801
  let nextCode = 258;
17802
+ for (let i = 0; i < 256; i++) {
17803
+ tableBuf[i] = i;
17804
+ tableOff[i] = i;
17805
+ tableLen[i] = 1;
17806
+ }
17692
17807
  function resetTable() {
17693
- table = [];
17694
- for (let i = 0; i < 256; i++) table[i] = new Uint8Array([i]);
17695
- table[256] = new Uint8Array(0);
17696
- table[257] = new Uint8Array(0);
17808
+ tableBufUsed = 256;
17697
17809
  nextCode = 258;
17698
17810
  codeSize = 9;
17699
17811
  }
17700
- resetTable();
17701
- const output = [];
17702
- let prevEntry = null;
17812
+ let out = new Uint8Array(Math.max(data.length * 3, 4096));
17813
+ let outPos = 0;
17814
+ function ensureOut(needed) {
17815
+ if (outPos + needed > out.length) {
17816
+ const newBuf = new Uint8Array(Math.max(out.length * 2, outPos + needed));
17817
+ newBuf.set(out.subarray(0, outPos));
17818
+ out = newBuf;
17819
+ }
17820
+ }
17821
+ function ensureTable(needed) {
17822
+ if (tableBufUsed + needed > tableBuf.length) {
17823
+ const newBuf = new Uint8Array(Math.max(tableBuf.length * 2, tableBufUsed + needed));
17824
+ newBuf.set(tableBuf.subarray(0, tableBufUsed));
17825
+ tableBuf = newBuf;
17826
+ }
17827
+ }
17828
+ function writeEntry(code) {
17829
+ const off = tableOff[code];
17830
+ const len = tableLen[code];
17831
+ ensureOut(len);
17832
+ out.set(tableBuf.subarray(off, off + len), outPos);
17833
+ outPos += len;
17834
+ }
17835
+ function addEntry(prevCode, firstByte) {
17836
+ const prevOff = tableOff[prevCode];
17837
+ const prevLen = tableLen[prevCode];
17838
+ const newLen = prevLen + 1;
17839
+ ensureTable(newLen);
17840
+ tableBuf.set(tableBuf.subarray(prevOff, prevOff + prevLen), tableBufUsed);
17841
+ tableBuf[tableBufUsed + prevLen] = firstByte;
17842
+ tableOff[nextCode] = tableBufUsed;
17843
+ tableLen[nextCode] = newLen;
17844
+ tableBufUsed += newLen;
17845
+ nextCode++;
17846
+ }
17703
17847
  let code = readBits(codeSize);
17704
17848
  if (code === CLEAR_TABLE) {
17705
17849
  resetTable();
17706
17850
  code = readBits(codeSize);
17707
17851
  }
17708
- if (code === EOD) return new Uint8Array(output);
17709
- let entry = table[code];
17710
- if (entry) {
17711
- for (const b of entry) output.push(b);
17712
- prevEntry = entry;
17713
- }
17852
+ if (code === EOD) return new Uint8Array(0);
17853
+ writeEntry(code);
17854
+ let prevCode = code;
17714
17855
  while (true) {
17715
17856
  code = readBits(codeSize);
17716
17857
  if (code === EOD) break;
17717
17858
  if (code === CLEAR_TABLE) {
17718
17859
  resetTable();
17719
- prevEntry = null;
17720
17860
  code = readBits(codeSize);
17721
17861
  if (code === EOD) break;
17722
- entry = table[code];
17723
- if (entry) {
17724
- for (const b of entry) output.push(b);
17725
- prevEntry = entry;
17726
- }
17862
+ writeEntry(code);
17863
+ prevCode = code;
17727
17864
  continue;
17728
17865
  }
17729
- if (code < nextCode && table[code]) {
17730
- entry = table[code];
17731
- for (const b of entry) output.push(b);
17732
- if (prevEntry) {
17733
- const newEntry = new Uint8Array(prevEntry.length + 1);
17734
- newEntry.set(prevEntry);
17735
- newEntry[prevEntry.length] = entry[0];
17736
- table[nextCode] = newEntry;
17737
- nextCode++;
17738
- }
17866
+ if (code < nextCode) {
17867
+ writeEntry(code);
17868
+ addEntry(prevCode, tableBuf[tableOff[code]]);
17739
17869
  } else {
17740
- if (!prevEntry) throw new Error("LZWDecode: invalid code sequence");
17741
- const newEntry = new Uint8Array(prevEntry.length + 1);
17742
- newEntry.set(prevEntry);
17743
- newEntry[prevEntry.length] = prevEntry[0];
17744
- for (const b of newEntry) output.push(b);
17745
- table[nextCode] = newEntry;
17746
- nextCode++;
17747
- entry = newEntry;
17748
- }
17749
- prevEntry = entry;
17870
+ addEntry(prevCode, tableBuf[tableOff[prevCode]]);
17871
+ writeEntry(nextCode - 1);
17872
+ }
17873
+ prevCode = code;
17750
17874
  const threshold = (1 << codeSize) - earlyChange;
17751
17875
  if (nextCode >= threshold && codeSize < 12) codeSize++;
17752
17876
  }
17753
- return new Uint8Array(output);
17877
+ return out.subarray(0, outPos);
17754
17878
  }
17755
17879
  /**
17756
17880
  * Decode a RunLengthDecode stream.
@@ -17882,7 +18006,6 @@ function embedPageAsFormXObject(page, sourceRegistry, targetRegistry, xObjectNam
17882
18006
  const pageWidth = page.width;
17883
18007
  const pageHeight = page.height;
17884
18008
  const contentChunks = [];
17885
- new TextDecoder();
17886
18009
  const originalRefs = page.getOriginalContentRefs();
17887
18010
  for (const ref of originalRefs) {
17888
18011
  const obj = sourceRegistry.resolve(ref);
@@ -18400,7 +18523,7 @@ var PdfDocument = class PdfDocument {
18400
18523
  async embedTrueTypeFont(fontData, options) {
18401
18524
  const embeddedFont = await embedFont(fontData);
18402
18525
  const metrics = embeddedFont.metrics;
18403
- const psName = options?.customName || metrics.postScriptName || metrics.familyName || "CustomFont";
18526
+ const psName = options?.customName ?? metrics.postScriptName ?? metrics.familyName ?? "CustomFont";
18404
18527
  const existing = this.embeddedFonts.get(`__ttf__${psName}`);
18405
18528
  if (existing) return existing;
18406
18529
  this.fontCounter++;
@@ -18515,7 +18638,7 @@ var PdfDocument = class PdfDocument {
18515
18638
  async embedCffFont(fontData, options) {
18516
18639
  const embeddedFont = await embedFont(fontData);
18517
18640
  const metrics = embeddedFont.metrics;
18518
- const psName = options?.customName || metrics.postScriptName || metrics.familyName || "CFFFont";
18641
+ const psName = options?.customName ?? metrics.postScriptName ?? metrics.familyName ?? "CFFFont";
18519
18642
  const existing = this.embeddedFonts.get(`__cff__${psName}`);
18520
18643
  if (existing) return existing;
18521
18644
  this.fontCounter++;
@@ -18805,7 +18928,7 @@ var PdfDocument = class PdfDocument {
18805
18928
  * @param pages Array of PdfPage instances to embed.
18806
18929
  * @returns Array of {@link EmbeddedPdfPage} handles, one per input page.
18807
18930
  */
18808
- async embedPages(pages) {
18931
+ embedPages(pages) {
18809
18932
  return pages.map((page) => this.embedPage(page));
18810
18933
  }
18811
18934
  /** Set the document title. */
@@ -20337,8 +20460,8 @@ function compressStream(stream, level) {
20337
20460
  * @returns The incremental save result.
20338
20461
  */
20339
20462
  async function saveDocumentIncremental(originalBytes, doc, options) {
20340
- const { buildDocumentStructure } = await Promise.resolve().then(() => require("./pdfCatalog-y_XG8Hq1.cjs")).then((n) => n.pdfCatalog_exports);
20341
- const { PdfPage: _PdfPage } = await Promise.resolve().then(() => require("./pdfPage-BebMv6fN.cjs")).then((n) => n.pdfPage_exports);
20463
+ const { buildDocumentStructure } = await Promise.resolve().then(() => require("./pdfCatalog-COKoYQ8C.cjs")).then((n) => n.pdfCatalog_exports);
20464
+ const { PdfPage: _PdfPage } = await Promise.resolve().then(() => require("./pdfPage-DBfdinTR.cjs")).then((n) => n.pdfPage_exports);
20342
20465
  const registry = doc.getRegistry();
20343
20466
  const structure = buildDocumentStructure(doc.getInternalPages().map((p) => p.finalize()), {
20344
20467
  producer: doc.getProducer(),
@@ -22445,6 +22568,19 @@ var TokenType = /* @__PURE__ */ function(TokenType) {
22445
22568
  return TokenType;
22446
22569
  }(TokenType || {});
22447
22570
  /**
22571
+ * `hexVal[b]` is the numeric value (0-15) of a hex character, or -1 if
22572
+ * the byte is not a valid hex digit.
22573
+ */
22574
+ const hexVal = /* @__PURE__ */ (() => {
22575
+ const t = new Int8Array(256).fill(-1);
22576
+ for (let i = 0; i <= 9; i++) t[48 + i] = i;
22577
+ for (let i = 0; i < 6; i++) {
22578
+ t[65 + i] = 10 + i;
22579
+ t[97 + i] = 10 + i;
22580
+ }
22581
+ return t;
22582
+ })();
22583
+ /**
22448
22584
  * Combined lexer + parser for PDF content streams.
22449
22585
  *
22450
22586
  * Content streams are simpler than full PDF object syntax — there are no
@@ -22563,20 +22699,22 @@ var ContentStreamLexer = class {
22563
22699
  }
22564
22700
  const dataStart = this.pos;
22565
22701
  let dataEnd = this.pos;
22566
- while (this.pos < this.data.length) {
22567
- if (this.isWhitespace(this.data[this.pos])) {
22568
- const wsPos = this.pos;
22569
- let probe = wsPos + 1;
22570
- if (probe + 1 < this.data.length && this.data[probe] === 69 && this.data[probe + 1] === 73) {
22571
- const afterEI = probe + 2;
22572
- if (afterEI >= this.data.length || this.isWhitespace(this.data[afterEI])) {
22573
- dataEnd = wsPos;
22574
- this.pos = afterEI;
22575
- break;
22576
- }
22702
+ let searchFrom = this.pos;
22703
+ while (searchFrom < this.data.length) {
22704
+ const eIdx = this.data.indexOf(69, searchFrom);
22705
+ if (eIdx === -1 || eIdx + 1 >= this.data.length) {
22706
+ this.pos = this.data.length;
22707
+ break;
22708
+ }
22709
+ if (eIdx > dataStart && this.isWhitespace(this.data[eIdx - 1]) && this.data[eIdx + 1] === 73) {
22710
+ const afterEI = eIdx + 2;
22711
+ if (afterEI >= this.data.length || this.isWhitespace(this.data[afterEI])) {
22712
+ dataEnd = eIdx - 1;
22713
+ this.pos = afterEI;
22714
+ break;
22577
22715
  }
22578
22716
  }
22579
- this.pos++;
22717
+ searchFrom = eIdx + 1;
22580
22718
  }
22581
22719
  return {
22582
22720
  dict,
@@ -22644,7 +22782,7 @@ var ContentStreamLexer = class {
22644
22782
  */
22645
22783
  readLiteralString() {
22646
22784
  this.pos++;
22647
- let result = "";
22785
+ const parts = [];
22648
22786
  let depth = 1;
22649
22787
  while (this.pos < this.data.length && depth > 0) {
22650
22788
  const ch = this.data[this.pos];
@@ -22654,35 +22792,35 @@ var ContentStreamLexer = class {
22654
22792
  const esc = this.data[this.pos];
22655
22793
  switch (esc) {
22656
22794
  case 110:
22657
- result += "\n";
22795
+ parts.push("\n");
22658
22796
  this.pos++;
22659
22797
  break;
22660
22798
  case 114:
22661
- result += "\r";
22799
+ parts.push("\r");
22662
22800
  this.pos++;
22663
22801
  break;
22664
22802
  case 116:
22665
- result += " ";
22803
+ parts.push(" ");
22666
22804
  this.pos++;
22667
22805
  break;
22668
22806
  case 98:
22669
- result += "\b";
22807
+ parts.push("\b");
22670
22808
  this.pos++;
22671
22809
  break;
22672
22810
  case 102:
22673
- result += "\f";
22811
+ parts.push("\f");
22674
22812
  this.pos++;
22675
22813
  break;
22676
22814
  case 40:
22677
- result += "(";
22815
+ parts.push("(");
22678
22816
  this.pos++;
22679
22817
  break;
22680
22818
  case 41:
22681
- result += ")";
22819
+ parts.push(")");
22682
22820
  this.pos++;
22683
22821
  break;
22684
22822
  case 92:
22685
- result += "\\";
22823
+ parts.push("\\");
22686
22824
  this.pos++;
22687
22825
  break;
22688
22826
  case 10:
@@ -22710,29 +22848,29 @@ var ContentStreamLexer = class {
22710
22848
  }
22711
22849
  }
22712
22850
  }
22713
- result += String.fromCharCode(octal & 255);
22851
+ parts.push(String.fromCharCode(octal & 255));
22714
22852
  } else {
22715
- result += String.fromCharCode(esc);
22853
+ parts.push(String.fromCharCode(esc));
22716
22854
  this.pos++;
22717
22855
  }
22718
22856
  break;
22719
22857
  }
22720
22858
  } else if (ch === 40) {
22721
22859
  depth++;
22722
- result += "(";
22860
+ parts.push("(");
22723
22861
  this.pos++;
22724
22862
  } else if (ch === 41) {
22725
22863
  depth--;
22726
- if (depth > 0) result += ")";
22864
+ if (depth > 0) parts.push(")");
22727
22865
  this.pos++;
22728
22866
  } else {
22729
- result += String.fromCharCode(ch);
22867
+ parts.push(String.fromCharCode(ch));
22730
22868
  this.pos++;
22731
22869
  }
22732
22870
  }
22733
22871
  return {
22734
22872
  type: TokenType.String,
22735
- value: result
22873
+ value: parts.join("")
22736
22874
  };
22737
22875
  }
22738
22876
  /**
@@ -22740,7 +22878,8 @@ var ContentStreamLexer = class {
22740
22878
  */
22741
22879
  readHexString() {
22742
22880
  this.pos++;
22743
- let hex = "";
22881
+ const bytes = [];
22882
+ let hi = -1;
22744
22883
  while (this.pos < this.data.length) {
22745
22884
  const ch = this.data[this.pos];
22746
22885
  if (ch === 62) {
@@ -22751,18 +22890,22 @@ var ContentStreamLexer = class {
22751
22890
  this.pos++;
22752
22891
  continue;
22753
22892
  }
22754
- hex += String.fromCharCode(ch);
22893
+ const v = hexVal[ch];
22894
+ if (v === -1) {
22895
+ this.pos++;
22896
+ continue;
22897
+ }
22898
+ if (hi === -1) hi = v;
22899
+ else {
22900
+ bytes.push(hi << 4 | v);
22901
+ hi = -1;
22902
+ }
22755
22903
  this.pos++;
22756
22904
  }
22757
- if (hex.length % 2 !== 0) hex += "0";
22758
- let result = "";
22759
- for (let i = 0; i < hex.length; i += 2) {
22760
- const byte = parseInt(hex.substring(i, i + 2), 16);
22761
- if (!isNaN(byte)) result += String.fromCharCode(byte);
22762
- }
22905
+ if (hi !== -1) bytes.push(hi << 4);
22763
22906
  return {
22764
22907
  type: TokenType.HexString,
22765
- value: result
22908
+ value: String.fromCharCode.apply(null, bytes)
22766
22909
  };
22767
22910
  }
22768
22911
  /**
@@ -22770,27 +22913,25 @@ var ContentStreamLexer = class {
22770
22913
  */
22771
22914
  readName() {
22772
22915
  this.pos++;
22773
- let name = "/";
22916
+ const parts = ["/"];
22774
22917
  while (this.pos < this.data.length) {
22775
22918
  const ch = this.data[this.pos];
22776
22919
  if (this.isWhitespace(ch) || this.isDelimiter(ch)) break;
22777
22920
  if (ch === 35 && this.pos + 2 < this.data.length) {
22778
- const hi = this.data[this.pos + 1];
22779
- const lo = this.data[this.pos + 2];
22780
- const hex = String.fromCharCode(hi) + String.fromCharCode(lo);
22781
- const code = parseInt(hex, 16);
22782
- if (!isNaN(code)) {
22783
- name += String.fromCharCode(code);
22921
+ const hi = hexVal[this.data[this.pos + 1]];
22922
+ const lo = hexVal[this.data[this.pos + 2]];
22923
+ if (hi !== -1 && lo !== -1) {
22924
+ parts.push(String.fromCharCode(hi << 4 | lo));
22784
22925
  this.pos += 3;
22785
22926
  continue;
22786
22927
  }
22787
22928
  }
22788
- name += String.fromCharCode(ch);
22929
+ parts.push(String.fromCharCode(ch));
22789
22930
  this.pos++;
22790
22931
  }
22791
22932
  return {
22792
22933
  type: TokenType.Name,
22793
- value: require_pdfCatalog.PdfName.of(name)
22934
+ value: require_pdfCatalog.PdfName.of(parts.join(""))
22794
22935
  };
22795
22936
  }
22796
22937
  /**
@@ -22884,9 +23025,7 @@ var ContentStreamLexer = class {
22884
23025
  * Decode a slice of the data as ASCII text.
22885
23026
  */
22886
23027
  decodeAscii(start, end) {
22887
- let s = "";
22888
- for (let i = start; i < end; i++) s += String.fromCharCode(this.data[i]);
22889
- return s;
23028
+ return String.fromCharCode.apply(null, this.data.subarray(start, end));
22890
23029
  }
22891
23030
  };
22892
23031