pdf-lite 1.0.2 → 1.0.4

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 (45) hide show
  1. package/EXAMPLES.md +354 -0
  2. package/README.md +7 -3
  3. package/dist/core/index.d.ts +48 -0
  4. package/dist/core/index.js +48 -0
  5. package/dist/core/objects/pdf-array.d.ts +1 -1
  6. package/dist/core/objects/pdf-indirect-object.d.ts +1 -1
  7. package/dist/core/objects/pdf-start-xref.d.ts +1 -1
  8. package/dist/core/objects/pdf-xref-table.d.ts +1 -1
  9. package/dist/core/tokens/number-token.js +11 -6
  10. package/dist/crypto/index.d.ts +11 -0
  11. package/dist/crypto/index.js +11 -0
  12. package/dist/crypto/key-derivation/key-derivation.d.ts +0 -14
  13. package/dist/crypto/key-derivation/key-derivation.js +1 -26
  14. package/dist/crypto/key-gen/key-gen-rc4-128.js +1 -2
  15. package/dist/crypto/key-gen/key-gen-rc4-40.js +1 -2
  16. package/dist/filters/index.d.ts +7 -0
  17. package/dist/filters/index.js +7 -0
  18. package/dist/index.d.ts +5 -1
  19. package/dist/index.js +5 -1
  20. package/dist/pdf/index.d.ts +5 -4
  21. package/dist/pdf/index.js +5 -4
  22. package/dist/pdf/pdf-document.d.ts +9 -3
  23. package/dist/pdf/pdf-document.js +15 -3
  24. package/dist/security/index.d.ts +13 -0
  25. package/dist/security/index.js +13 -0
  26. package/dist/signing/index.d.ts +5 -3
  27. package/dist/signing/index.js +5 -3
  28. package/dist/signing/signatures/adbe-pkcs7-detached.d.ts +7 -0
  29. package/dist/signing/signatures/adbe-pkcs7-detached.js +36 -0
  30. package/dist/signing/signatures/adbe-pkcs7-sha1.d.ts +7 -0
  31. package/dist/signing/signatures/adbe-pkcs7-sha1.js +54 -0
  32. package/dist/signing/signatures/adbe-x509-rsa-sha1.d.ts +7 -0
  33. package/dist/signing/signatures/adbe-x509-rsa-sha1.js +77 -0
  34. package/dist/signing/signatures/base.d.ts +16 -1
  35. package/dist/signing/signatures/base.js +18 -0
  36. package/dist/signing/signatures/etsi-cades-detached.d.ts +7 -0
  37. package/dist/signing/signatures/etsi-cades-detached.js +36 -0
  38. package/dist/signing/signatures/etsi-rfc3161.d.ts +7 -0
  39. package/dist/signing/signatures/etsi-rfc3161.js +102 -0
  40. package/dist/signing/signer.d.ts +55 -0
  41. package/dist/signing/signer.js +196 -1
  42. package/dist/signing/types.d.ts +26 -0
  43. package/dist/utils/index.d.ts +17 -0
  44. package/dist/utils/index.js +17 -0
  45. package/package.json +3 -3
package/EXAMPLES.md CHANGED
@@ -1510,3 +1510,357 @@ for (const obj of preservingDecoder) {
1510
1510
  console.log('Match:', simpleDict === reconstructed)
1511
1511
  }
1512
1512
  ```
1513
+
1514
+ ## PDF verify signatures example
1515
+
1516
+ ```typescript
1517
+ import { PdfArray } from 'pdf-lite/core/objects/pdf-array'
1518
+ import { PdfDictionary } from 'pdf-lite/core/objects/pdf-dictionary'
1519
+ import { PdfIndirectObject } from 'pdf-lite/core/objects/pdf-indirect-object'
1520
+ import { PdfName } from 'pdf-lite/core/objects/pdf-name'
1521
+ import { PdfNumber } from 'pdf-lite/core/objects/pdf-number'
1522
+ import { PdfObjectReference } from 'pdf-lite/core/objects/pdf-object-reference'
1523
+ import { PdfStream } from 'pdf-lite/core/objects/pdf-stream'
1524
+ import { PdfDocument } from 'pdf-lite/pdf/pdf-document'
1525
+ import { PdfString } from 'pdf-lite/core/objects/pdf-string'
1526
+ import {
1527
+ PdfAdbePkcsX509RsaSha1SignatureObject,
1528
+ PdfAdbePkcs7DetachedSignatureObject,
1529
+ PdfAdbePkcs7Sha1SignatureObject,
1530
+ PdfEtsiCadesDetachedSignatureObject,
1531
+ PdfEtsiRfc3161SignatureObject,
1532
+ } from 'pdf-lite'
1533
+ import { rsaSigningKeys } from '../packages/pdf-lite/test/unit/fixtures/rsa-2048/index'
1534
+
1535
+ function createPage(
1536
+ contentStreamRef: PdfObjectReference,
1537
+ ): PdfIndirectObject<PdfDictionary> {
1538
+ const pageDict = new PdfDictionary()
1539
+ pageDict.set('Type', new PdfName('Page'))
1540
+ pageDict.set(
1541
+ 'MediaBox',
1542
+ new PdfArray([
1543
+ new PdfNumber(0),
1544
+ new PdfNumber(0),
1545
+ new PdfNumber(612),
1546
+ new PdfNumber(792),
1547
+ ]),
1548
+ )
1549
+ pageDict.set('Contents', contentStreamRef)
1550
+ return new PdfIndirectObject({ content: pageDict })
1551
+ }
1552
+
1553
+ function createPages(
1554
+ pages: PdfIndirectObject<PdfDictionary>[],
1555
+ ): PdfIndirectObject<PdfDictionary> {
1556
+ const pagesDict = new PdfDictionary()
1557
+ pagesDict.set('Type', new PdfName('Pages'))
1558
+ pagesDict.set('Kids', new PdfArray(pages.map((x) => x.reference)))
1559
+ pagesDict.set('Count', new PdfNumber(pages.length))
1560
+ return new PdfIndirectObject({ content: pagesDict })
1561
+ }
1562
+
1563
+ function createCatalog(
1564
+ pagesRef: PdfObjectReference,
1565
+ ): PdfIndirectObject<PdfDictionary> {
1566
+ const catalogDict = new PdfDictionary()
1567
+ catalogDict.set('Type', new PdfName('Catalog'))
1568
+ catalogDict.set('Pages', pagesRef)
1569
+ return new PdfIndirectObject({ content: catalogDict })
1570
+ }
1571
+
1572
+ function createFont(): PdfIndirectObject<PdfDictionary> {
1573
+ const fontDict = new PdfDictionary()
1574
+ fontDict.set('Type', new PdfName('Font'))
1575
+ fontDict.set('Subtype', new PdfName('Type1'))
1576
+ fontDict.set('BaseFont', new PdfName('Helvetica'))
1577
+ return new PdfIndirectObject({ content: fontDict })
1578
+ }
1579
+
1580
+ function createResources(
1581
+ fontRef: PdfObjectReference,
1582
+ ): PdfIndirectObject<PdfDictionary> {
1583
+ const resourcesDict = new PdfDictionary()
1584
+ const fontDict = new PdfDictionary()
1585
+ fontDict.set('F1', fontRef)
1586
+ resourcesDict.set('Font', fontDict)
1587
+ return new PdfIndirectObject({ content: resourcesDict })
1588
+ }
1589
+
1590
+ function createPageWithSignatureField(
1591
+ contentStreamRef: PdfObjectReference,
1592
+ signatureAnnotRef: PdfObjectReference,
1593
+ ): PdfIndirectObject<PdfDictionary> {
1594
+ const pageDict = new PdfDictionary()
1595
+ pageDict.set('Type', new PdfName('Page'))
1596
+ pageDict.set(
1597
+ 'MediaBox',
1598
+ new PdfArray([
1599
+ new PdfNumber(0),
1600
+ new PdfNumber(0),
1601
+ new PdfNumber(612),
1602
+ new PdfNumber(792),
1603
+ ]),
1604
+ )
1605
+ pageDict.set('Contents', contentStreamRef)
1606
+ pageDict.set('Annots', new PdfArray([signatureAnnotRef]))
1607
+
1608
+ return new PdfIndirectObject({ content: pageDict })
1609
+ }
1610
+
1611
+ function createSignatureAnnotation(
1612
+ signatureRef: PdfObjectReference,
1613
+ appearanceStreamRef: PdfObjectReference,
1614
+ pageRef: PdfObjectReference,
1615
+ signatureName: string,
1616
+ ): PdfIndirectObject<PdfDictionary> {
1617
+ const signatureAnnotation = new PdfDictionary()
1618
+ signatureAnnotation.set('Type', new PdfName('Annot'))
1619
+ signatureAnnotation.set('Subtype', new PdfName('Widget'))
1620
+ signatureAnnotation.set('FT', new PdfName('Sig'))
1621
+ signatureAnnotation.set('T', new PdfString(signatureName))
1622
+ signatureAnnotation.set(
1623
+ 'Rect',
1624
+ new PdfArray([
1625
+ new PdfNumber(135), // x1: Start after "Signature: " text (~72 + 63)
1626
+ new PdfNumber(640), // y1: Bottom of signature area (652 - 12)
1627
+ new PdfNumber(400), // x2: End of signature line
1628
+ new PdfNumber(665), // y2: Top of signature area (652 + 13)
1629
+ ]),
1630
+ )
1631
+ signatureAnnotation.set('F', new PdfNumber(4))
1632
+ signatureAnnotation.set('P', pageRef) // Reference to parent page
1633
+ signatureAnnotation.set('V', signatureRef)
1634
+
1635
+ // Add appearance dictionary
1636
+ const appearanceDict = new PdfDictionary()
1637
+ appearanceDict.set('N', appearanceStreamRef)
1638
+ signatureAnnotation.set('AP', appearanceDict)
1639
+
1640
+ return new PdfIndirectObject({ content: signatureAnnotation })
1641
+ }
1642
+
1643
+ function createSignatureAppearance(): PdfIndirectObject<PdfStream> {
1644
+ // Create font for appearance
1645
+ const appearanceFont = new PdfDictionary()
1646
+ appearanceFont.set('Type', new PdfName('Font'))
1647
+ appearanceFont.set('Subtype', new PdfName('Type1'))
1648
+ appearanceFont.set('BaseFont', new PdfName('Helvetica'))
1649
+
1650
+ const fontDict = new PdfDictionary()
1651
+ fontDict.set('F1', appearanceFont)
1652
+
1653
+ const resourcesDict = new PdfDictionary()
1654
+ resourcesDict.set('Font', fontDict)
1655
+
1656
+ // Create appearance stream header
1657
+ const appearanceHeader = new PdfDictionary()
1658
+ appearanceHeader.set('Type', new PdfName('XObject'))
1659
+ appearanceHeader.set('Subtype', new PdfName('Form'))
1660
+ appearanceHeader.set(
1661
+ 'BBox',
1662
+ new PdfArray([
1663
+ new PdfNumber(0),
1664
+ new PdfNumber(0),
1665
+ new PdfNumber(265), // Width: 400 - 135
1666
+ new PdfNumber(25), // Height: 665 - 640
1667
+ ]),
1668
+ )
1669
+ appearanceHeader.set('Resources', resourcesDict)
1670
+
1671
+ // Create appearance stream for the signature
1672
+ return new PdfIndirectObject({
1673
+ content: new PdfStream({
1674
+ header: appearanceHeader,
1675
+ original:
1676
+ 'BT /F1 10 Tf 5 14 Td (Digitally signed by: Jake Shirley) Tj ET',
1677
+ }),
1678
+ })
1679
+ }
1680
+
1681
+ // Create the document
1682
+ const document = new PdfDocument()
1683
+
1684
+ // Create font
1685
+ const font = createFont()
1686
+ document.add(font)
1687
+
1688
+ // Create resources with the font
1689
+ const resources = createResources(font.reference)
1690
+ document.add(resources)
1691
+
1692
+ // Create content stream for first page
1693
+ const contentStream = new PdfIndirectObject({
1694
+ content: new PdfStream({
1695
+ header: new PdfDictionary(),
1696
+ original: 'BT /F1 24 Tf 100 700 Td (Hello, PDF-Lite!) Tj ET',
1697
+ }),
1698
+ })
1699
+ document.add(contentStream)
1700
+
1701
+ // Create first page
1702
+ const page1 = createPage(contentStream.reference)
1703
+ page1.content.set('Resources', resources.reference)
1704
+ document.add(page1)
1705
+
1706
+ // Array to hold all pages and signature objects
1707
+ const allPages: PdfIndirectObject<PdfDictionary>[] = [page1]
1708
+ const allSignatures: any[] = []
1709
+ const signatureFields: PdfObjectReference[] = []
1710
+
1711
+ // Helper function to create a signature page
1712
+ function createSignaturePage(
1713
+ signatureType: string,
1714
+ signatureObj: any,
1715
+ pageNumber: number,
1716
+ ) {
1717
+ const content = new PdfIndirectObject({
1718
+ content: new PdfStream({
1719
+ header: new PdfDictionary(),
1720
+ original: `BT /F1 12 Tf 72 712 Td (Signature Type: ${signatureType}) Tj 0 -60 Td (Signature: ________________________________) Tj ET`,
1721
+ }),
1722
+ })
1723
+ document.add(content)
1724
+
1725
+ const appearance = createSignatureAppearance()
1726
+ document.add(appearance)
1727
+
1728
+ // Create page first to get its reference
1729
+ const page = createPageWithSignatureField(
1730
+ content.reference,
1731
+ new PdfObjectReference(0, 0), // Temporary placeholder
1732
+ )
1733
+ page.content.set('Resources', resources.reference)
1734
+ document.add(page)
1735
+
1736
+ // Now create annotation with page reference
1737
+ const annotation = createSignatureAnnotation(
1738
+ signatureObj.reference,
1739
+ appearance.reference,
1740
+ page.reference,
1741
+ `Signature${pageNumber}`,
1742
+ )
1743
+ document.add(annotation)
1744
+
1745
+ // Update page's Annots array with actual annotation reference
1746
+ page.content.set('Annots', new PdfArray([annotation.reference]))
1747
+
1748
+ signatureFields.push(annotation.reference)
1749
+ return page
1750
+ }
1751
+
1752
+ // Page 2: Adobe PKCS7 Detached
1753
+ const pkcs7DetachedSig = new PdfAdbePkcs7DetachedSignatureObject({
1754
+ privateKey: rsaSigningKeys.privateKey,
1755
+ certificate: rsaSigningKeys.cert,
1756
+ issuerCertificate: rsaSigningKeys.caCert,
1757
+ name: 'Jake Shirley',
1758
+ location: 'Earth',
1759
+ reason: 'PKCS7 Detached Signature',
1760
+ contactInfo: 'test@test.com',
1761
+ revocationInfo: {
1762
+ crls: [rsaSigningKeys.caCrl],
1763
+ ocsps: [rsaSigningKeys.ocspResponse],
1764
+ },
1765
+ })
1766
+ allSignatures.push(pkcs7DetachedSig)
1767
+ allPages.push(createSignaturePage('Adobe PKCS7 Detached', pkcs7DetachedSig, 2))
1768
+
1769
+ // Page 3: Adobe PKCS7 SHA1
1770
+ const pkcs7Sha1Sig = new PdfAdbePkcs7Sha1SignatureObject({
1771
+ privateKey: rsaSigningKeys.privateKey,
1772
+ certificate: rsaSigningKeys.cert,
1773
+ issuerCertificate: rsaSigningKeys.caCert,
1774
+ name: 'Jake Shirley',
1775
+ location: 'Earth',
1776
+ reason: 'PKCS7 SHA1 Signature',
1777
+ contactInfo: 'test@test.com',
1778
+ })
1779
+ allSignatures.push(pkcs7Sha1Sig)
1780
+ allPages.push(createSignaturePage('Adobe PKCS7 SHA1', pkcs7Sha1Sig, 3))
1781
+
1782
+ // Page 4: Adobe X509 RSA SHA1
1783
+ const x509RsaSha1Sig = new PdfAdbePkcsX509RsaSha1SignatureObject({
1784
+ privateKey: rsaSigningKeys.privateKey,
1785
+ certificate: rsaSigningKeys.cert,
1786
+ additionalCertificates: [rsaSigningKeys.caCert],
1787
+ name: 'Jake Shirley',
1788
+ location: 'Earth',
1789
+ reason: 'X509 RSA SHA1 Signature',
1790
+ contactInfo: 'test@test.com',
1791
+ revocationInfo: {
1792
+ crls: [rsaSigningKeys.caCrl],
1793
+ ocsps: [rsaSigningKeys.ocspResponse],
1794
+ },
1795
+ })
1796
+ allSignatures.push(x509RsaSha1Sig)
1797
+ allPages.push(createSignaturePage('Adobe X509 RSA SHA1', x509RsaSha1Sig, 4))
1798
+
1799
+ // Page 5: ETSI CAdES Detached
1800
+ const cadesDetachedSig = new PdfEtsiCadesDetachedSignatureObject({
1801
+ privateKey: rsaSigningKeys.privateKey,
1802
+ certificate: rsaSigningKeys.cert,
1803
+ issuerCertificate: rsaSigningKeys.caCert,
1804
+ name: 'Jake Shirley',
1805
+ location: 'Earth',
1806
+ reason: 'CAdES Detached Signature',
1807
+ contactInfo: 'test@test.com',
1808
+ revocationInfo: {
1809
+ crls: [rsaSigningKeys.caCrl],
1810
+ ocsps: [rsaSigningKeys.ocspResponse],
1811
+ },
1812
+ })
1813
+ allSignatures.push(cadesDetachedSig)
1814
+ allPages.push(createSignaturePage('ETSI CAdES Detached', cadesDetachedSig, 5))
1815
+
1816
+ // Page 6: ETSI RFC3161 (Timestamp)
1817
+ const rfc3161Sig = new PdfEtsiRfc3161SignatureObject({
1818
+ timeStampAuthority: {
1819
+ url: 'https://freetsa.org/tsr',
1820
+ },
1821
+ })
1822
+ allSignatures.push(rfc3161Sig)
1823
+ allPages.push(createSignaturePage('ETSI RFC3161 Timestamp', rfc3161Sig, 6))
1824
+
1825
+ // Create pages collection with all pages
1826
+ const pages = createPages(allPages)
1827
+ // Set parent reference for all pages
1828
+ allPages.forEach((page) => {
1829
+ page.content.set('Parent', pages.reference)
1830
+ })
1831
+ document.add(pages)
1832
+
1833
+ // Create catalog with AcroForm
1834
+ const catalog = createCatalog(pages.reference)
1835
+
1836
+ // Add AcroForm to catalog with all signature fields
1837
+ const acroForm = new PdfDictionary()
1838
+ acroForm.set('Fields', new PdfArray(signatureFields))
1839
+ acroForm.set('SigFlags', new PdfNumber(3))
1840
+ const acroFormObj = new PdfIndirectObject({ content: acroForm })
1841
+ document.add(acroFormObj)
1842
+ catalog.content.set('AcroForm', acroFormObj.reference)
1843
+
1844
+ document.add(catalog)
1845
+
1846
+ // Set the catalog as the root
1847
+ document.trailerDict.set('Root', catalog.reference)
1848
+
1849
+ // IMPORTANT: Add all signatures LAST - after all other objects
1850
+ // This ensures the ByteRange is calculated correctly for each signature
1851
+ allSignatures.forEach((sig) => {
1852
+ document.startNewRevision()
1853
+ document.add(sig)
1854
+ })
1855
+
1856
+ await document.commit()
1857
+
1858
+ const documentBytes = document.toBytes()
1859
+ const newDocument = await PdfDocument.fromBytes([documentBytes])
1860
+
1861
+ const validationResult = await newDocument.verifySignatures()
1862
+ console.log(
1863
+ 'Signature validation result:',
1864
+ JSON.stringify(validationResult, null, 2),
1865
+ )
1866
+ ```
package/README.md CHANGED
@@ -8,9 +8,8 @@ A low-level, minimal-dependency, type-safe PDF library that works in the browser
8
8
 
9
9
  PRs and issues are welcome!
10
10
 
11
- ## License
12
-
13
- MIT License - see [LICENSE](LICENSE) for details.
11
+ [![npm version](https://img.shields.io/npm/v/pdf-lite.svg)](https://www.npmjs.com/package/pdf-lite)
12
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
14
13
 
15
14
  ## Features
16
15
 
@@ -99,6 +98,7 @@ Long-Term Validation (LTV) support ensures that digital signatures remain valid
99
98
  **Other features:**
100
99
 
101
100
  - [x] Timestamping
101
+ - [x] Verification of existing signatures
102
102
 
103
103
  ## Future Plans
104
104
 
@@ -283,3 +283,7 @@ import {
283
283
  PdfEtsiRfc3161SignatureObject,
284
284
  } from 'pdf-lite'
285
285
  ```
286
+
287
+ ## License
288
+
289
+ MIT License - see [LICENSE](LICENSE) for details.
@@ -1,2 +1,50 @@
1
1
  export * from './decoder.js';
2
+ export * from './generators.js';
3
+ export * from './incremental-parser.js';
4
+ export * from './objects/pdf-array.js';
5
+ export * from './objects/pdf-boolean.js';
6
+ export * from './objects/pdf-comment.js';
7
+ export * from './objects/pdf-date.js';
8
+ export * from './objects/pdf-dictionary.js';
9
+ export * from './objects/pdf-hexadecimal.js';
10
+ export * from './objects/pdf-indirect-object.js';
11
+ export * from './objects/pdf-name.js';
12
+ export * from './objects/pdf-null.js';
13
+ export * from './objects/pdf-number.js';
14
+ export * from './objects/pdf-object-reference.js';
15
+ export * from './objects/pdf-object.js';
16
+ export * from './objects/pdf-start-xref.js';
17
+ export * from './objects/pdf-stream.js';
18
+ export * from './objects/pdf-string.js';
19
+ export * from './objects/pdf-trailer.js';
20
+ export * from './objects/pdf-xref-table.js';
21
+ export * from './parser.js';
22
+ export * from './ref.js';
23
+ export * from './serializer.js';
24
+ export * from './streams/object-stream.js';
2
25
  export * from './tokeniser.js';
26
+ export * from './tokens/boolean-token.js';
27
+ export * from './tokens/byte-offset-token.js';
28
+ export * from './tokens/comment-token.js';
29
+ export * from './tokens/end-array-token.js';
30
+ export * from './tokens/end-dictionary-token.js';
31
+ export * from './tokens/end-object-token.js';
32
+ export * from './tokens/end-stream-token.js';
33
+ export * from './tokens/hexadecimal-token.js';
34
+ export * from './tokens/name-token.js';
35
+ export * from './tokens/null-token.js';
36
+ export * from './tokens/number-token.js';
37
+ export * from './tokens/object-reference-token.js';
38
+ export * from './tokens/start-array-token.js';
39
+ export * from './tokens/start-dictionary-token.js';
40
+ export * from './tokens/start-object-token.js';
41
+ export * from './tokens/start-stream-token.js';
42
+ export * from './tokens/start-xref-token.js';
43
+ export * from './tokens/stream-chunk-token.js';
44
+ export * from './tokens/string-token.js';
45
+ export * from './tokens/token.js';
46
+ export * from './tokens/trailer-token.js';
47
+ export * from './tokens/whitespace-token.js';
48
+ export * from './tokens/xref-table-entry-token.js';
49
+ export * from './tokens/xref-table-section-start-token.js';
50
+ export * from './tokens/xref-table-start-token.js';
@@ -1,2 +1,50 @@
1
1
  export * from './decoder.js';
2
+ export * from './generators.js';
3
+ export * from './incremental-parser.js';
4
+ export * from './objects/pdf-array.js';
5
+ export * from './objects/pdf-boolean.js';
6
+ export * from './objects/pdf-comment.js';
7
+ export * from './objects/pdf-date.js';
8
+ export * from './objects/pdf-dictionary.js';
9
+ export * from './objects/pdf-hexadecimal.js';
10
+ export * from './objects/pdf-indirect-object.js';
11
+ export * from './objects/pdf-name.js';
12
+ export * from './objects/pdf-null.js';
13
+ export * from './objects/pdf-number.js';
14
+ export * from './objects/pdf-object-reference.js';
15
+ export * from './objects/pdf-object.js';
16
+ export * from './objects/pdf-start-xref.js';
17
+ export * from './objects/pdf-stream.js';
18
+ export * from './objects/pdf-string.js';
19
+ export * from './objects/pdf-trailer.js';
20
+ export * from './objects/pdf-xref-table.js';
21
+ export * from './parser.js';
22
+ export * from './ref.js';
23
+ export * from './serializer.js';
24
+ export * from './streams/object-stream.js';
2
25
  export * from './tokeniser.js';
26
+ export * from './tokens/boolean-token.js';
27
+ export * from './tokens/byte-offset-token.js';
28
+ export * from './tokens/comment-token.js';
29
+ export * from './tokens/end-array-token.js';
30
+ export * from './tokens/end-dictionary-token.js';
31
+ export * from './tokens/end-object-token.js';
32
+ export * from './tokens/end-stream-token.js';
33
+ export * from './tokens/hexadecimal-token.js';
34
+ export * from './tokens/name-token.js';
35
+ export * from './tokens/null-token.js';
36
+ export * from './tokens/number-token.js';
37
+ export * from './tokens/object-reference-token.js';
38
+ export * from './tokens/start-array-token.js';
39
+ export * from './tokens/start-dictionary-token.js';
40
+ export * from './tokens/start-object-token.js';
41
+ export * from './tokens/start-stream-token.js';
42
+ export * from './tokens/start-xref-token.js';
43
+ export * from './tokens/stream-chunk-token.js';
44
+ export * from './tokens/string-token.js';
45
+ export * from './tokens/token.js';
46
+ export * from './tokens/trailer-token.js';
47
+ export * from './tokens/whitespace-token.js';
48
+ export * from './tokens/xref-table-entry-token.js';
49
+ export * from './tokens/xref-table-section-start-token.js';
50
+ export * from './tokens/xref-table-start-token.js';
@@ -6,7 +6,7 @@ export declare class PdfArray<T extends PdfObject = PdfObject> extends PdfObject
6
6
  constructor(items?: T[]);
7
7
  get length(): number;
8
8
  push(item: T): void;
9
- protected tokenize(): import("../tokens/token").PdfToken[];
9
+ protected tokenize(): import("..").PdfToken[];
10
10
  clone(): this;
11
11
  isModified(): boolean;
12
12
  }
@@ -20,7 +20,7 @@ export declare class PdfIndirectObject<T extends PdfObject = PdfObject> extends
20
20
  static createPlaceholder<T extends PdfObject>(objectNumber?: number, generationNumber?: number, content?: T): PdfIndirectObject<T extends unknown ? PdfNull : T>;
21
21
  inPdf(): boolean;
22
22
  matchesReference(ref?: PdfObjectReference): boolean;
23
- protected tokenize(): import("../tokens/token").PdfToken[];
23
+ protected tokenize(): import("..").PdfToken[];
24
24
  clone(): this;
25
25
  order(): number;
26
26
  isModified(): boolean;
@@ -4,7 +4,7 @@ import { PdfObject } from './pdf-object';
4
4
  export declare class PdfStartXRef extends PdfObject {
5
5
  offset: PdfNumber;
6
6
  constructor(offset?: number | PdfNumber | Ref<number>);
7
- protected tokenize(): import("../tokens/token").PdfToken[];
7
+ protected tokenize(): import("..").PdfToken[];
8
8
  clone(): this;
9
9
  isModified(): boolean;
10
10
  }
@@ -42,7 +42,7 @@ export declare class PdfXRefTable extends PdfObject {
42
42
  addEntryForObject(obj: PdfIndirectObject): void;
43
43
  getEntry(objectNumber: number): PdfXRefTableEntry | undefined;
44
44
  get lastSection(): PdfXRefTableSectionHeader | null;
45
- protected tokenize(): import("../tokens/token").PdfToken[];
45
+ protected tokenize(): import("..").PdfToken[];
46
46
  private sortEntriesIntoSections;
47
47
  clone(): this;
48
48
  }
@@ -13,13 +13,14 @@ export class PdfNumberToken extends PdfToken {
13
13
  options instanceof Ref ||
14
14
  options instanceof PdfNumberToken) {
15
15
  this.#value = PdfNumberToken.getValue(options);
16
- this.padTo = padTo ?? 0;
17
- this.decimalPlaces = decimalPlaces ?? 0;
16
+ this.padTo = padTo ?? PdfNumberToken.getPadding(options);
17
+ this.decimalPlaces =
18
+ decimalPlaces ?? PdfNumberToken.getDecimalPlaces(options);
18
19
  this.isByteToken = false;
19
20
  return;
20
21
  }
21
22
  this.#value = PdfNumberToken.getValue(options.value);
22
- this.padTo = options.padTo ?? 0;
23
+ this.padTo = options.padTo ?? PdfNumberToken.getPadding(options.value);
23
24
  this.decimalPlaces =
24
25
  options.decimalPlaces ??
25
26
  PdfNumberToken.getDecimalPlaces(options.value);
@@ -63,12 +64,16 @@ export class PdfNumberToken extends PdfToken {
63
64
  if (typeof bytes === 'number') {
64
65
  bytes = PdfNumberToken.toBytes(bytes);
65
66
  }
66
- let padding = 0;
67
+ // Count leading zeros
68
+ let leadingZeros = 0;
69
+ const originalLength = bytes.length;
67
70
  while (bytes.length && bytes[0] === 0x30) {
68
71
  bytes = bytes.slice(1);
69
- padding++;
72
+ leadingZeros++;
70
73
  }
71
- return padding;
74
+ // If all characters were zeros (value is 0), padding should be total length
75
+ // Otherwise, padding should be total length (to maintain original formatting)
76
+ return originalLength;
72
77
  }
73
78
  static getDecimalPlaces(bytes) {
74
79
  if (bytes instanceof PdfNumberToken) {
@@ -0,0 +1,11 @@
1
+ export * from './ciphers/aes128.js';
2
+ export * from './ciphers/aes256.js';
3
+ export * from './ciphers/rc4.js';
4
+ export * from './constants.js';
5
+ export * from './key-derivation/key-derivation-aes256.js';
6
+ export * from './key-derivation/key-derivation.js';
7
+ export * from './key-gen/key-gen-aes256.js';
8
+ export * from './key-gen/key-gen-rc4-128.js';
9
+ export * from './key-gen/key-gen-rc4-40.js';
10
+ export * from './types.js';
11
+ export * from './utils.js';
@@ -0,0 +1,11 @@
1
+ export * from './ciphers/aes128.js';
2
+ export * from './ciphers/aes256.js';
3
+ export * from './ciphers/rc4.js';
4
+ export * from './constants.js';
5
+ export * from './key-derivation/key-derivation-aes256.js';
6
+ export * from './key-derivation/key-derivation.js';
7
+ export * from './key-gen/key-gen-aes256.js';
8
+ export * from './key-gen/key-gen-rc4-128.js';
9
+ export * from './key-gen/key-gen-rc4-40.js';
10
+ export * from './types.js';
11
+ export * from './utils.js';
@@ -1,18 +1,4 @@
1
1
  import { ByteArray } from '../../types.js';
2
- /**
3
- * Pads a password to exactly 32 bytes using the PDF standard padding.
4
- * If the password is shorter than 32 bytes, it is padded with bytes from DEFAULT_PADDING.
5
- * If the password is 32 bytes or longer, only the first 32 bytes are used.
6
- *
7
- * @param password - The password to pad.
8
- * @returns A 32-byte padded password.
9
- *
10
- * @example
11
- * ```typescript
12
- * const padded = padPassword(new Uint8Array([1, 2, 3])) // Returns 32-byte array
13
- * ```
14
- */
15
- export declare function padPassword(password: ByteArray): ByteArray;
16
2
  /**
17
3
  * Compute the master encryption key for a PDF file.
18
4
  *
@@ -1,31 +1,6 @@
1
- import { DEFAULT_PADDING } from '../constants.js';
2
1
  import { md5 } from '../../utils/algos.js';
3
- import { int32ToLittleEndianBytes } from '../utils.js';
2
+ import { int32ToLittleEndianBytes, padPassword } from '../utils.js';
4
3
  import { concatUint8Arrays } from '../../utils/concatUint8Arrays.js';
5
- /**
6
- * Pads a password to exactly 32 bytes using the PDF standard padding.
7
- * If the password is shorter than 32 bytes, it is padded with bytes from DEFAULT_PADDING.
8
- * If the password is 32 bytes or longer, only the first 32 bytes are used.
9
- *
10
- * @param password - The password to pad.
11
- * @returns A 32-byte padded password.
12
- *
13
- * @example
14
- * ```typescript
15
- * const padded = padPassword(new Uint8Array([1, 2, 3])) // Returns 32-byte array
16
- * ```
17
- */
18
- export function padPassword(password) {
19
- const padded = new Uint8Array(32);
20
- if (password.length >= 32) {
21
- padded.set(password.subarray(0, 32));
22
- }
23
- else {
24
- padded.set(password);
25
- padded.set(DEFAULT_PADDING.subarray(0, 32 - password.length), password.length);
26
- }
27
- return padded;
28
- }
29
4
  /**
30
5
  * Compute the master encryption key for a PDF file.
31
6
  *
@@ -2,8 +2,7 @@ import { md5 } from '../../utils/algos';
2
2
  import { concatUint8Arrays } from '../../utils/concatUint8Arrays';
3
3
  import { rc4 } from '../ciphers/rc4';
4
4
  import { DEFAULT_PADDING } from '../constants';
5
- import { padPassword } from '../key-derivation/key-derivation';
6
- import { int32ToLittleEndianBytes, removePdfPasswordPadding } from '../utils';
5
+ import { int32ToLittleEndianBytes, padPassword, removePdfPasswordPadding, } from '../utils';
7
6
  /**
8
7
  * Encrypts data with RC4 using the provided key.
9
8
  *
@@ -1,7 +1,6 @@
1
- import { padPassword } from '../key-derivation/key-derivation.js';
2
1
  import { rc4 } from '../ciphers/rc4.js';
3
2
  import { DEFAULT_PADDING } from '../constants.js';
4
- import { int32ToLittleEndianBytes, removePdfPasswordPadding } from '../utils.js';
3
+ import { int32ToLittleEndianBytes, padPassword, removePdfPasswordPadding, } from '../utils.js';
5
4
  import { md5 } from '../../utils/algos.js';
6
5
  import { concatUint8Arrays } from '../../utils/concatUint8Arrays.js';
7
6
  /**
@@ -0,0 +1,7 @@
1
+ export * from './ascii85.js';
2
+ export * from './asciihex.js';
3
+ export * from './flate.js';
4
+ export * from './lzw.js';
5
+ export * from './pass-through.js';
6
+ export * from './runlength.js';
7
+ export * from './types.js';