@adnsistemas/pdf-lib 2.7.1 → 2.7.3

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.
Files changed (47) hide show
  1. package/README.md +4 -3
  2. package/cjs/api/PDFDocument.js +1 -1
  3. package/cjs/api/PDFDocument.js.map +1 -1
  4. package/cjs/api/snapshot/IncrementalDocumentSnapshot.d.ts +1 -1
  5. package/cjs/api/snapshot/IncrementalDocumentSnapshot.d.ts.map +1 -1
  6. package/cjs/api/snapshot/IncrementalDocumentSnapshot.js +3 -7
  7. package/cjs/api/snapshot/IncrementalDocumentSnapshot.js.map +1 -1
  8. package/cjs/core/objects/PDFString.js +1 -1
  9. package/cjs/core/parser/PDFObjectParser.d.ts.map +1 -1
  10. package/cjs/core/parser/PDFObjectParser.js +2 -1
  11. package/cjs/core/parser/PDFObjectParser.js.map +1 -1
  12. package/cjs/core/writers/PDFWriter.d.ts +20 -0
  13. package/cjs/core/writers/PDFWriter.d.ts.map +1 -1
  14. package/cjs/core/writers/PDFWriter.js +64 -3
  15. package/cjs/core/writers/PDFWriter.js.map +1 -1
  16. package/dist/pdf-lib.esm.js +69 -13
  17. package/dist/pdf-lib.esm.js.map +1 -1
  18. package/dist/pdf-lib.esm.min.js +3 -3
  19. package/dist/pdf-lib.esm.min.js.map +1 -1
  20. package/dist/pdf-lib.js +69 -13
  21. package/dist/pdf-lib.js.map +1 -1
  22. package/dist/pdf-lib.min.js +3 -3
  23. package/dist/pdf-lib.min.js.map +1 -1
  24. package/es/api/PDFDocument.js +1 -1
  25. package/es/api/PDFDocument.js.map +1 -1
  26. package/es/api/snapshot/IncrementalDocumentSnapshot.d.ts +1 -1
  27. package/es/api/snapshot/IncrementalDocumentSnapshot.d.ts.map +1 -1
  28. package/es/api/snapshot/IncrementalDocumentSnapshot.js +3 -7
  29. package/es/api/snapshot/IncrementalDocumentSnapshot.js.map +1 -1
  30. package/es/core/objects/PDFString.js +1 -1
  31. package/es/core/parser/PDFObjectParser.d.ts.map +1 -1
  32. package/es/core/parser/PDFObjectParser.js +3 -2
  33. package/es/core/parser/PDFObjectParser.js.map +1 -1
  34. package/es/core/writers/PDFWriter.d.ts +20 -0
  35. package/es/core/writers/PDFWriter.d.ts.map +1 -1
  36. package/es/core/writers/PDFWriter.js +64 -3
  37. package/es/core/writers/PDFWriter.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/api/PDFDocument.ts +1 -1
  40. package/src/api/snapshot/IncrementalDocumentSnapshot.ts +5 -11
  41. package/src/core/objects/PDFString.ts +1 -1
  42. package/src/core/parser/PDFObjectParser.ts +5 -2
  43. package/src/core/writers/PDFWriter.ts +72 -3
  44. package/ts3.4/cjs/api/snapshot/IncrementalDocumentSnapshot.d.ts +1 -1
  45. package/ts3.4/cjs/core/writers/PDFWriter.d.ts +23 -0
  46. package/ts3.4/es/api/snapshot/IncrementalDocumentSnapshot.d.ts +1 -1
  47. package/ts3.4/es/core/writers/PDFWriter.d.ts +23 -0
@@ -9002,7 +9002,7 @@ class PDFString extends PDFObject {
9002
9002
  pushByte(CharCodes$1.LeftParen);
9003
9003
  else if (byte === CharCodes$1.RightParen)
9004
9004
  pushByte(CharCodes$1.RightParen);
9005
- else if (byte === CharCodes$1.Backspace)
9005
+ else if (byte === CharCodes$1.BackSlash)
9006
9006
  pushByte(CharCodes$1.BackSlash);
9007
9007
  else if (byte >= CharCodes$1.Zero && byte <= CharCodes$1.Seven) {
9008
9008
  octal += char;
@@ -9982,13 +9982,9 @@ class IncrementalDocumentSnapshot {
9982
9982
  this.context = context;
9983
9983
  }
9984
9984
  shouldSave(objectNumber) {
9985
- if (objectNumber > this.lastObjectNumber) {
9985
+ if (objectNumber > this.lastObjectNumber)
9986
9986
  return true;
9987
- }
9988
- if (this.changedObjects.includes(objectNumber)) {
9989
- return true;
9990
- }
9991
- return false;
9987
+ return this.changedObjects.has(objectNumber);
9992
9988
  }
9993
9989
  markRefForSave(ref) {
9994
9990
  this.markRefsForSave([ref]);
@@ -9996,7 +9992,7 @@ class IncrementalDocumentSnapshot {
9996
9992
  markRefsForSave(refs) {
9997
9993
  refs.forEach((ref) => {
9998
9994
  if (ref)
9999
- this.changedObjects.push(ref.objectNumber);
9995
+ this.changedObjects.add(ref.objectNumber);
10000
9996
  });
10001
9997
  }
10002
9998
  markObjForSave(obj) {
@@ -10325,6 +10321,17 @@ PDFObjectStream.withContextAndObjects = (context, objects, encode = true) => new
10325
10321
  class PDFWriter {
10326
10322
  constructor(context, objectsPerTick, snapshot) {
10327
10323
  this.parsedObjects = 0;
10324
+ /**
10325
+ * If PDF has an XRef Stream, then the last object will be probably be skipped on saving.
10326
+ * If that's the case, this property will have that object number, and the PDF /Size can
10327
+ * be corrected, to be accurate.
10328
+ */
10329
+ this._largestSkippedObjectNum = 0;
10330
+ /**
10331
+ * Used to check wheter an object should be saved or not, preserves the object number of the
10332
+ * last XRef Stream object, if there is one.
10333
+ */
10334
+ this._lastXRefObjectNumber = 0;
10328
10335
  this.shouldWaitForTick = (n) => {
10329
10336
  this.parsedObjects += n;
10330
10337
  return this.parsedObjects % this.objectsPerTick === 0;
@@ -10333,6 +10340,44 @@ class PDFWriter {
10333
10340
  this.objectsPerTick = objectsPerTick;
10334
10341
  this.snapshot = snapshot;
10335
10342
  }
10343
+ /**
10344
+ * For incremental saves, defers the decision to the snapshot.
10345
+ * For full saves, checks that the object is not the last XRef stream object.
10346
+ * @param {boolean} incremental If making an incremental save, or a full save of the PDF
10347
+ * @param {number} objNum Object number
10348
+ * @param {[PDFRef, PDFObject][]} objects List of objects that form the PDF
10349
+ * @returns {boolean} whether the object should be saved or not
10350
+ */
10351
+ shouldSave(incremental, objNum, objects) {
10352
+ let should = true;
10353
+ if (incremental) {
10354
+ should = this.snapshot.shouldSave(objNum);
10355
+ }
10356
+ else {
10357
+ // only the last XRef Stream will be regenerated on save
10358
+ if (!this._lastXRefObjectNumber) {
10359
+ // if no XRef Stream, then nothing should be skipped
10360
+ this._lastXRefObjectNumber = this.context.largestObjectNumber + 1;
10361
+ const checkWatermark = this._lastXRefObjectNumber - 10; // max number of objects in the final part of the PDF to check
10362
+ // search the last XRef Stream, if there is one, objects are expected to be in object number order
10363
+ for (let idx = objects.length - 1; idx > 0; idx--) {
10364
+ // if not in last 'rangeToCheck' objects, there is none that should be skipped, most probably a linearized PDF, or without XRef Streams
10365
+ if (objects[idx][0].objectNumber < checkWatermark)
10366
+ break;
10367
+ const object = objects[idx][1];
10368
+ if (object instanceof PDFRawStream &&
10369
+ object.dict.lookup(PDFName.of('Type')) === PDFName.of('XRef')) {
10370
+ this._lastXRefObjectNumber = objects[idx][0].objectNumber;
10371
+ break;
10372
+ }
10373
+ }
10374
+ }
10375
+ should = objNum !== this._lastXRefObjectNumber;
10376
+ }
10377
+ if (!should && this._largestSkippedObjectNum < objNum)
10378
+ this._largestSkippedObjectNum = objNum;
10379
+ return should;
10380
+ }
10336
10381
  serializeToBuffer() {
10337
10382
  return __awaiter(this, void 0, void 0, function* () {
10338
10383
  const incremental = !(this.snapshot instanceof DefaultDocumentSnapshot);
@@ -10346,7 +10391,7 @@ class PDFWriter {
10346
10391
  buffer[offset++] = CharCodes$1.Newline;
10347
10392
  for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
10348
10393
  const [ref, object] = indirectObjects[idx];
10349
- if (!this.snapshot.shouldSave(ref.objectNumber)) {
10394
+ if (!this.shouldSave(incremental, ref.objectNumber, indirectObjects)) {
10350
10395
  continue;
10351
10396
  }
10352
10397
  const objectNumber = String(ref.objectNumber);
@@ -10392,8 +10437,16 @@ class PDFWriter {
10392
10437
  return refSize + objectSize;
10393
10438
  }
10394
10439
  createTrailerDict(prevStartXRef) {
10440
+ /**
10441
+ * if last object (XRef Stream) is not in the output, then size is one less.
10442
+ * An XRef Stream object should always be the largest object number in PDF
10443
+ */
10444
+ const size = this.context.largestObjectNumber +
10445
+ (this._largestSkippedObjectNum === this.context.largestObjectNumber
10446
+ ? 0
10447
+ : 1);
10395
10448
  return this.context.obj({
10396
- Size: this.context.largestObjectNumber + 1,
10449
+ Size: size,
10397
10450
  Root: this.context.trailerInfo.Root,
10398
10451
  Encrypt: this.context.trailerInfo.Encrypt,
10399
10452
  Info: this.context.trailerInfo.Info,
@@ -10403,6 +10456,8 @@ class PDFWriter {
10403
10456
  }
10404
10457
  computeBufferSize(incremental) {
10405
10458
  return __awaiter(this, void 0, void 0, function* () {
10459
+ this._largestSkippedObjectNum = 0;
10460
+ this._lastXRefObjectNumber = 0;
10406
10461
  const header = PDFHeader.forVersion(1, 7);
10407
10462
  let size = this.snapshot.pdfSize;
10408
10463
  if (!incremental) {
@@ -10415,7 +10470,7 @@ class PDFWriter {
10415
10470
  for (let idx = 0, len = indirectObjects.length; idx < len; idx++) {
10416
10471
  const indirectObject = indirectObjects[idx];
10417
10472
  const [ref, object] = indirectObject;
10418
- if (!this.snapshot.shouldSave(ref.objectNumber))
10473
+ if (!this.shouldSave(incremental, ref.objectNumber, indirectObjects))
10419
10474
  continue;
10420
10475
  if (security)
10421
10476
  this.encrypt(ref, object, security);
@@ -15877,7 +15932,8 @@ class PDFObjectParser extends BaseParser {
15877
15932
  let actualValue = value.substring(1, value.length - 1);
15878
15933
  if (this.cryptoFactory && ref) {
15879
15934
  const transformer = this.cryptoFactory.createCipherTransform(ref.objectNumber, ref.generationNumber);
15880
- actualValue = transformer.decryptString(actualValue);
15935
+ const decrypted = transformer.decryptBytes(PDFString.of(actualValue).asBytes());
15936
+ actualValue = arrayAsString(decrypted);
15881
15937
  }
15882
15938
  // Remove the outer parens so they aren't part of the contents
15883
15939
  return PDFString.of(actualValue);
@@ -37269,7 +37325,7 @@ class PDFDocument {
37269
37325
  return undefined;
37270
37326
  }
37271
37327
  takeSnapshot() {
37272
- const indirectObjects = [];
37328
+ const indirectObjects = new Set();
37273
37329
  const snapshot = new IncrementalDocumentSnapshot(this.context.largestObjectNumber, indirectObjects, this.context.pdfFileDetails.pdfSize, this.context.pdfFileDetails.prevStartXRef, this.context);
37274
37330
  if (!this.context.snapshot && this.context.pdfFileDetails.originalBytes) {
37275
37331
  this.context.snapshot = snapshot;