pdf-codec 4.0.12 → 4.1.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/README.md +6 -5
- package/dist/annotations.d.cts +1 -1
- package/dist/annotations.d.ts +1 -1
- package/dist/attachments.d.cts +1 -1
- package/dist/attachments.d.ts +1 -1
- package/dist/content-read.d.cts +1 -1
- package/dist/content-read.d.ts +1 -1
- package/dist/crypto/random.cjs +9 -0
- package/dist/crypto/random.d.cts +4 -0
- package/dist/crypto/random.d.ts +4 -0
- package/dist/crypto/random.js +8 -0
- package/dist/document.d.cts +1 -1
- package/dist/document.d.ts +1 -1
- package/dist/embedded-font-write.d.cts +1 -1
- package/dist/embedded-font-write.d.ts +1 -1
- package/dist/encrypt-write.cjs +234 -0
- package/dist/encrypt-write.d.cts +31 -0
- package/dist/encrypt-write.d.ts +31 -0
- package/dist/encrypt-write.js +231 -0
- package/dist/encrypt.cjs +50 -20
- package/dist/encrypt.d.cts +18 -2
- package/dist/encrypt.d.ts +18 -2
- package/dist/encrypt.js +35 -21
- package/dist/filters.d.cts +1 -1
- package/dist/filters.d.ts +1 -1
- package/dist/font-read.d.cts +1 -1
- package/dist/font-read.d.ts +1 -1
- package/dist/form.d.cts +1 -1
- package/dist/form.d.ts +1 -1
- package/dist/images-read.d.cts +1 -1
- package/dist/images-read.d.ts +1 -1
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/interpret.d.cts +1 -1
- package/dist/interpret.d.ts +1 -1
- package/dist/math-font-write.d.cts +1 -1
- package/dist/math-font-write.d.ts +1 -1
- package/dist/names.d.cts +1 -1
- package/dist/names.d.ts +1 -1
- package/dist/navigation.d.cts +1 -1
- package/dist/navigation.d.ts +1 -1
- package/dist/objects-B7HdMeWS.d.cts +59 -0
- package/dist/objects-B7HdMeWS.d.ts +59 -0
- package/dist/objects.d.cts +1 -58
- package/dist/objects.d.ts +1 -58
- package/dist/optional-content.d.cts +1 -1
- package/dist/optional-content.d.ts +1 -1
- package/dist/parse.d.cts +1 -1
- package/dist/parse.d.ts +1 -1
- package/dist/predictors.d.cts +1 -1
- package/dist/predictors.d.ts +1 -1
- package/dist/serialize.d.cts +1 -1
- package/dist/serialize.d.ts +1 -1
- package/dist/structure.d.cts +1 -1
- package/dist/structure.d.ts +1 -1
- package/dist/tounicode.d.cts +1 -1
- package/dist/tounicode.d.ts +1 -1
- package/dist/write.cjs +29 -6
- package/dist/write.d.cts +2 -0
- package/dist/write.d.ts +2 -0
- package/dist/write.js +29 -6
- package/dist/xref.d.cts +1 -1
- package/dist/xref.d.ts +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
> A hand-written, dependency-minimal PDF codec: parses arbitrary real-world PDFs into a structured, positioned-content document and generates new PDFs from one, built on its own codec-owned `LayoutDocument` item model and [Zod 4](https://zod.dev) codecs.
|
|
6
6
|
|
|
7
|
-
`pdf-codec` is the PDF-reading-and-writing half of [`documents.js`](https://github.com/ExaDev/documents.js), extracted into its own package: every layer of the PDF format — the object model, the cross-reference table, the content-stream operators, standard-font metrics, the parser's cross-reference/object-stream resolution and content-stream interpreter — is hand-written against the ISO 32000-1 specification, with no external PDF library (`pdf-lib`, `pdfjs-dist`, `mupdf`, or any other) as a dependency. The one exception is [`fflate`](https://github.com/101arrowz/fflate) for raw DEFLATE/zlib compression. The OpenType/CFF font parsing this package's own writer uses to embed a real math font (`sfnt.ts`/`math-*.ts`) is hand-written too, as are the cryptographic primitives
|
|
7
|
+
`pdf-codec` is the PDF-reading-and-writing half of [`documents.js`](https://github.com/ExaDev/documents.js), extracted into its own package: every layer of the PDF format — the object model, the cross-reference table, the content-stream operators, standard-font metrics, the parser's cross-reference/object-stream resolution and content-stream interpreter — is hand-written against the ISO 32000-1 specification, with no external PDF library (`pdf-lib`, `pdfjs-dist`, `mupdf`, or any other) as a dependency. The one exception is [`fflate`](https://github.com/101arrowz/fflate) for raw DEFLATE/zlib compression. The OpenType/CFF font parsing this package's own writer uses to embed a real math font (`sfnt.ts`/`math-*.ts`) is hand-written too, as are the cryptographic primitives the reader needs to open an encrypted PDF and the writer needs to produce one (`crypto/` — MD5, SHA-2, RC4, AES, and a `getRandomValues`-backed CSPRNG for the writer's own salts/keys/IVs), because `node:crypto` would end this package's platform neutrality and WebCrypto's `crypto.subtle` offers neither MD5 nor RC4 nor a synchronous API (`crypto.getRandomValues` itself is synchronous and used directly). The one bundled binary asset is the vendored STIX Two Math font itself (OFL-1.1, see [Fidelity](#fidelity) and `assets/fonts/NOTICE.md`).
|
|
8
8
|
|
|
9
9
|
This is a genuinely large undertaking with an honest trade-off spelled out in [Fidelity](#fidelity): this is not, and does not attempt to be, as robust against adversarial or badly malformed real-world PDFs as a library with 15+ years of hardening. What it buys instead is a dependency-free, fully auditable PDF implementation with no supply-chain surface beyond `document-schema.js`, `fflate`, and `zod`.
|
|
10
10
|
|
|
@@ -89,7 +89,7 @@ const bytes = writePdf(layout);
|
|
|
89
89
|
|
|
90
90
|
There is deliberately **no `DocumentTree`-returning read or `DocumentTree`-accepting write here**, and `readPdf`/`writePdf` are this package's primary API precisely because of that. Only `markdown-codec`'s own read entry point returns `document-schema.js`'s flat `ContentDocument` directly — `ooxml.js`'s `readDocx`/`readPptx` return `DocxDocument`/`PptxDocument` and `odf.js`'s `readOdt`/`readOds` return `OdtDocument`/`OdsDocument`, each codec's own native model, with only `ooxml.js`'s separate `readXlsxContent` producing a `ContentDocument` outright. What lets `documents.js` offer one tree-native entry point uniformly across those formats (`decompose`/`assembleTree` outward, `flattenTree` back) is its own `readXContent` wrapper layer (`readDocxContent`, `readOdtContent`, and siblings), projecting each codec's native model into the flat `ContentDocument` — a step the codecs themselves don't take. PDF has no such wrapper to project through: `readPdf` yields _layout_ cheaply, because positioned glyphs and paths are all the format actually states, and semantic content only through a separate, expensive, lossy reconstruction pass that infers paragraphs, headings, tables, and shapes back out of geometry. That inference is semantic policy rather than codec business, so it lives in `documents.js` — a caller wanting a PDF as a `DocumentTree` passes `onDocument` to a named conversion function or to `convertDocument` itself and reads the tree off that callback (`convertDocument` on its own returns only bytes), or uses `createLocalDocumentConverter()`'s `DocumentConverter` port, whose `ConversionResult.package` is populated by wiring that same callback internally. The write direction is asymmetric for a different reason than it might look: turning a `DocumentTree` into PDF bytes is not itself a layout pass — `documents.js`'s `layoutDocumentFromPackage` is a mechanical inverse that walks the positions a _prior_ layout pass already stamped onto the package's own content nodes as `frames`, and it only works at all when those frames exist (a bridge conversion's own dump, e.g. `odt-to-docx`, carries no `pages` and cannot reach PDF this way). The actual font-measuring, line-breaking engine runs earlier, wherever the package first passed through an X-to-PDF or PDF-to-X conversion — both the frame-stamping and the frame-walking are `documents.js`'s. Keeping both edges out of this package is still what makes the item layer an honest record of what a file says, separate from what any consumer thinks it means.
|
|
91
91
|
|
|
92
|
-
An encrypted PDF that opens without a password decrypts transparently — no extra option, no password parameter; one that genuinely needs a user password throws `PdfPasswordRequiredError`. See [Gotchas](#gotchas-and-quirks) for exactly which encryption is supported.
|
|
92
|
+
An encrypted PDF that opens without a password decrypts transparently — no extra option, no password parameter; one that genuinely needs a user password throws `PdfPasswordRequiredError`. `writePdf` encrypts on the way out via its own `encryption` option (`WritePdfOptions.encryption`, `PdfEncryptionOptions` from `pdf-codec`) — a user password, an optional owner password, a choice of scheme (`"rc4-40" | "rc4-128" | "aes-128" | "aes-256"`, default `"aes-256"`), and permission flags. See [Gotchas](#gotchas-and-quirks) for exactly which encryption is supported on both sides.
|
|
93
93
|
|
|
94
94
|
Both accept an optional `signal` (`AbortSignal`); `readPdf` additionally takes a `sink` (`PdfDiagnosticSink`, called once per recoverable parse diagnostic — see the three-tier failure policy under [Conventions](#conventions)), and `writePdf` an `onSubstitution` callback (called once per character not representable in a standard-14 font — see [Fidelity](#fidelity)).
|
|
95
95
|
|
|
@@ -232,7 +232,7 @@ The package is layered from generic primitives outward to the codec itself:
|
|
|
232
232
|
- **The math port types** — `MathColor`/`MathGlyphRun`/`MathRule`/`MathStroke`/`MathLayoutItem`/`MathBox`/`MathGlyphMetrics`/`MathFontMetrics` and `PositionedFormula`, sourced from `document-schema.js`'s math layout port (one shared definition across the family, not a local mirror). Deliberately not imported from `documents.js` — that would be a circular dependency once `documents.js` depends on this package. Because every one of these types is plain data (only `MathFontMetrics` carries a method), a real `MathBox` value `documents.js` produces passes into `writePdf({ formulas })` with zero cast, zero wrapper, and zero transformation.
|
|
233
233
|
- **`src/bytes/`** and **`src/image/`** — generic byte and image-container primitives with zero PDF-specific knowledge: a chunked byte writer, backtracking byte reader, CRC32, a hand-written PNG decoder/encoder, JPEG marker scanning for dimensions only (compressed bytes pass through unchanged), a hand-written CCITT Group 3/Group 4 fax decoder (ITU-T T.4/T.6), a hand-written JBIG2 decoder (ITU-T T.88 — `jbig2-arith.ts` MQ decoder, `jbig2-bitmap.ts`, `jbig2-generic.ts`, `jbig2-text.ts`, `jbig2.ts`), and a hand-written JPEG 2000 decoder (ISO/IEC 15444-1 — `jp2-boxes.ts`, `jpeg2000-codestream.ts`, `jpeg2000-tagtree.ts`, `jpeg2000-t2.ts`, `jpeg2000-t1.ts`, `jpeg2000-dwt.ts`, `jpeg2000.ts`). `src/filters.ts` owns all PDF knowledge for CCITT/JBIG2 (resolving parameters, `/JBIG2Globals`, inverting polarity); `src/images-read.ts` owns the JPEG 2000 PDF integration. `src/bytes/flate.ts` is the only file that imports `fflate`.
|
|
234
234
|
- **`src/util/`** — two small independently-duplicated copies of family-shared logic: `base64.ts` (verbatim copy of `odf.js`'s own, replacing a former `ooxml.js` dependency for this one helper) and `abort.ts` (`throwIfAborted`, called at every page loop boundary — there is no `await` point in this synchronous pipeline for cancellation to hook into implicitly).
|
|
235
|
-
- **`src/crypto/`** — MD5, SHA-256/384/512, RC4, and AES-CBC, hand-written with zero local imports. Not a preference: ISO 32000-1's key-derivation algorithms name MD5 and RC4 directly, neither offered by any portable platform crypto API, and `crypto.subtle` is asynchronous where this codec's read
|
|
235
|
+
- **`src/crypto/`** — MD5, SHA-256/384/512, RC4, and AES-CBC, hand-written with zero local imports, plus a thin `random.ts` wrapper around `globalThis.crypto.getRandomValues` for the writer's own salts/file keys/IVs. Not a preference: ISO 32000-1's key-derivation algorithms name MD5 and RC4 directly, neither offered by any portable platform crypto API, and `crypto.subtle` is asynchronous where this codec's read and write paths are both synchronous end to end — `getRandomValues` itself, unlike `crypto.subtle`, is synchronous and portable, so it is used directly rather than hand-written. Reaching for `node:crypto` would break the browser bundle. Each hash/cipher module cites its specification (RFC 1321, FIPS 180-4, FIPS 197) and is tested against published conformance vectors.
|
|
236
236
|
- **The codec itself, importing only `layout`/`bytes`/`image`/`crypto`/`util` plus `document-schema.js`'s port types (no OOXML or ODF knowledge):**
|
|
237
237
|
- **Write**: `objects.ts` (the `PdfObject` discriminated union), `afm-widths.ts`/`encoding.ts`/`winansi.ts`/`fonts.ts` (standard-14 metrics, WinAnsi encoding, family resolution), `font-registry.ts` (resolution port plus `resolveFaceWithRegistry`, the one step both measurer and writer resolve through so they can never disagree about which face a `LayoutFont` means), `font-face.ts` (`readFontFace`, reading a standalone font file's family/bold/italic triple off its `name`/`OS/2`/`head` tables), `measure.ts`/`text-layout.ts` (greedy line-wrapping against either standard-14 AFM widths plus per-family correction or a resolved face's own real `hmtx` advances — never both), `content-write.ts` (`LayoutItem[]` → content-stream operators, with text branching on standard-14 vs embedded face encoding, pair-kerning split into `TJ` arrays, and stroke `style` becoming real dash/line-cap state), `write.ts` (the full object graph, cross-reference table, trailer, and embedded font groups).
|
|
238
238
|
- **sfnt font tables**: `sfnt.ts` (bounds-checked table-directory reader), `cmap-table.ts` (character code → glyph ID, formats 0/4/6/12, exposed both as the best Unicode lookup and as every subtable individually, since a (3, 0) or (1, 0) subtable is keyed by a font's own codes rather than by code points), `hmtx-table.ts` (per-glyph advance widths), `font-tables.ts` (`head`/`maxp`/`OS/2`/`post`/`name`, including `post`'s own glyph names where a font still carries them), `glyf.ts` (`loca` offset index, per-glyph headers, composite component records, `glyphInkBounds`), `math-table.ts` (OpenType `MATH` constants/glyph-info/variants subtables). `ot-layout-common.ts` (Coverage/ClassDef, stored as sorted glyph ranges searched by bisection). `gpos-table.ts` reads `GPOS` for exactly one thing: pair-advance kerning through the `kern` feature, both PairPos formats and LookupType 9 Extension indirection — mark attachment, cursive joining, and contextual positioning have no consumer here. Every parser degrades to `undefined` on a missing/truncated table rather than throwing.
|
|
@@ -261,7 +261,8 @@ Dependency direction is strictly downward and checkable: `layout` imports only `
|
|
|
261
261
|
|
|
262
262
|
- **Reading arbitrary real-world PDFs is the single largest risk surface in this package**, and the parser targets cleanly-generated output from mainstream producers (Word, PowerPoint, Chrome, LibreOffice, Acrobat), recovering from the malformations those producers actually create, and failing loudly and specifically on anything else — not matching a mature library's robustness against adversarial input.
|
|
263
263
|
- **An encrypted PDF is readable when, and only when, it opens without a password** — the overwhelmingly common real-world case (a permissions-only file whose owner password may be set but whose user password is empty). Supported: `/Filter /Standard` at `/V` 1, 2, 4, and 5 — RC4-40, RC4-128, AES-128, AES-256 — including `/EncryptMetadata false` and `/Identity` crypt filters. A file genuinely needing a user password throws `PdfPasswordRequiredError` (distinct from `PdfEncryptedError`, because "supply the password" and "this codec cannot read this at all" are different things to tell a user).
|
|
264
|
-
- **Nothing in this codec accepts, prompts for, or guesses a password.** Authenticating as owner is a permissions escalation, not a way to read a file you were already allowed to read.
|
|
264
|
+
- **Nothing in this codec's reader accepts, prompts for, or guesses a password.** Authenticating as owner is a permissions escalation, not a way to read a file you were already allowed to read.
|
|
265
|
+
- **`writePdf` produces real, spec-conformant encryption for all four of the schemes above** (`src/encrypt-write.ts`, `WritePdfOptions.encryption`) — genuine `/O`/`/U`/`/OE`/`/UE`/`/Perms` computation per ISO 32000-2 7.6.4.4's Algorithms 3, 8, 9, and 10, a real user and (optional, defaulting to the user password) owner password, and per-`/P`-bit permission flags. Unlike the reader, the writer's own password is not scoped to empty: a genuinely non-empty user password is fully supported and round-trips against the published algorithm (see `encrypt-write.test.ts`), even though this package's own reader — scoped as above — can only ever open the result back up if the user password used to encrypt it was itself empty. Two boundaries are deliberately narrower than the full spec rather than approximated silently: a revision 2-4 (rc4-40/rc4-128/aes-128) password must be plain printable ASCII, not the full 8-bit PDFDocEncoding table, and a revision 6 (aes-256) password is Unicode-normalised with NFKC rather than the full SASLPrep/stringprep profile (prohibited-character tables and the bidirectional-text rule are not implemented). Both throw `PdfEncryptionError` for a password outside that scope rather than silently mis-encoding it into one that will not open the file it was meant to protect.
|
|
265
266
|
- **`CCITTFaxDecode`, `JBIG2Decode` and `JPXDecode` images all decode for real** via hand-written decoders (`src/image/ccitt.ts` for ITU-T T.4/T.6 fax; `src/image/jbig2*.ts` for ITU-T T.88; `src/image/jpeg2000*.ts` for ISO/IEC 15444-1). JPEG images (`DCTDecode`) pass through losslessly in both directions. See [JBIG2 scope](#jbig2-scope) and [JPEG 2000 scope](#jpeg-2000-scope) for exactly what is and is not implemented.
|
|
266
267
|
- **`interpret.ts` tracks general vector paths, not just axis-aligned `re` rectangles.** `m`/`l`/`c`/`v`/`y`/`h` (and `re` itself) accumulate real subpaths — CTM-transformed line/cubic segments, open or closed — and any paint operator emits an item built from them. A recovered path matching one of three characteristic shape patterns comes back as that shape's own kind, not a generic `LayoutPath`: an axis-aligned closed four-corner subpath is a `LayoutRect`; a closed subpath of four cubic segments meeting its bounding box at cardinal points with kappa-ratio control points is a `LayoutEllipse`; an open single-straight-segment stroke-only subpath is a `LayoutLine` (tolerance: `max(1e-3pt, 1e-4 × extent)`). **These are deliberate, bounded heuristics** — a false positive changes an item's kind, never its geometry, since every detected shape reproduces its source path's own points exactly. Off-axis rotations, non-quadrant curves, polygons, and multi-subpath figures stay a `LayoutPath`.
|
|
267
268
|
- **`writePdf`/`readPdf` round-trip a page's own `notes` field via a hidden `/Subtype /Text` annotation** with the `Hidden` flag set so it never renders or prints, distinguished from a genuine third-party sticky note by an internal author marker. This is a round-trip mechanism specific to this package's own writer/reader pair. `documents.js` uses this to carry pptx/odp speaker notes through PDF.
|
|
@@ -347,7 +348,7 @@ There is a single `main` branch and no open pull request workflow established so
|
|
|
347
348
|
- [documents.js](https://github.com/ExaDev/documents.js) — the package this codec was extracted from, and its principal downstream consumer: docx/pptx/odt/odp/ods/odg ⇄ PDF conversion, and MathML formula rendering (its own `src/mathml/` typesetting engine feeds a real `MathBox` into this package's `writePdf({ formulas })` with zero cast).
|
|
348
349
|
- [document-schema.js](../document-schema.js/README.md) — the sibling package that owns the canonical `ContentDocument`/`DocumentTree` pivots the wider family shares, plus the shared leaf shapes and port types this package imports (`Color`, `LayoutFont`, `LayoutMetadata`, `TextMeasurer`, the math family). The `LayoutDocument` item family itself lived there until moving into this package.
|
|
349
350
|
- [qpdf](https://qpdf.sourceforge.io/) — the independent implementation that produces this package's encrypted-PDF test fixtures. A build-time and test-time tool only, never a dependency of the package itself.
|
|
350
|
-
- The specifications `src/crypto/` implements, each cited in the module that implements it and checked against published conformance vectors: [RFC 1321](https://www.rfc-editor.org/rfc/rfc1321) (MD5), [FIPS 180-4](https://csrc.nist.gov/pubs/fips/180-4/upd1/final) (SHA-256/384/512), [FIPS 197](https://csrc.nist.gov/pubs/fips/197/final) (AES), and [NIST SP 800-38A](https://csrc.nist.gov/pubs/sp/800/38/a/final) (CBC mode). The standard security handler is ISO 32000-1 7.6, extended for revisions 5 and 6 by ISO 32000-2 7.6.4.3.
|
|
351
|
+
- The specifications `src/crypto/` implements, each cited in the module that implements it and checked against published conformance vectors: [RFC 1321](https://www.rfc-editor.org/rfc/rfc1321) (MD5), [FIPS 180-4](https://csrc.nist.gov/pubs/fips/180-4/upd1/final) (SHA-256/384/512), [FIPS 197](https://csrc.nist.gov/pubs/fips/197/final) (AES), and [NIST SP 800-38A](https://csrc.nist.gov/pubs/sp/800/38/a/final) (CBC mode). The standard security handler is ISO 32000-1 7.6, extended for revisions 5 and 6 by ISO 32000-2 7.6.4.3; the write side's own password algorithms (`src/encrypt-write.ts`) are ISO 32000-2 7.6.4.4's Algorithms 3, 8, 9, and 10.
|
|
351
352
|
- [STIX Two Math](https://github.com/stipub/stixfonts) — the embedded math font, vendored at `assets/fonts/STIXTwoMath-Regular.otf` and embedded into `dist/` as a base64 string (`src/assets/stix-two-math-font.ts`, generated by `scripts/generate-math-font-asset.mjs`). Copyright 2001-2021 The STIX Fonts Project Authors, licensed [OFL-1.1](assets/fonts/OFL.txt) — see `assets/fonts/NOTICE.md` for the exact source commit and version.
|
|
352
353
|
|
|
353
354
|
## npm aliases
|
package/dist/annotations.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PdfDiagnosticSink } from "./diagnostics.cjs";
|
|
2
2
|
import { r as Matrix } from "./matrix-B7_SBKQ5.cjs";
|
|
3
|
-
import { PdfDict } from "./objects.cjs";
|
|
3
|
+
import { n as PdfDict } from "./objects-B7HdMeWS.cjs";
|
|
4
4
|
import { PdfObjectResolver } from "./interpret.cjs";
|
|
5
5
|
import { LayoutAnnotation } from "./layout.cjs";
|
|
6
6
|
//#region src/annotations.d.ts
|
package/dist/annotations.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PdfDiagnosticSink } from "./diagnostics.js";
|
|
2
2
|
import { r as Matrix } from "./matrix-B7_SBKQ5.js";
|
|
3
|
-
import { PdfDict } from "./objects.js";
|
|
3
|
+
import { n as PdfDict } from "./objects-B7HdMeWS.js";
|
|
4
4
|
import { PdfObjectResolver } from "./interpret.js";
|
|
5
5
|
import { LayoutAnnotation } from "./layout.js";
|
|
6
6
|
//#region src/annotations.d.ts
|
package/dist/attachments.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PdfDiagnosticSink } from "./diagnostics.cjs";
|
|
2
|
-
import { PdfDict } from "./objects.cjs";
|
|
2
|
+
import { n as PdfDict } from "./objects-B7HdMeWS.cjs";
|
|
3
3
|
import { PdfObjectResolver } from "./interpret.cjs";
|
|
4
4
|
import { LayoutAttachment } from "./layout.cjs";
|
|
5
5
|
//#region src/attachments.d.ts
|
package/dist/attachments.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PdfDiagnosticSink } from "./diagnostics.js";
|
|
2
|
-
import { PdfDict } from "./objects.js";
|
|
2
|
+
import { n as PdfDict } from "./objects-B7HdMeWS.js";
|
|
3
3
|
import { PdfObjectResolver } from "./interpret.js";
|
|
4
4
|
import { LayoutAttachment } from "./layout.js";
|
|
5
5
|
//#region src/attachments.d.ts
|
package/dist/content-read.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PdfDiagnosticSink } from "./diagnostics.cjs";
|
|
2
|
-
import { PdfDict, PdfObject } from "./objects.cjs";
|
|
2
|
+
import { n as PdfDict, r as PdfObject } from "./objects-B7HdMeWS.cjs";
|
|
3
3
|
//#region src/content-read.d.ts
|
|
4
4
|
interface ContentOperation {
|
|
5
5
|
readonly operands: readonly PdfObject[];
|
package/dist/content-read.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PdfDiagnosticSink } from "./diagnostics.js";
|
|
2
|
-
import { PdfDict, PdfObject } from "./objects.js";
|
|
2
|
+
import { n as PdfDict, r as PdfObject } from "./objects-B7HdMeWS.js";
|
|
3
3
|
//#region src/content-read.d.ts
|
|
4
4
|
interface ContentOperation {
|
|
5
5
|
readonly operands: readonly PdfObject[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/crypto/random.ts
|
|
3
|
+
function randomBytes(length) {
|
|
4
|
+
const bytes = new Uint8Array(length);
|
|
5
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
6
|
+
return bytes;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
exports.randomBytes = randomBytes;
|
package/dist/document.d.cts
CHANGED
package/dist/document.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PdfDict, PdfObject } from "./objects.cjs";
|
|
1
|
+
import { n as PdfDict, r as PdfObject } from "./objects-B7HdMeWS.cjs";
|
|
2
2
|
import { t as EmbeddedFace } from "./embedded-font-BU6Jgcof.cjs";
|
|
3
3
|
import { SfntSubsetResult } from "./sfnt-subset.cjs";
|
|
4
4
|
//#region src/embedded-font-write.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PdfDict, PdfObject } from "./objects.js";
|
|
1
|
+
import { n as PdfDict, r as PdfObject } from "./objects-B7HdMeWS.js";
|
|
2
2
|
import { t as EmbeddedFace } from "./embedded-font-fREdbxnr.js";
|
|
3
3
|
import { SfntSubsetResult } from "./sfnt-subset.js";
|
|
4
4
|
//#region src/embedded-font-write.d.ts
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_objects = require("./objects.cjs");
|
|
3
|
+
const require_bytes_writer = require("./bytes/writer.cjs");
|
|
4
|
+
const require_crypto_aes = require("./crypto/aes.cjs");
|
|
5
|
+
const require_crypto_md5 = require("./crypto/md5.cjs");
|
|
6
|
+
const require_crypto_rc4 = require("./crypto/rc4.cjs");
|
|
7
|
+
const require_encrypt = require("./encrypt.cjs");
|
|
8
|
+
const require_crypto_random = require("./crypto/random.cjs");
|
|
9
|
+
//#region src/encrypt-write.ts
|
|
10
|
+
var PdfEncryptionError = class extends Error {
|
|
11
|
+
constructor(message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = "PdfEncryptionError";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const RC4_128_KEY_BYTES = 16;
|
|
17
|
+
const R6_PASSWORD_MAX_BYTES = 127;
|
|
18
|
+
const RESERVED_BIT_7_AND_8 = 192;
|
|
19
|
+
const DEPRECATED_ALWAYS_ONE_BIT_10 = 512;
|
|
20
|
+
const SCHEME_SPECS = {
|
|
21
|
+
"rc4-40": {
|
|
22
|
+
v: 1,
|
|
23
|
+
r: 2,
|
|
24
|
+
keyBytes: 5,
|
|
25
|
+
method: "rc4"
|
|
26
|
+
},
|
|
27
|
+
"rc4-128": {
|
|
28
|
+
v: 2,
|
|
29
|
+
r: 3,
|
|
30
|
+
keyBytes: RC4_128_KEY_BYTES,
|
|
31
|
+
method: "rc4"
|
|
32
|
+
},
|
|
33
|
+
"aes-128": {
|
|
34
|
+
v: 4,
|
|
35
|
+
r: 4,
|
|
36
|
+
keyBytes: 16,
|
|
37
|
+
method: "aes"
|
|
38
|
+
},
|
|
39
|
+
"aes-256": {
|
|
40
|
+
v: 5,
|
|
41
|
+
r: 6,
|
|
42
|
+
keyBytes: 32,
|
|
43
|
+
method: "aes"
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
function legacyPasswordBytes(password) {
|
|
47
|
+
const bytes = new Uint8Array(password.length);
|
|
48
|
+
for (let i = 0; i < password.length; i++) {
|
|
49
|
+
const code = password.charCodeAt(i);
|
|
50
|
+
if (code > 127) throw new PdfEncryptionError(`password contains character code ${String(code)}, outside the printable-ASCII range this writer supports for the rc4-40/rc4-128/aes-128 schemes; use a plain-ASCII password, or the aes-256 scheme, whose revision-6 passwords are Unicode`);
|
|
51
|
+
bytes[i] = code;
|
|
52
|
+
}
|
|
53
|
+
return bytes;
|
|
54
|
+
}
|
|
55
|
+
function r6PasswordBytes(password) {
|
|
56
|
+
return new TextEncoder().encode(password.normalize("NFKC")).subarray(0, R6_PASSWORD_MAX_BYTES);
|
|
57
|
+
}
|
|
58
|
+
function permissionsToP(permissions) {
|
|
59
|
+
let p = 0;
|
|
60
|
+
if (permissions?.print ?? true) p |= 4;
|
|
61
|
+
if (permissions?.modifyContents ?? true) p |= 8;
|
|
62
|
+
if (permissions?.copy ?? true) p |= 16;
|
|
63
|
+
if (permissions?.annotate ?? true) p |= 32;
|
|
64
|
+
p |= RESERVED_BIT_7_AND_8;
|
|
65
|
+
if (permissions?.fillForms ?? true) p |= 256;
|
|
66
|
+
p |= DEPRECATED_ALWAYS_ONE_BIT_10;
|
|
67
|
+
if (permissions?.assemble ?? true) p |= 1024;
|
|
68
|
+
if (permissions?.printHighRes ?? true) p |= 2048;
|
|
69
|
+
for (let bit = 13; bit <= 32; bit++) p |= 1 << bit - 1;
|
|
70
|
+
return p;
|
|
71
|
+
}
|
|
72
|
+
function computeLegacyOwnerValue(ownerPassword, userPassword, revision, keyBytes) {
|
|
73
|
+
let digest = require_crypto_md5.md5(require_encrypt.padOrTruncatePassword(ownerPassword));
|
|
74
|
+
if (revision >= 3) for (let i = 0; i < 50; i++) digest = require_crypto_md5.md5(digest);
|
|
75
|
+
const ownerKey = digest.subarray(0, keyBytes);
|
|
76
|
+
let value = require_crypto_rc4.rc4(ownerKey, require_encrypt.padOrTruncatePassword(userPassword));
|
|
77
|
+
if (revision >= 3) for (let i = 1; i <= 19; i++) {
|
|
78
|
+
const roundKey = Uint8Array.from(ownerKey, (byte) => byte ^ i);
|
|
79
|
+
value = require_crypto_rc4.rc4(roundKey, value);
|
|
80
|
+
}
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
function computeLegacyUserValue(fileKey, fileId, revision) {
|
|
84
|
+
const core = require_encrypt.legacyUserValueCore(fileKey, fileId, revision);
|
|
85
|
+
if (revision === 2) return core;
|
|
86
|
+
return require_bytes_writer.concatBytes([core, require_crypto_random.randomBytes(require_encrypt.PASSWORD_PADDING.length - core.length)]);
|
|
87
|
+
}
|
|
88
|
+
function encryptAes(key, data) {
|
|
89
|
+
const iv = require_crypto_random.randomBytes(16);
|
|
90
|
+
const padLength = 16 - data.length % 16;
|
|
91
|
+
const padded = new Uint8Array(data.length + padLength);
|
|
92
|
+
padded.set(data);
|
|
93
|
+
padded.fill(padLength, data.length);
|
|
94
|
+
return require_bytes_writer.concatBytes([iv, require_crypto_aes.aesCbcEncrypt(key, iv, padded)]);
|
|
95
|
+
}
|
|
96
|
+
function applyEncryptMethod(method, fileKey, perObjectKeys, bytes, num, gen) {
|
|
97
|
+
if (method === "identity") return bytes;
|
|
98
|
+
const key = perObjectKeys ? require_encrypt.objectKey(fileKey, num, gen, method) : fileKey;
|
|
99
|
+
return method === "rc4" ? require_crypto_rc4.rc4(key, bytes) : encryptAes(key, bytes);
|
|
100
|
+
}
|
|
101
|
+
function buildEncryptor(encryptDict, fileKey, method, perObjectKeys, encryptMetadata) {
|
|
102
|
+
return {
|
|
103
|
+
encryptDict,
|
|
104
|
+
encryptString(bytes, num, gen) {
|
|
105
|
+
return applyEncryptMethod(method, fileKey, perObjectKeys, bytes, num, gen);
|
|
106
|
+
},
|
|
107
|
+
encryptStream(bytes, dict, num, gen) {
|
|
108
|
+
const type = dict.entries.get("Type");
|
|
109
|
+
if (!encryptMetadata && type?.kind === "name" && type.name === "Metadata") return bytes;
|
|
110
|
+
return applyEncryptMethod(method, fileKey, perObjectKeys, bytes, num, gen);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function buildLegacyEncryptor(spec, options, fileId) {
|
|
115
|
+
const userPassword = legacyPasswordBytes(options.userPassword ?? "");
|
|
116
|
+
const ownerPassword = legacyPasswordBytes(options.ownerPassword ?? options.userPassword ?? "");
|
|
117
|
+
const encryptMetadata = options.encryptMetadata ?? true;
|
|
118
|
+
const p = permissionsToP(options.permissions);
|
|
119
|
+
const owner = computeLegacyOwnerValue(ownerPassword, userPassword, spec.r, spec.keyBytes);
|
|
120
|
+
const fileKey = require_encrypt.computeLegacyFileKeyFromPaddedPassword(require_encrypt.padOrTruncatePassword(userPassword), owner, p, fileId, spec.r, spec.keyBytes, encryptMetadata);
|
|
121
|
+
const user = computeLegacyUserValue(fileKey, fileId, spec.r);
|
|
122
|
+
const entries = /* @__PURE__ */ new Map([
|
|
123
|
+
["Filter", require_objects.pdfName("Standard")],
|
|
124
|
+
["V", require_objects.pdfNum(spec.v)],
|
|
125
|
+
["R", require_objects.pdfNum(spec.r)],
|
|
126
|
+
["O", require_objects.pdfHexString(owner)],
|
|
127
|
+
["U", require_objects.pdfHexString(user)],
|
|
128
|
+
["P", require_objects.pdfNum(p)],
|
|
129
|
+
["Length", require_objects.pdfNum(spec.keyBytes * 8)]
|
|
130
|
+
]);
|
|
131
|
+
if (spec.v === 4) {
|
|
132
|
+
entries.set("CF", require_objects.pdfDict({ StdCF: require_objects.pdfDict({
|
|
133
|
+
AuthEvent: require_objects.pdfName("DocOpen"),
|
|
134
|
+
CFM: require_objects.pdfName("AESV2"),
|
|
135
|
+
Length: require_objects.pdfNum(spec.keyBytes)
|
|
136
|
+
}) }));
|
|
137
|
+
entries.set("StmF", require_objects.pdfName("StdCF"));
|
|
138
|
+
entries.set("StrF", require_objects.pdfName("StdCF"));
|
|
139
|
+
entries.set("EncryptMetadata", require_objects.pdfBool(encryptMetadata));
|
|
140
|
+
}
|
|
141
|
+
return buildEncryptor(require_objects.pdfDict(entries), fileKey, spec.method, true, encryptMetadata);
|
|
142
|
+
}
|
|
143
|
+
function buildAes256Encryptor(spec, options) {
|
|
144
|
+
const userPassword = r6PasswordBytes(options.userPassword ?? "");
|
|
145
|
+
const ownerPassword = r6PasswordBytes(options.ownerPassword ?? options.userPassword ?? "");
|
|
146
|
+
const encryptMetadata = options.encryptMetadata ?? true;
|
|
147
|
+
const p = permissionsToP(options.permissions);
|
|
148
|
+
const fileKey = require_crypto_random.randomBytes(32);
|
|
149
|
+
const userValidationSalt = require_crypto_random.randomBytes(8);
|
|
150
|
+
const userKeySalt = require_crypto_random.randomBytes(8);
|
|
151
|
+
const empty = /* @__PURE__ */ new Uint8Array(0);
|
|
152
|
+
const userHash = require_encrypt.hardenedHash(userPassword, userValidationSalt, empty, spec.r);
|
|
153
|
+
const u = require_bytes_writer.concatBytes([
|
|
154
|
+
userHash,
|
|
155
|
+
userValidationSalt,
|
|
156
|
+
userKeySalt
|
|
157
|
+
]);
|
|
158
|
+
const userIntermediateKey = require_encrypt.hardenedHash(userPassword, userKeySalt, empty, spec.r);
|
|
159
|
+
const ue = require_crypto_aes.aesCbcEncrypt(userIntermediateKey, require_encrypt.ZERO_IV, fileKey);
|
|
160
|
+
const ownerValidationSalt = require_crypto_random.randomBytes(8);
|
|
161
|
+
const ownerKeySalt = require_crypto_random.randomBytes(8);
|
|
162
|
+
const ownerHash = require_encrypt.hardenedHash(ownerPassword, ownerValidationSalt, u, spec.r);
|
|
163
|
+
const o = require_bytes_writer.concatBytes([
|
|
164
|
+
ownerHash,
|
|
165
|
+
ownerValidationSalt,
|
|
166
|
+
ownerKeySalt
|
|
167
|
+
]);
|
|
168
|
+
const ownerIntermediateKey = require_encrypt.hardenedHash(ownerPassword, ownerKeySalt, u, spec.r);
|
|
169
|
+
const oe = require_crypto_aes.aesCbcEncrypt(ownerIntermediateKey, require_encrypt.ZERO_IV, fileKey);
|
|
170
|
+
const permsBlock = /* @__PURE__ */ new Uint8Array(16);
|
|
171
|
+
permsBlock.set(require_encrypt.permissionsBytes(p), 0);
|
|
172
|
+
permsBlock.set([
|
|
173
|
+
255,
|
|
174
|
+
255,
|
|
175
|
+
255,
|
|
176
|
+
255
|
|
177
|
+
], 4);
|
|
178
|
+
permsBlock[8] = encryptMetadata ? 84 : 70;
|
|
179
|
+
permsBlock.set([
|
|
180
|
+
97,
|
|
181
|
+
100,
|
|
182
|
+
98
|
|
183
|
+
], 9);
|
|
184
|
+
permsBlock.set(require_crypto_random.randomBytes(4), 12);
|
|
185
|
+
const perms = require_crypto_aes.aesCbcEncrypt(fileKey, require_encrypt.ZERO_IV, permsBlock);
|
|
186
|
+
const entries = /* @__PURE__ */ new Map([
|
|
187
|
+
["Filter", require_objects.pdfName("Standard")],
|
|
188
|
+
["V", require_objects.pdfNum(spec.v)],
|
|
189
|
+
["R", require_objects.pdfNum(spec.r)],
|
|
190
|
+
["O", require_objects.pdfHexString(o)],
|
|
191
|
+
["U", require_objects.pdfHexString(u)],
|
|
192
|
+
["OE", require_objects.pdfHexString(oe)],
|
|
193
|
+
["UE", require_objects.pdfHexString(ue)],
|
|
194
|
+
["P", require_objects.pdfNum(p)],
|
|
195
|
+
["Perms", require_objects.pdfHexString(perms)],
|
|
196
|
+
["Length", require_objects.pdfNum(spec.keyBytes * 8)],
|
|
197
|
+
["CF", require_objects.pdfDict({ StdCF: require_objects.pdfDict({
|
|
198
|
+
AuthEvent: require_objects.pdfName("DocOpen"),
|
|
199
|
+
CFM: require_objects.pdfName("AESV3"),
|
|
200
|
+
Length: require_objects.pdfNum(spec.keyBytes)
|
|
201
|
+
}) })],
|
|
202
|
+
["StmF", require_objects.pdfName("StdCF")],
|
|
203
|
+
["StrF", require_objects.pdfName("StdCF")],
|
|
204
|
+
["EncryptMetadata", require_objects.pdfBool(encryptMetadata)]
|
|
205
|
+
]);
|
|
206
|
+
return buildEncryptor(require_objects.pdfDict(entries), fileKey, spec.method, false, encryptMetadata);
|
|
207
|
+
}
|
|
208
|
+
function createStandardEncryptor(options, fileId) {
|
|
209
|
+
const scheme = options.scheme ?? "aes-256";
|
|
210
|
+
const spec = SCHEME_SPECS[scheme];
|
|
211
|
+
return spec.v === 5 ? buildAes256Encryptor(spec, options) : buildLegacyEncryptor(spec, options, fileId);
|
|
212
|
+
}
|
|
213
|
+
function encryptIndirectObject(value, num, gen, encryptor) {
|
|
214
|
+
if (value.kind === "string") return {
|
|
215
|
+
kind: "string",
|
|
216
|
+
bytes: encryptor.encryptString(value.bytes, num, gen),
|
|
217
|
+
hex: value.hex
|
|
218
|
+
};
|
|
219
|
+
if (value.kind === "array") return require_objects.pdfArray(value.items.map((item) => encryptIndirectObject(item, num, gen, encryptor)));
|
|
220
|
+
if (value.kind === "dict") return encryptDictEntries(value, num, gen, encryptor);
|
|
221
|
+
if (value.kind === "stream") return {
|
|
222
|
+
kind: "stream",
|
|
223
|
+
dict: encryptDictEntries(value.dict, num, gen, encryptor),
|
|
224
|
+
raw: encryptor.encryptStream(value.raw, value.dict, num, gen)
|
|
225
|
+
};
|
|
226
|
+
return value;
|
|
227
|
+
}
|
|
228
|
+
function encryptDictEntries(dict, num, gen, encryptor) {
|
|
229
|
+
return require_objects.pdfDict(new Map(Array.from(dict.entries, ([key, entry]) => [key, encryptIndirectObject(entry, num, gen, encryptor)])));
|
|
230
|
+
}
|
|
231
|
+
//#endregion
|
|
232
|
+
exports.PdfEncryptionError = PdfEncryptionError;
|
|
233
|
+
exports.createStandardEncryptor = createStandardEncryptor;
|
|
234
|
+
exports.encryptIndirectObject = encryptIndirectObject;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { n as PdfDict, r as PdfObject } from "./objects-B7HdMeWS.cjs";
|
|
2
|
+
//#region src/encrypt-write.d.ts
|
|
3
|
+
declare class PdfEncryptionError extends Error {
|
|
4
|
+
constructor(message: string);
|
|
5
|
+
}
|
|
6
|
+
type PdfEncryptionScheme = "rc4-40" | "rc4-128" | "aes-128" | "aes-256";
|
|
7
|
+
interface PdfEncryptionPermissions {
|
|
8
|
+
readonly print?: boolean;
|
|
9
|
+
readonly modifyContents?: boolean;
|
|
10
|
+
readonly copy?: boolean;
|
|
11
|
+
readonly annotate?: boolean;
|
|
12
|
+
readonly fillForms?: boolean;
|
|
13
|
+
readonly assemble?: boolean;
|
|
14
|
+
readonly printHighRes?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface PdfEncryptionOptions {
|
|
17
|
+
readonly userPassword?: string;
|
|
18
|
+
readonly ownerPassword?: string;
|
|
19
|
+
readonly scheme?: PdfEncryptionScheme;
|
|
20
|
+
readonly permissions?: PdfEncryptionPermissions;
|
|
21
|
+
readonly encryptMetadata?: boolean;
|
|
22
|
+
}
|
|
23
|
+
interface PdfEncryptor {
|
|
24
|
+
readonly encryptDict: PdfDict;
|
|
25
|
+
encryptString(bytes: Uint8Array<ArrayBuffer>, num: number, gen: number): Uint8Array<ArrayBuffer>;
|
|
26
|
+
encryptStream(bytes: Uint8Array<ArrayBuffer>, dict: PdfDict, num: number, gen: number): Uint8Array<ArrayBuffer>;
|
|
27
|
+
}
|
|
28
|
+
declare function createStandardEncryptor(options: PdfEncryptionOptions, fileId: Uint8Array<ArrayBuffer>): PdfEncryptor;
|
|
29
|
+
declare function encryptIndirectObject(value: PdfObject, num: number, gen: number, encryptor: PdfEncryptor): PdfObject;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { PdfEncryptionError, PdfEncryptionOptions, PdfEncryptionPermissions, PdfEncryptionScheme, PdfEncryptor, createStandardEncryptor, encryptIndirectObject };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { n as PdfDict, r as PdfObject } from "./objects-B7HdMeWS.js";
|
|
2
|
+
//#region src/encrypt-write.d.ts
|
|
3
|
+
declare class PdfEncryptionError extends Error {
|
|
4
|
+
constructor(message: string);
|
|
5
|
+
}
|
|
6
|
+
type PdfEncryptionScheme = "rc4-40" | "rc4-128" | "aes-128" | "aes-256";
|
|
7
|
+
interface PdfEncryptionPermissions {
|
|
8
|
+
readonly print?: boolean;
|
|
9
|
+
readonly modifyContents?: boolean;
|
|
10
|
+
readonly copy?: boolean;
|
|
11
|
+
readonly annotate?: boolean;
|
|
12
|
+
readonly fillForms?: boolean;
|
|
13
|
+
readonly assemble?: boolean;
|
|
14
|
+
readonly printHighRes?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface PdfEncryptionOptions {
|
|
17
|
+
readonly userPassword?: string;
|
|
18
|
+
readonly ownerPassword?: string;
|
|
19
|
+
readonly scheme?: PdfEncryptionScheme;
|
|
20
|
+
readonly permissions?: PdfEncryptionPermissions;
|
|
21
|
+
readonly encryptMetadata?: boolean;
|
|
22
|
+
}
|
|
23
|
+
interface PdfEncryptor {
|
|
24
|
+
readonly encryptDict: PdfDict;
|
|
25
|
+
encryptString(bytes: Uint8Array<ArrayBuffer>, num: number, gen: number): Uint8Array<ArrayBuffer>;
|
|
26
|
+
encryptStream(bytes: Uint8Array<ArrayBuffer>, dict: PdfDict, num: number, gen: number): Uint8Array<ArrayBuffer>;
|
|
27
|
+
}
|
|
28
|
+
declare function createStandardEncryptor(options: PdfEncryptionOptions, fileId: Uint8Array<ArrayBuffer>): PdfEncryptor;
|
|
29
|
+
declare function encryptIndirectObject(value: PdfObject, num: number, gen: number, encryptor: PdfEncryptor): PdfObject;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { PdfEncryptionError, PdfEncryptionOptions, PdfEncryptionPermissions, PdfEncryptionScheme, PdfEncryptor, createStandardEncryptor, encryptIndirectObject };
|