pdf-parser.js 3.0.8 → 4.5.2
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 +105 -54
- package/dist/{afm-widths-Dxucrg7D.js → afm-widths-BTu0IDp2.cjs} +1517 -4
- package/dist/{afm-widths-DyDq56Ph.d.cts → afm-widths-CneRyu5l.d.cts} +1 -1
- package/dist/{afm-widths-DyDq56Ph.d.ts → afm-widths-CneRyu5l.d.ts} +1 -1
- package/dist/{afm-widths-BoeTOK2r.cjs → afm-widths-De_QMWgC.js} +1416 -51
- package/dist/afm-widths.cjs +1 -1
- package/dist/afm-widths.d.cts +1 -1
- package/dist/afm-widths.d.ts +1 -1
- package/dist/afm-widths.js +1 -1
- package/dist/annotations.cjs +104 -0
- package/dist/annotations.d.cts +9 -0
- package/dist/annotations.d.ts +9 -0
- package/dist/annotations.js +103 -0
- package/dist/attachments.cjs +65 -0
- package/dist/attachments.d.cts +8 -0
- package/dist/attachments.d.ts +8 -0
- package/dist/attachments.js +64 -0
- package/dist/builtin-encoding.cjs +221 -0
- package/dist/builtin-encoding.d.cts +8 -0
- package/dist/builtin-encoding.d.ts +8 -0
- package/dist/builtin-encoding.js +220 -0
- package/dist/bytes/flate.cjs +1 -1
- package/dist/bytes/flate.js +1 -1
- package/dist/cff.cjs +14 -0
- package/dist/cff.d.cts +4 -1
- package/dist/cff.d.ts +4 -1
- package/dist/cff.js +12 -1
- package/dist/cmap-table.cjs +76 -13
- package/dist/cmap-table.d.cts +9 -1
- package/dist/cmap-table.d.ts +9 -1
- package/dist/cmap-table.js +77 -15
- package/dist/codec.cjs +1 -1
- package/dist/codec.d.cts +134 -0
- package/dist/codec.d.ts +134 -0
- package/dist/codec.js +1 -1
- package/dist/content-read.cjs +1 -1
- package/dist/content-read.d.cts +3 -3
- package/dist/content-read.d.ts +3 -3
- package/dist/content-read.js +1 -1
- package/dist/content-write.cjs +32 -10
- package/dist/content-write.d.cts +12 -5
- package/dist/content-write.d.ts +12 -5
- package/dist/content-write.js +32 -10
- 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/diagnostics.d.cts +1 -1
- package/dist/diagnostics.d.ts +1 -1
- package/dist/document.cjs +12 -3
- package/dist/document.d.cts +3 -1
- package/dist/document.d.ts +3 -1
- package/dist/document.js +12 -3
- package/dist/{embedded-font-fREdbxnr.d.ts → embedded-font-B4p9a3O3.d.ts} +3 -1
- package/dist/{embedded-font-BU6Jgcof.d.cts → embedded-font-oc65VGlr.d.cts} +3 -1
- package/dist/embedded-font-write.cjs +1 -1
- package/dist/embedded-font-write.d.cts +3 -3
- package/dist/embedded-font-write.d.ts +3 -3
- package/dist/embedded-font-write.js +1 -1
- package/dist/embedded-font.cjs +46 -15
- package/dist/embedded-font.d.cts +1 -1
- package/dist/embedded-font.d.ts +1 -1
- package/dist/embedded-font.js +46 -15
- package/dist/encoding.cjs +10 -1
- package/dist/encoding.d.cts +10 -1
- package/dist/encoding.d.ts +10 -1
- package/dist/encoding.js +2 -2
- 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 +51 -21
- package/dist/encrypt.d.cts +19 -3
- package/dist/encrypt.d.ts +19 -3
- package/dist/encrypt.js +36 -22
- package/dist/filters.cjs +18 -14
- package/dist/filters.d.cts +1 -1
- package/dist/filters.d.ts +1 -1
- package/dist/filters.js +18 -14
- package/dist/font-read.cjs +68 -13
- package/dist/font-read.d.cts +1 -1
- package/dist/font-read.d.ts +1 -1
- package/dist/font-read.js +69 -14
- package/dist/font-registry.cjs +1 -1
- package/dist/font-registry.d.cts +4 -4
- package/dist/font-registry.d.ts +4 -4
- package/dist/font-registry.js +1 -1
- package/dist/font-substitutes.d.cts +1 -1
- package/dist/font-substitutes.d.ts +1 -1
- package/dist/font-tables.cjs +31 -0
- package/dist/font-tables.d.cts +3 -1
- package/dist/font-tables.d.ts +3 -1
- package/dist/font-tables.js +31 -2
- package/dist/fonts.d.cts +2 -2
- package/dist/fonts.d.ts +2 -2
- package/dist/form.cjs +138 -0
- package/dist/form.d.cts +9 -0
- package/dist/form.d.ts +9 -0
- package/dist/form.js +137 -0
- package/dist/gsub-table-BRTQ8EUW.d.ts +10 -0
- package/dist/gsub-table-URczLd85.d.cts +10 -0
- package/dist/gsub-table.cjs +225 -0
- package/dist/gsub-table.d.cts +2 -0
- package/dist/gsub-table.d.ts +2 -0
- package/dist/gsub-table.js +224 -0
- package/dist/image/ccitt-encode.cjs +119 -0
- package/dist/image/ccitt-encode.d.cts +9 -0
- package/dist/image/ccitt-encode.d.ts +9 -0
- package/dist/image/ccitt-encode.js +118 -0
- package/dist/image/ccitt.cjs +3 -0
- package/dist/image/ccitt.d.cts +4 -1
- package/dist/image/ccitt.d.ts +4 -1
- package/dist/image/ccitt.js +1 -1
- package/dist/image/jbig2-bitmap.d.cts +1 -1
- package/dist/image/jbig2-bitmap.d.ts +1 -1
- package/dist/image/jbig2.cjs +3 -1
- package/dist/image/jbig2.js +3 -1
- package/dist/image/jp2-boxes.d.cts +1 -1
- package/dist/image/jp2-boxes.d.ts +1 -1
- package/dist/image/jpeg2000-codestream.d.cts +3 -3
- package/dist/image/jpeg2000-codestream.d.ts +3 -3
- package/dist/image/jpeg2000-t1.d.cts +1 -1
- package/dist/image/jpeg2000-t1.d.ts +1 -1
- package/dist/image/jpeg2000.cjs +1 -0
- package/dist/image/jpeg2000.d.cts +3 -0
- package/dist/image/jpeg2000.d.ts +3 -0
- package/dist/image/jpeg2000.js +1 -0
- package/dist/image/png-decode.cjs +1 -1
- package/dist/image/png-decode.js +1 -1
- package/dist/image/png-filter.d.cts +1 -1
- package/dist/image/png-filter.d.ts +1 -1
- package/dist/images-read.cjs +18 -12
- package/dist/images-read.d.cts +2 -2
- package/dist/images-read.d.ts +2 -2
- package/dist/images-read.js +15 -9
- package/dist/index.cjs +17 -4
- package/dist/index.d.cts +7 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +6 -5
- package/dist/interpret.cjs +178 -56
- package/dist/interpret.d.cts +27 -12
- package/dist/interpret.d.ts +27 -12
- package/dist/interpret.js +178 -56
- package/dist/layout.cjs +149 -2
- package/dist/layout.d.cts +394 -1
- package/dist/layout.d.ts +394 -1
- package/dist/layout.js +140 -4
- package/dist/lexer.d.cts +9 -9
- package/dist/lexer.d.ts +9 -9
- package/dist/math-content-write.cjs +1 -1
- package/dist/math-content-write.js +1 -1
- package/dist/math-font-write.cjs +1 -1
- package/dist/math-font-write.d.cts +1 -1
- package/dist/math-font-write.d.ts +1 -1
- package/dist/math-font-write.js +1 -1
- package/dist/math-font.cjs +2 -2
- package/dist/math-font.d.cts +1 -1
- package/dist/math-font.d.ts +1 -1
- package/dist/math-font.js +2 -2
- package/dist/{math-stretch-a_rHNRvc.d.ts → math-stretch-BbC2o4Br.d.ts} +1 -1
- package/dist/{math-stretch-E26z6byT.d.cts → math-stretch-C2JanDAz.d.cts} +1 -1
- package/dist/math-stretch.d.cts +1 -1
- package/dist/math-stretch.d.ts +1 -1
- package/dist/measure.cjs +1 -1
- package/dist/measure.d.cts +1 -1
- package/dist/measure.d.ts +1 -1
- package/dist/measure.js +1 -1
- package/dist/names.cjs +41 -0
- package/dist/names.d.cts +11 -0
- package/dist/names.d.ts +11 -0
- package/dist/names.js +40 -0
- package/dist/navigation.cjs +210 -0
- package/dist/navigation.d.cts +18 -0
- package/dist/navigation.d.ts +18 -0
- package/dist/navigation.js +207 -0
- package/dist/notes-annotation-author.cjs +5 -0
- package/dist/notes-annotation-author.d.cts +4 -0
- package/dist/notes-annotation-author.d.ts +4 -0
- package/dist/notes-annotation-author.js +4 -0
- 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.cjs +63 -0
- package/dist/optional-content.d.cts +12 -0
- package/dist/optional-content.d.ts +12 -0
- package/dist/optional-content.js +62 -0
- package/dist/parse.cjs +1 -1
- package/dist/parse.d.cts +2 -2
- package/dist/parse.d.ts +2 -2
- package/dist/parse.js +1 -1
- package/dist/pdf-text.cjs +21 -0
- package/dist/pdf-text.d.cts +5 -0
- package/dist/pdf-text.d.ts +5 -0
- package/dist/pdf-text.js +19 -0
- package/dist/predictors.d.cts +1 -1
- package/dist/predictors.d.ts +1 -1
- package/dist/read.cjs +287 -72
- package/dist/read.d.cts +2 -4
- package/dist/read.d.ts +2 -4
- package/dist/read.js +284 -67
- package/dist/serialize.cjs +5 -1
- package/dist/serialize.d.cts +3 -2
- package/dist/serialize.d.ts +3 -2
- package/dist/serialize.js +5 -2
- package/dist/sfnt-subset.cjs +10 -3
- package/dist/sfnt-subset.d.cts +1 -1
- package/dist/sfnt-subset.d.ts +1 -1
- package/dist/sfnt-subset.js +10 -3
- package/dist/structure.cjs +184 -0
- package/dist/structure.d.cts +12 -0
- package/dist/structure.d.ts +12 -0
- package/dist/structure.js +183 -0
- package/dist/tounicode.cjs +8 -3
- package/dist/tounicode.d.cts +2 -2
- package/dist/tounicode.d.ts +2 -2
- package/dist/tounicode.js +8 -3
- package/dist/util/base64.cjs +4 -4
- package/dist/util/base64.js +4 -4
- package/dist/winansi.cjs +1 -1
- package/dist/winansi.d.cts +1 -1
- package/dist/winansi.d.ts +1 -1
- package/dist/winansi.js +1 -1
- package/dist/write.cjs +464 -21
- package/dist/write.d.cts +4 -3
- package/dist/write.d.ts +4 -3
- package/dist/write.js +464 -20
- package/dist/xmp.cjs +46 -0
- package/dist/xmp.d.cts +14 -0
- package/dist/xmp.d.ts +14 -0
- package/dist/xmp.js +45 -0
- package/dist/xref.cjs +2 -2
- package/dist/xref.d.cts +3 -3
- package/dist/xref.d.ts +3 -3
- package/dist/xref.js +2 -2
- package/package.json +46 -31
- package/dist/image/png-encode.cjs +0 -64
- package/dist/image/png-encode.d.cts +0 -8
- package/dist/image/png-encode.d.ts +0 -8
- package/dist/image/png-encode.js +0 -63
package/dist/encrypt.cjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_objects = require("./objects.cjs");
|
|
2
3
|
const require_bytes_writer = require("./bytes/writer.cjs");
|
|
3
4
|
const require_diagnostics = require("./diagnostics.cjs");
|
|
4
5
|
const require_crypto_aes = require("./crypto/aes.cjs");
|
|
5
6
|
const require_crypto_md5 = require("./crypto/md5.cjs");
|
|
6
7
|
const require_crypto_rc4 = require("./crypto/rc4.cjs");
|
|
7
8
|
const require_crypto_sha2 = require("./crypto/sha2.cjs");
|
|
8
|
-
const require_objects = require("./objects.cjs");
|
|
9
9
|
//#region src/encrypt.ts
|
|
10
10
|
const PASSWORD_PADDING = new Uint8Array([
|
|
11
11
|
40,
|
|
@@ -50,11 +50,12 @@ const AES_OBJECT_KEY_SALT = new Uint8Array([
|
|
|
50
50
|
const MD5_DIGEST_BYTES = 16;
|
|
51
51
|
const OBJECT_KEY_EXTRA_BYTES = 5;
|
|
52
52
|
const LEGACY_KEY_ITERATIONS = 50;
|
|
53
|
-
const
|
|
53
|
+
const RC4_OBFUSCATION_ROUNDS = 19;
|
|
54
54
|
const R6_MINIMUM_ROUNDS = 64;
|
|
55
55
|
const R6_ROUND_REPEATS = 64;
|
|
56
56
|
const R6_TERMINATION_MARGIN = 32;
|
|
57
57
|
const AESV3_KEY_BYTES = 32;
|
|
58
|
+
const AESV3_SALT_BYTES = 8;
|
|
58
59
|
const RC4_40_KEY_BYTES = 5;
|
|
59
60
|
const AESV2_KEY_BYTES = 16;
|
|
60
61
|
const DEFAULT_KEY_BITS = 40;
|
|
@@ -80,11 +81,16 @@ function permissionsBytes(p) {
|
|
|
80
81
|
unsigned >>> 24 & 255
|
|
81
82
|
]);
|
|
82
83
|
}
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
const
|
|
84
|
+
function padOrTruncatePassword(password) {
|
|
85
|
+
if (password.length >= PASSWORD_PADDING.length) return password.subarray(0, PASSWORD_PADDING.length);
|
|
86
|
+
const padded = new Uint8Array(PASSWORD_PADDING.length);
|
|
87
|
+
padded.set(password);
|
|
88
|
+
padded.set(PASSWORD_PADDING.subarray(0, PASSWORD_PADDING.length - password.length), password.length);
|
|
89
|
+
return padded;
|
|
90
|
+
}
|
|
91
|
+
function computeLegacyFileKeyFromPaddedPassword(paddedPassword, owner, permissions, fileId, revision, keyBytes, encryptMetadata) {
|
|
86
92
|
const parts = [
|
|
87
|
-
|
|
93
|
+
paddedPassword,
|
|
88
94
|
owner.subarray(0, PASSWORD_PADDING.length),
|
|
89
95
|
permissionsBytes(permissions),
|
|
90
96
|
fileId
|
|
@@ -96,18 +102,26 @@ function computeLegacyFileKey(encryptDict, fileId, revision, keyBytes, encryptMe
|
|
|
96
102
|
255
|
|
97
103
|
]));
|
|
98
104
|
let digest = require_crypto_md5.md5(require_bytes_writer.concatBytes(parts));
|
|
99
|
-
if (revision >= 3) for (let i = 0; i <
|
|
105
|
+
if (revision >= 3) for (let i = 0; i < 50; i++) digest = require_crypto_md5.md5(digest.subarray(0, keyBytes));
|
|
100
106
|
return digest.subarray(0, keyBytes);
|
|
101
107
|
}
|
|
102
|
-
function
|
|
103
|
-
const
|
|
104
|
-
|
|
108
|
+
function computeLegacyFileKey(encryptDict, fileId, revision, keyBytes, encryptMetadata) {
|
|
109
|
+
const owner = requireStringBytes(encryptDict, "O");
|
|
110
|
+
const permissions = require_objects.asNumber(require_objects.dictGet(encryptDict, "P")) ?? 0;
|
|
111
|
+
return computeLegacyFileKeyFromPaddedPassword(PASSWORD_PADDING, owner, permissions, fileId, revision, keyBytes, encryptMetadata);
|
|
112
|
+
}
|
|
113
|
+
function legacyUserValueCore(fileKey, fileId, revision) {
|
|
114
|
+
if (revision === 2) return require_crypto_rc4.rc4(fileKey, PASSWORD_PADDING);
|
|
105
115
|
let value = require_crypto_rc4.rc4(fileKey, require_crypto_md5.md5(require_bytes_writer.concatBytes([PASSWORD_PADDING, fileId])));
|
|
106
|
-
for (let i = 1; i <=
|
|
116
|
+
for (let i = 1; i <= 19; i++) {
|
|
107
117
|
const roundKey = Uint8Array.from(fileKey, (byte) => byte ^ i);
|
|
108
118
|
value = require_crypto_rc4.rc4(roundKey, value);
|
|
109
119
|
}
|
|
110
|
-
return
|
|
120
|
+
return value;
|
|
121
|
+
}
|
|
122
|
+
function legacyUserPasswordVerifies(encryptDict, fileId, revision, fileKey) {
|
|
123
|
+
const storedUser = requireStringBytes(encryptDict, "U");
|
|
124
|
+
return bytesEqual(legacyUserValueCore(fileKey, fileId, revision), storedUser, revision === 2 ? PASSWORD_PADDING.length : 16);
|
|
111
125
|
}
|
|
112
126
|
function hardenedHash(password, salt, userData, revision) {
|
|
113
127
|
let k = require_crypto_sha2.sha256(require_bytes_writer.concatBytes([
|
|
@@ -133,20 +147,20 @@ function hardenedHash(password, salt, userData, revision) {
|
|
|
133
147
|
k = selector === 0 ? require_crypto_sha2.sha256(e) : selector === 1 ? require_crypto_sha2.sha384(e) : require_crypto_sha2.sha512(e);
|
|
134
148
|
round++;
|
|
135
149
|
}
|
|
136
|
-
return k.subarray(0,
|
|
150
|
+
return k.subarray(0, 32);
|
|
137
151
|
}
|
|
138
152
|
function computeAesV3FileKey(encryptDict, revision) {
|
|
139
153
|
const storedUser = requireStringBytes(encryptDict, "U");
|
|
140
154
|
const expectedLength = 48;
|
|
141
155
|
if (storedUser.length < expectedLength) throw new require_diagnostics.PdfEncryptedError(`the /Encrypt dictionary's /U entry is ${String(storedUser.length)} bytes; revision ${String(revision)} requires ${String(expectedLength)}`);
|
|
142
156
|
const empty = /* @__PURE__ */ new Uint8Array(0);
|
|
143
|
-
const validationSalt = storedUser.subarray(
|
|
157
|
+
const validationSalt = storedUser.subarray(32, 40);
|
|
144
158
|
const keySalt = storedUser.subarray(40, expectedLength);
|
|
145
|
-
if (!bytesEqual(hardenedHash(empty, validationSalt, empty, revision), storedUser,
|
|
159
|
+
if (!bytesEqual(hardenedHash(empty, validationSalt, empty, revision), storedUser, 32)) throw new require_diagnostics.PdfPasswordRequiredError();
|
|
146
160
|
const intermediateKey = hardenedHash(empty, keySalt, empty, revision);
|
|
147
161
|
const wrappedKey = requireStringBytes(encryptDict, "UE");
|
|
148
|
-
if (wrappedKey.length <
|
|
149
|
-
return require_crypto_aes.aesCbcDecrypt(intermediateKey, ZERO_IV, wrappedKey.subarray(0,
|
|
162
|
+
if (wrappedKey.length < 32) throw new require_diagnostics.PdfEncryptedError(`the /Encrypt dictionary's /UE entry is ${String(wrappedKey.length)} bytes; revision ${String(revision)} requires ${String(32)}`);
|
|
163
|
+
return require_crypto_aes.aesCbcDecrypt(intermediateKey, ZERO_IV, wrappedKey.subarray(0, 32));
|
|
150
164
|
}
|
|
151
165
|
function methodFromCryptFilterName(encryptDict, entryKey) {
|
|
152
166
|
const name = require_objects.asName(require_objects.dictGet(encryptDict, entryKey)) ?? "Identity";
|
|
@@ -164,7 +178,7 @@ function cryptFilterKeyBytes(encryptDict, declaredBits) {
|
|
|
164
178
|
const streamFilterName = require_objects.asName(require_objects.dictGet(encryptDict, "StmF")) ?? "Identity";
|
|
165
179
|
const filters = require_objects.asDict(require_objects.dictGet(encryptDict, "CF"));
|
|
166
180
|
const filter = filters !== void 0 ? require_objects.asDict(require_objects.dictGet(filters, streamFilterName)) : void 0;
|
|
167
|
-
if ((filter !== void 0 ? require_objects.asName(require_objects.dictGet(filter, "CFM")) : void 0) === "AESV2") return
|
|
181
|
+
if ((filter !== void 0 ? require_objects.asName(require_objects.dictGet(filter, "CFM")) : void 0) === "AESV2") return 16;
|
|
168
182
|
const declared = filter !== void 0 ? require_objects.asNumber(require_objects.dictGet(filter, "Length")) : void 0;
|
|
169
183
|
if (declared === void 0) return Math.floor(declaredBits / BITS_PER_BYTE);
|
|
170
184
|
return declared >= DEFAULT_KEY_BITS ? Math.floor(declared / BITS_PER_BYTE) : declared;
|
|
@@ -189,8 +203,8 @@ function setUpHandler(encryptDict, fileId) {
|
|
|
189
203
|
if (revision < 2 || revision > 4) throw new require_diagnostics.PdfEncryptedError(`unsupported standard security handler revision /R ${String(revision)}`);
|
|
190
204
|
const streamMethod = version === 4 ? methodFromCryptFilterName(encryptDict, "StmF") : "rc4";
|
|
191
205
|
const stringMethod = version === 4 ? methodFromCryptFilterName(encryptDict, "StrF") : "rc4";
|
|
192
|
-
const keyBytes = version === 1 ?
|
|
193
|
-
if (keyBytes <
|
|
206
|
+
const keyBytes = version === 1 ? 5 : version === 2 ? Math.floor(declaredBits / BITS_PER_BYTE) : cryptFilterKeyBytes(encryptDict, declaredBits);
|
|
207
|
+
if (keyBytes < 5 || keyBytes > MAX_RC4_KEY_BYTES) throw new require_diagnostics.PdfEncryptedError(`the /Encrypt dictionary declares a ${String(keyBytes * BITS_PER_BYTE)}-bit file key, outside the 40-128 bit range /V ${String(version)} permits`);
|
|
194
208
|
const fileKey = computeLegacyFileKey(encryptDict, fileId, revision, keyBytes, encryptMetadata);
|
|
195
209
|
if (!legacyUserPasswordVerifies(encryptDict, fileId, revision, fileKey)) throw new require_diagnostics.PdfPasswordRequiredError();
|
|
196
210
|
return {
|
|
@@ -212,7 +226,7 @@ function objectKey(fileKey, num, gen, method) {
|
|
|
212
226
|
fileKey,
|
|
213
227
|
extra,
|
|
214
228
|
AES_OBJECT_KEY_SALT
|
|
215
|
-
] : [fileKey, extra])).subarray(0, Math.min(fileKey.length + OBJECT_KEY_EXTRA_BYTES,
|
|
229
|
+
] : [fileKey, extra])).subarray(0, Math.min(fileKey.length + OBJECT_KEY_EXTRA_BYTES, 16));
|
|
216
230
|
}
|
|
217
231
|
function decryptAes(key, data, sink) {
|
|
218
232
|
if (data.length <= 16) {
|
|
@@ -261,4 +275,20 @@ function createStandardDecryptor(encryptDict, fileId, sink) {
|
|
|
261
275
|
};
|
|
262
276
|
}
|
|
263
277
|
//#endregion
|
|
278
|
+
exports.AESV2_KEY_BYTES = AESV2_KEY_BYTES;
|
|
279
|
+
exports.AESV3_KEY_BYTES = AESV3_KEY_BYTES;
|
|
280
|
+
exports.AESV3_SALT_BYTES = AESV3_SALT_BYTES;
|
|
281
|
+
exports.AES_OBJECT_KEY_SALT = AES_OBJECT_KEY_SALT;
|
|
282
|
+
exports.LEGACY_KEY_ITERATIONS = LEGACY_KEY_ITERATIONS;
|
|
283
|
+
exports.MD5_DIGEST_BYTES = MD5_DIGEST_BYTES;
|
|
284
|
+
exports.PASSWORD_PADDING = PASSWORD_PADDING;
|
|
285
|
+
exports.RC4_40_KEY_BYTES = RC4_40_KEY_BYTES;
|
|
286
|
+
exports.RC4_OBFUSCATION_ROUNDS = RC4_OBFUSCATION_ROUNDS;
|
|
287
|
+
exports.ZERO_IV = ZERO_IV;
|
|
288
|
+
exports.computeLegacyFileKeyFromPaddedPassword = computeLegacyFileKeyFromPaddedPassword;
|
|
264
289
|
exports.createStandardDecryptor = createStandardDecryptor;
|
|
290
|
+
exports.hardenedHash = hardenedHash;
|
|
291
|
+
exports.legacyUserValueCore = legacyUserValueCore;
|
|
292
|
+
exports.objectKey = objectKey;
|
|
293
|
+
exports.padOrTruncatePassword = padOrTruncatePassword;
|
|
294
|
+
exports.permissionsBytes = permissionsBytes;
|
package/dist/encrypt.d.cts
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
import { PdfDiagnosticSink } from "./diagnostics.cjs";
|
|
2
|
-
import { PdfDict } from "./objects.cjs";
|
|
2
|
+
import { n as PdfDict } from "./objects-B7HdMeWS.cjs";
|
|
3
3
|
//#region src/encrypt.d.ts
|
|
4
|
-
type CipherMethod =
|
|
4
|
+
type CipherMethod = "identity" | "rc4" | "aes";
|
|
5
5
|
interface PdfDecryptor {
|
|
6
6
|
decryptString(bytes: Uint8Array<ArrayBuffer>, num: number, gen: number): Uint8Array<ArrayBuffer>;
|
|
7
7
|
decryptStream(bytes: Uint8Array<ArrayBuffer>, dict: PdfDict, num: number, gen: number): Uint8Array<ArrayBuffer>;
|
|
8
8
|
}
|
|
9
|
+
declare const PASSWORD_PADDING: Uint8Array<ArrayBuffer>;
|
|
10
|
+
declare const AES_OBJECT_KEY_SALT: Uint8Array<ArrayBuffer>;
|
|
11
|
+
declare const MD5_DIGEST_BYTES = 16;
|
|
12
|
+
declare const LEGACY_KEY_ITERATIONS = 50;
|
|
13
|
+
declare const RC4_OBFUSCATION_ROUNDS = 19;
|
|
14
|
+
declare const AESV3_KEY_BYTES = 32;
|
|
15
|
+
declare const AESV3_SALT_BYTES = 8;
|
|
16
|
+
declare const RC4_40_KEY_BYTES = 5;
|
|
17
|
+
declare const AESV2_KEY_BYTES = 16;
|
|
18
|
+
declare const ZERO_IV: Uint8Array<ArrayBuffer>;
|
|
19
|
+
declare function permissionsBytes(p: number): Uint8Array<ArrayBuffer>;
|
|
20
|
+
declare function padOrTruncatePassword(password: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>;
|
|
21
|
+
declare function computeLegacyFileKeyFromPaddedPassword(paddedPassword: Uint8Array<ArrayBuffer>, owner: Uint8Array<ArrayBuffer>, permissions: number, fileId: Uint8Array<ArrayBuffer>, revision: number, keyBytes: number, encryptMetadata: boolean): Uint8Array<ArrayBuffer>;
|
|
22
|
+
declare function legacyUserValueCore(fileKey: Uint8Array<ArrayBuffer>, fileId: Uint8Array<ArrayBuffer>, revision: number): Uint8Array<ArrayBuffer>;
|
|
23
|
+
declare function hardenedHash(password: Uint8Array<ArrayBuffer>, salt: Uint8Array<ArrayBuffer>, userData: Uint8Array<ArrayBuffer>, revision: number): Uint8Array<ArrayBuffer>;
|
|
24
|
+
declare function objectKey(fileKey: Uint8Array<ArrayBuffer>, num: number, gen: number, method: CipherMethod): Uint8Array<ArrayBuffer>;
|
|
9
25
|
declare function createStandardDecryptor(encryptDict: PdfDict, fileId: Uint8Array<ArrayBuffer>, sink: PdfDiagnosticSink): PdfDecryptor;
|
|
10
26
|
//#endregion
|
|
11
|
-
export { CipherMethod, PdfDecryptor, createStandardDecryptor };
|
|
27
|
+
export { AESV2_KEY_BYTES, AESV3_KEY_BYTES, AESV3_SALT_BYTES, AES_OBJECT_KEY_SALT, CipherMethod, LEGACY_KEY_ITERATIONS, MD5_DIGEST_BYTES, PASSWORD_PADDING, PdfDecryptor, RC4_40_KEY_BYTES, RC4_OBFUSCATION_ROUNDS, ZERO_IV, computeLegacyFileKeyFromPaddedPassword, createStandardDecryptor, hardenedHash, legacyUserValueCore, objectKey, padOrTruncatePassword, permissionsBytes };
|
package/dist/encrypt.d.ts
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
import { PdfDiagnosticSink } from "./diagnostics.js";
|
|
2
|
-
import { PdfDict } from "./objects.js";
|
|
2
|
+
import { n as PdfDict } from "./objects-B7HdMeWS.js";
|
|
3
3
|
//#region src/encrypt.d.ts
|
|
4
|
-
type CipherMethod =
|
|
4
|
+
type CipherMethod = "identity" | "rc4" | "aes";
|
|
5
5
|
interface PdfDecryptor {
|
|
6
6
|
decryptString(bytes: Uint8Array<ArrayBuffer>, num: number, gen: number): Uint8Array<ArrayBuffer>;
|
|
7
7
|
decryptStream(bytes: Uint8Array<ArrayBuffer>, dict: PdfDict, num: number, gen: number): Uint8Array<ArrayBuffer>;
|
|
8
8
|
}
|
|
9
|
+
declare const PASSWORD_PADDING: Uint8Array<ArrayBuffer>;
|
|
10
|
+
declare const AES_OBJECT_KEY_SALT: Uint8Array<ArrayBuffer>;
|
|
11
|
+
declare const MD5_DIGEST_BYTES = 16;
|
|
12
|
+
declare const LEGACY_KEY_ITERATIONS = 50;
|
|
13
|
+
declare const RC4_OBFUSCATION_ROUNDS = 19;
|
|
14
|
+
declare const AESV3_KEY_BYTES = 32;
|
|
15
|
+
declare const AESV3_SALT_BYTES = 8;
|
|
16
|
+
declare const RC4_40_KEY_BYTES = 5;
|
|
17
|
+
declare const AESV2_KEY_BYTES = 16;
|
|
18
|
+
declare const ZERO_IV: Uint8Array<ArrayBuffer>;
|
|
19
|
+
declare function permissionsBytes(p: number): Uint8Array<ArrayBuffer>;
|
|
20
|
+
declare function padOrTruncatePassword(password: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>;
|
|
21
|
+
declare function computeLegacyFileKeyFromPaddedPassword(paddedPassword: Uint8Array<ArrayBuffer>, owner: Uint8Array<ArrayBuffer>, permissions: number, fileId: Uint8Array<ArrayBuffer>, revision: number, keyBytes: number, encryptMetadata: boolean): Uint8Array<ArrayBuffer>;
|
|
22
|
+
declare function legacyUserValueCore(fileKey: Uint8Array<ArrayBuffer>, fileId: Uint8Array<ArrayBuffer>, revision: number): Uint8Array<ArrayBuffer>;
|
|
23
|
+
declare function hardenedHash(password: Uint8Array<ArrayBuffer>, salt: Uint8Array<ArrayBuffer>, userData: Uint8Array<ArrayBuffer>, revision: number): Uint8Array<ArrayBuffer>;
|
|
24
|
+
declare function objectKey(fileKey: Uint8Array<ArrayBuffer>, num: number, gen: number, method: CipherMethod): Uint8Array<ArrayBuffer>;
|
|
9
25
|
declare function createStandardDecryptor(encryptDict: PdfDict, fileId: Uint8Array<ArrayBuffer>, sink: PdfDiagnosticSink): PdfDecryptor;
|
|
10
26
|
//#endregion
|
|
11
|
-
export { CipherMethod, PdfDecryptor, createStandardDecryptor };
|
|
27
|
+
export { AESV2_KEY_BYTES, AESV3_KEY_BYTES, AESV3_SALT_BYTES, AES_OBJECT_KEY_SALT, CipherMethod, LEGACY_KEY_ITERATIONS, MD5_DIGEST_BYTES, PASSWORD_PADDING, PdfDecryptor, RC4_40_KEY_BYTES, RC4_OBFUSCATION_ROUNDS, ZERO_IV, computeLegacyFileKeyFromPaddedPassword, createStandardDecryptor, hardenedHash, legacyUserValueCore, objectKey, padOrTruncatePassword, permissionsBytes };
|
package/dist/encrypt.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { asDict, asName, asNumber, dictGet } from "./objects.js";
|
|
1
2
|
import { concatBytes } from "./bytes/writer.js";
|
|
2
3
|
import { PdfEncryptedError, PdfPasswordRequiredError } from "./diagnostics.js";
|
|
3
4
|
import { aesCbcDecrypt, aesCbcEncrypt } from "./crypto/aes.js";
|
|
4
5
|
import { md5 } from "./crypto/md5.js";
|
|
5
6
|
import { rc4 } from "./crypto/rc4.js";
|
|
6
7
|
import { sha256, sha384, sha512 } from "./crypto/sha2.js";
|
|
7
|
-
import { asDict, asName, asNumber, dictGet } from "./objects.js";
|
|
8
8
|
//#region src/encrypt.ts
|
|
9
9
|
const PASSWORD_PADDING = new Uint8Array([
|
|
10
10
|
40,
|
|
@@ -49,11 +49,12 @@ const AES_OBJECT_KEY_SALT = new Uint8Array([
|
|
|
49
49
|
const MD5_DIGEST_BYTES = 16;
|
|
50
50
|
const OBJECT_KEY_EXTRA_BYTES = 5;
|
|
51
51
|
const LEGACY_KEY_ITERATIONS = 50;
|
|
52
|
-
const
|
|
52
|
+
const RC4_OBFUSCATION_ROUNDS = 19;
|
|
53
53
|
const R6_MINIMUM_ROUNDS = 64;
|
|
54
54
|
const R6_ROUND_REPEATS = 64;
|
|
55
55
|
const R6_TERMINATION_MARGIN = 32;
|
|
56
56
|
const AESV3_KEY_BYTES = 32;
|
|
57
|
+
const AESV3_SALT_BYTES = 8;
|
|
57
58
|
const RC4_40_KEY_BYTES = 5;
|
|
58
59
|
const AESV2_KEY_BYTES = 16;
|
|
59
60
|
const DEFAULT_KEY_BITS = 40;
|
|
@@ -79,11 +80,16 @@ function permissionsBytes(p) {
|
|
|
79
80
|
unsigned >>> 24 & 255
|
|
80
81
|
]);
|
|
81
82
|
}
|
|
82
|
-
function
|
|
83
|
-
|
|
84
|
-
const
|
|
83
|
+
function padOrTruncatePassword(password) {
|
|
84
|
+
if (password.length >= PASSWORD_PADDING.length) return password.subarray(0, PASSWORD_PADDING.length);
|
|
85
|
+
const padded = new Uint8Array(PASSWORD_PADDING.length);
|
|
86
|
+
padded.set(password);
|
|
87
|
+
padded.set(PASSWORD_PADDING.subarray(0, PASSWORD_PADDING.length - password.length), password.length);
|
|
88
|
+
return padded;
|
|
89
|
+
}
|
|
90
|
+
function computeLegacyFileKeyFromPaddedPassword(paddedPassword, owner, permissions, fileId, revision, keyBytes, encryptMetadata) {
|
|
85
91
|
const parts = [
|
|
86
|
-
|
|
92
|
+
paddedPassword,
|
|
87
93
|
owner.subarray(0, PASSWORD_PADDING.length),
|
|
88
94
|
permissionsBytes(permissions),
|
|
89
95
|
fileId
|
|
@@ -95,18 +101,26 @@ function computeLegacyFileKey(encryptDict, fileId, revision, keyBytes, encryptMe
|
|
|
95
101
|
255
|
|
96
102
|
]));
|
|
97
103
|
let digest = md5(concatBytes(parts));
|
|
98
|
-
if (revision >= 3) for (let i = 0; i <
|
|
104
|
+
if (revision >= 3) for (let i = 0; i < 50; i++) digest = md5(digest.subarray(0, keyBytes));
|
|
99
105
|
return digest.subarray(0, keyBytes);
|
|
100
106
|
}
|
|
101
|
-
function
|
|
102
|
-
const
|
|
103
|
-
|
|
107
|
+
function computeLegacyFileKey(encryptDict, fileId, revision, keyBytes, encryptMetadata) {
|
|
108
|
+
const owner = requireStringBytes(encryptDict, "O");
|
|
109
|
+
const permissions = asNumber(dictGet(encryptDict, "P")) ?? 0;
|
|
110
|
+
return computeLegacyFileKeyFromPaddedPassword(PASSWORD_PADDING, owner, permissions, fileId, revision, keyBytes, encryptMetadata);
|
|
111
|
+
}
|
|
112
|
+
function legacyUserValueCore(fileKey, fileId, revision) {
|
|
113
|
+
if (revision === 2) return rc4(fileKey, PASSWORD_PADDING);
|
|
104
114
|
let value = rc4(fileKey, md5(concatBytes([PASSWORD_PADDING, fileId])));
|
|
105
|
-
for (let i = 1; i <=
|
|
115
|
+
for (let i = 1; i <= 19; i++) {
|
|
106
116
|
const roundKey = Uint8Array.from(fileKey, (byte) => byte ^ i);
|
|
107
117
|
value = rc4(roundKey, value);
|
|
108
118
|
}
|
|
109
|
-
return
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
function legacyUserPasswordVerifies(encryptDict, fileId, revision, fileKey) {
|
|
122
|
+
const storedUser = requireStringBytes(encryptDict, "U");
|
|
123
|
+
return bytesEqual(legacyUserValueCore(fileKey, fileId, revision), storedUser, revision === 2 ? PASSWORD_PADDING.length : 16);
|
|
110
124
|
}
|
|
111
125
|
function hardenedHash(password, salt, userData, revision) {
|
|
112
126
|
let k = sha256(concatBytes([
|
|
@@ -132,20 +146,20 @@ function hardenedHash(password, salt, userData, revision) {
|
|
|
132
146
|
k = selector === 0 ? sha256(e) : selector === 1 ? sha384(e) : sha512(e);
|
|
133
147
|
round++;
|
|
134
148
|
}
|
|
135
|
-
return k.subarray(0,
|
|
149
|
+
return k.subarray(0, 32);
|
|
136
150
|
}
|
|
137
151
|
function computeAesV3FileKey(encryptDict, revision) {
|
|
138
152
|
const storedUser = requireStringBytes(encryptDict, "U");
|
|
139
153
|
const expectedLength = 48;
|
|
140
154
|
if (storedUser.length < expectedLength) throw new PdfEncryptedError(`the /Encrypt dictionary's /U entry is ${String(storedUser.length)} bytes; revision ${String(revision)} requires ${String(expectedLength)}`);
|
|
141
155
|
const empty = /* @__PURE__ */ new Uint8Array(0);
|
|
142
|
-
const validationSalt = storedUser.subarray(
|
|
156
|
+
const validationSalt = storedUser.subarray(32, 40);
|
|
143
157
|
const keySalt = storedUser.subarray(40, expectedLength);
|
|
144
|
-
if (!bytesEqual(hardenedHash(empty, validationSalt, empty, revision), storedUser,
|
|
158
|
+
if (!bytesEqual(hardenedHash(empty, validationSalt, empty, revision), storedUser, 32)) throw new PdfPasswordRequiredError();
|
|
145
159
|
const intermediateKey = hardenedHash(empty, keySalt, empty, revision);
|
|
146
160
|
const wrappedKey = requireStringBytes(encryptDict, "UE");
|
|
147
|
-
if (wrappedKey.length <
|
|
148
|
-
return aesCbcDecrypt(intermediateKey, ZERO_IV, wrappedKey.subarray(0,
|
|
161
|
+
if (wrappedKey.length < 32) throw new PdfEncryptedError(`the /Encrypt dictionary's /UE entry is ${String(wrappedKey.length)} bytes; revision ${String(revision)} requires ${String(32)}`);
|
|
162
|
+
return aesCbcDecrypt(intermediateKey, ZERO_IV, wrappedKey.subarray(0, 32));
|
|
149
163
|
}
|
|
150
164
|
function methodFromCryptFilterName(encryptDict, entryKey) {
|
|
151
165
|
const name = asName(dictGet(encryptDict, entryKey)) ?? "Identity";
|
|
@@ -163,7 +177,7 @@ function cryptFilterKeyBytes(encryptDict, declaredBits) {
|
|
|
163
177
|
const streamFilterName = asName(dictGet(encryptDict, "StmF")) ?? "Identity";
|
|
164
178
|
const filters = asDict(dictGet(encryptDict, "CF"));
|
|
165
179
|
const filter = filters !== void 0 ? asDict(dictGet(filters, streamFilterName)) : void 0;
|
|
166
|
-
if ((filter !== void 0 ? asName(dictGet(filter, "CFM")) : void 0) === "AESV2") return
|
|
180
|
+
if ((filter !== void 0 ? asName(dictGet(filter, "CFM")) : void 0) === "AESV2") return 16;
|
|
167
181
|
const declared = filter !== void 0 ? asNumber(dictGet(filter, "Length")) : void 0;
|
|
168
182
|
if (declared === void 0) return Math.floor(declaredBits / BITS_PER_BYTE);
|
|
169
183
|
return declared >= DEFAULT_KEY_BITS ? Math.floor(declared / BITS_PER_BYTE) : declared;
|
|
@@ -188,8 +202,8 @@ function setUpHandler(encryptDict, fileId) {
|
|
|
188
202
|
if (revision < 2 || revision > 4) throw new PdfEncryptedError(`unsupported standard security handler revision /R ${String(revision)}`);
|
|
189
203
|
const streamMethod = version === 4 ? methodFromCryptFilterName(encryptDict, "StmF") : "rc4";
|
|
190
204
|
const stringMethod = version === 4 ? methodFromCryptFilterName(encryptDict, "StrF") : "rc4";
|
|
191
|
-
const keyBytes = version === 1 ?
|
|
192
|
-
if (keyBytes <
|
|
205
|
+
const keyBytes = version === 1 ? 5 : version === 2 ? Math.floor(declaredBits / BITS_PER_BYTE) : cryptFilterKeyBytes(encryptDict, declaredBits);
|
|
206
|
+
if (keyBytes < 5 || keyBytes > MAX_RC4_KEY_BYTES) throw new PdfEncryptedError(`the /Encrypt dictionary declares a ${String(keyBytes * BITS_PER_BYTE)}-bit file key, outside the 40-128 bit range /V ${String(version)} permits`);
|
|
193
207
|
const fileKey = computeLegacyFileKey(encryptDict, fileId, revision, keyBytes, encryptMetadata);
|
|
194
208
|
if (!legacyUserPasswordVerifies(encryptDict, fileId, revision, fileKey)) throw new PdfPasswordRequiredError();
|
|
195
209
|
return {
|
|
@@ -211,7 +225,7 @@ function objectKey(fileKey, num, gen, method) {
|
|
|
211
225
|
fileKey,
|
|
212
226
|
extra,
|
|
213
227
|
AES_OBJECT_KEY_SALT
|
|
214
|
-
] : [fileKey, extra])).subarray(0, Math.min(fileKey.length + OBJECT_KEY_EXTRA_BYTES,
|
|
228
|
+
] : [fileKey, extra])).subarray(0, Math.min(fileKey.length + OBJECT_KEY_EXTRA_BYTES, 16));
|
|
215
229
|
}
|
|
216
230
|
function decryptAes(key, data, sink) {
|
|
217
231
|
if (data.length <= 16) {
|
|
@@ -260,4 +274,4 @@ function createStandardDecryptor(encryptDict, fileId, sink) {
|
|
|
260
274
|
};
|
|
261
275
|
}
|
|
262
276
|
//#endregion
|
|
263
|
-
export { createStandardDecryptor };
|
|
277
|
+
export { AESV2_KEY_BYTES, AESV3_KEY_BYTES, AESV3_SALT_BYTES, AES_OBJECT_KEY_SALT, LEGACY_KEY_ITERATIONS, MD5_DIGEST_BYTES, PASSWORD_PADDING, RC4_40_KEY_BYTES, RC4_OBFUSCATION_ROUNDS, ZERO_IV, computeLegacyFileKeyFromPaddedPassword, createStandardDecryptor, hardenedHash, legacyUserValueCore, objectKey, padOrTruncatePassword, permissionsBytes };
|
package/dist/filters.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_bytes_reader = require("./bytes/reader.cjs");
|
|
3
2
|
const require_objects = require("./objects.cjs");
|
|
3
|
+
const require_bytes_reader = require("./bytes/reader.cjs");
|
|
4
4
|
const require_bytes_flate = require("./bytes/flate.cjs");
|
|
5
5
|
const require_image_ccitt = require("./image/ccitt.cjs");
|
|
6
6
|
const require_image_jbig2 = require("./image/jbig2.cjs");
|
|
@@ -62,11 +62,13 @@ function ccittFaxDecode(data, parm, dict, sink) {
|
|
|
62
62
|
rows,
|
|
63
63
|
blackIs1: require_objects.asBool(parmGet("BlackIs1")),
|
|
64
64
|
encodedByteAlign: require_objects.asBool(parmGet("EncodedByteAlign")),
|
|
65
|
-
onWarning: (message) =>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
onWarning: (message) => {
|
|
66
|
+
sink({
|
|
67
|
+
code: "pdf/ccitt-fax-degraded",
|
|
68
|
+
severity: "warning",
|
|
69
|
+
message
|
|
70
|
+
});
|
|
71
|
+
}
|
|
70
72
|
}).bytes;
|
|
71
73
|
}
|
|
72
74
|
function jbig2Decode(data, parm, dict, sink, resolve) {
|
|
@@ -84,11 +86,13 @@ function jbig2Decode(data, parm, dict, sink, resolve) {
|
|
|
84
86
|
globals,
|
|
85
87
|
width: require_objects.asNumber(require_objects.dictGet(dict, "Width") ?? require_objects.dictGet(dict, "W")),
|
|
86
88
|
height: require_objects.asNumber(require_objects.dictGet(dict, "Height") ?? require_objects.dictGet(dict, "H")),
|
|
87
|
-
onWarning: (message) =>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
onWarning: (message) => {
|
|
90
|
+
sink({
|
|
91
|
+
code: "pdf/jbig2-degraded",
|
|
92
|
+
severity: "warning",
|
|
93
|
+
message
|
|
94
|
+
});
|
|
95
|
+
}
|
|
92
96
|
});
|
|
93
97
|
return Uint8Array.from(image.bytes, (byte) => byte ^ 255);
|
|
94
98
|
} catch (error) {
|
|
@@ -188,9 +192,9 @@ function lzwDecode(data, earlyChange, sink) {
|
|
|
188
192
|
if (prevEntry !== void 0) {
|
|
189
193
|
dict[nextCode] = concatTwo(prevEntry, new Uint8Array([entry[0] ?? 0]));
|
|
190
194
|
nextCode++;
|
|
191
|
-
if (nextCode + bias ===
|
|
192
|
-
else if (nextCode + bias ===
|
|
193
|
-
else if (nextCode + bias ===
|
|
195
|
+
if (nextCode + bias === 512) codeWidth = 10;
|
|
196
|
+
else if (nextCode + bias === 1024) codeWidth = 11;
|
|
197
|
+
else if (nextCode + bias === 2048) codeWidth = 12;
|
|
194
198
|
}
|
|
195
199
|
prevEntry = entry;
|
|
196
200
|
}
|
package/dist/filters.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/filters.d.ts
|
|
4
4
|
interface DecodedStream {
|
|
5
5
|
readonly bytes: Uint8Array<ArrayBuffer>;
|
package/dist/filters.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/filters.d.ts
|
|
4
4
|
interface DecodedStream {
|
|
5
5
|
readonly bytes: Uint8Array<ArrayBuffer>;
|
package/dist/filters.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isAsciiWhitespace } from "./bytes/reader.js";
|
|
2
1
|
import { asArray, asBool, asDict, asName, asNumber, dictGet } from "./objects.js";
|
|
2
|
+
import { isAsciiWhitespace } from "./bytes/reader.js";
|
|
3
3
|
import { inflateTolerant } from "./bytes/flate.js";
|
|
4
4
|
import { decodeCcittFax } from "./image/ccitt.js";
|
|
5
5
|
import { decodeJbig2Embedded } from "./image/jbig2.js";
|
|
@@ -61,11 +61,13 @@ function ccittFaxDecode(data, parm, dict, sink) {
|
|
|
61
61
|
rows,
|
|
62
62
|
blackIs1: asBool(parmGet("BlackIs1")),
|
|
63
63
|
encodedByteAlign: asBool(parmGet("EncodedByteAlign")),
|
|
64
|
-
onWarning: (message) =>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
onWarning: (message) => {
|
|
65
|
+
sink({
|
|
66
|
+
code: "pdf/ccitt-fax-degraded",
|
|
67
|
+
severity: "warning",
|
|
68
|
+
message
|
|
69
|
+
});
|
|
70
|
+
}
|
|
69
71
|
}).bytes;
|
|
70
72
|
}
|
|
71
73
|
function jbig2Decode(data, parm, dict, sink, resolve) {
|
|
@@ -83,11 +85,13 @@ function jbig2Decode(data, parm, dict, sink, resolve) {
|
|
|
83
85
|
globals,
|
|
84
86
|
width: asNumber(dictGet(dict, "Width") ?? dictGet(dict, "W")),
|
|
85
87
|
height: asNumber(dictGet(dict, "Height") ?? dictGet(dict, "H")),
|
|
86
|
-
onWarning: (message) =>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
onWarning: (message) => {
|
|
89
|
+
sink({
|
|
90
|
+
code: "pdf/jbig2-degraded",
|
|
91
|
+
severity: "warning",
|
|
92
|
+
message
|
|
93
|
+
});
|
|
94
|
+
}
|
|
91
95
|
});
|
|
92
96
|
return Uint8Array.from(image.bytes, (byte) => byte ^ 255);
|
|
93
97
|
} catch (error) {
|
|
@@ -187,9 +191,9 @@ function lzwDecode(data, earlyChange, sink) {
|
|
|
187
191
|
if (prevEntry !== void 0) {
|
|
188
192
|
dict[nextCode] = concatTwo(prevEntry, new Uint8Array([entry[0] ?? 0]));
|
|
189
193
|
nextCode++;
|
|
190
|
-
if (nextCode + bias ===
|
|
191
|
-
else if (nextCode + bias ===
|
|
192
|
-
else if (nextCode + bias ===
|
|
194
|
+
if (nextCode + bias === 512) codeWidth = 10;
|
|
195
|
+
else if (nextCode + bias === 1024) codeWidth = 11;
|
|
196
|
+
else if (nextCode + bias === 2048) codeWidth = 12;
|
|
193
197
|
}
|
|
194
198
|
prevEntry = entry;
|
|
195
199
|
}
|
package/dist/font-read.cjs
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_afm_widths = require("./afm-widths-
|
|
3
|
-
const require_cmap = require("./cmap.cjs");
|
|
2
|
+
const require_afm_widths = require("./afm-widths-BTu0IDp2.cjs");
|
|
4
3
|
const require_objects = require("./objects.cjs");
|
|
5
4
|
const require_filters = require("./filters.cjs");
|
|
5
|
+
const require_builtin_encoding = require("./builtin-encoding.cjs");
|
|
6
|
+
const require_cmap = require("./cmap.cjs");
|
|
6
7
|
const require_fonts = require("./fonts.cjs");
|
|
7
8
|
const require_font_style = require("./font-style.cjs");
|
|
8
9
|
//#region src/font-read.ts
|
|
10
|
+
const SYMBOLIC_FLAG_BIT = 4;
|
|
9
11
|
const ITALIC_FLAG_BIT = 64;
|
|
10
12
|
const FORCE_BOLD_FLAG_BIT = 1 << 18;
|
|
11
13
|
const REPLACEMENT_CHARACTER = "�";
|
|
@@ -14,14 +16,34 @@ function styleFlagsFromDescriptor(descriptor) {
|
|
|
14
16
|
return {
|
|
15
17
|
forceBold: flags !== void 0 ? (flags & FORCE_BOLD_FLAG_BIT) !== 0 : void 0,
|
|
16
18
|
italicFlag: flags !== void 0 ? (flags & ITALIC_FLAG_BIT) !== 0 : void 0,
|
|
17
|
-
italicAngle: descriptor !== void 0 ? require_objects.asNumber(require_objects.dictGet(descriptor, "ItalicAngle")) : void 0
|
|
19
|
+
italicAngle: descriptor !== void 0 ? require_objects.asNumber(require_objects.dictGet(descriptor, "ItalicAngle")) : void 0,
|
|
20
|
+
symbolic: flags !== void 0 ? (flags & SYMBOLIC_FLAG_BIT) !== 0 : void 0
|
|
18
21
|
};
|
|
19
22
|
}
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
if (
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
function builtinSymbolGlyphNameLookup(baseFamily) {
|
|
24
|
+
if (baseFamily === "Symbol") return require_afm_widths.symbolGlyphName;
|
|
25
|
+
if (baseFamily === "ZapfDingbats") return require_afm_widths.zapfDingbatsGlyphName;
|
|
26
|
+
}
|
|
27
|
+
function readFontProgram(descriptor, context) {
|
|
28
|
+
if (descriptor === void 0) return;
|
|
29
|
+
for (const key of [
|
|
30
|
+
"FontFile2",
|
|
31
|
+
"FontFile3",
|
|
32
|
+
"FontFile"
|
|
33
|
+
]) {
|
|
34
|
+
const stream = context.resolver.resolve(require_objects.dictGet(descriptor, key));
|
|
35
|
+
if (stream?.kind !== "stream") continue;
|
|
36
|
+
const decoded = require_filters.decodeStream(stream.raw, stream.dict, context.sink);
|
|
37
|
+
const encoding = require_builtin_encoding.readFontProgramEncoding(decoded.bytes);
|
|
38
|
+
if (encoding !== void 0) return encoding;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function lazyFontProgram(descriptor, context) {
|
|
42
|
+
let read;
|
|
43
|
+
return () => {
|
|
44
|
+
read ??= { encoding: readFontProgram(descriptor, context) };
|
|
45
|
+
return read.encoding;
|
|
46
|
+
};
|
|
25
47
|
}
|
|
26
48
|
function readDifferencesMap(differences) {
|
|
27
49
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -43,7 +65,10 @@ function readToUnicodeCMap(fontDict, context) {
|
|
|
43
65
|
function buildSimpleFont(fontDict, context) {
|
|
44
66
|
const baseFont = require_objects.asName(require_objects.dictGet(fontDict, "BaseFont")) ?? "Helvetica";
|
|
45
67
|
const descriptor = context.resolver.resolveDict(require_objects.dictGet(fontDict, "FontDescriptor"));
|
|
46
|
-
const
|
|
68
|
+
const styleFlags = styleFlagsFromDescriptor(descriptor);
|
|
69
|
+
const { baseFamily, bold, italic } = require_font_style.styleFromBaseFontName(baseFont, styleFlags);
|
|
70
|
+
const symbolic = styleFlags.symbolic ?? false;
|
|
71
|
+
const builtinGlyphName = builtinSymbolGlyphNameLookup(baseFamily);
|
|
47
72
|
const widthsArr = require_objects.asArray(require_objects.dictGet(fontDict, "Widths"));
|
|
48
73
|
const firstChar = require_objects.asNumber(require_objects.dictGet(fontDict, "FirstChar")) ?? 0;
|
|
49
74
|
const missingWidth = (descriptor !== void 0 ? require_objects.asNumber(require_objects.dictGet(descriptor, "MissingWidth")) : void 0) ?? 0;
|
|
@@ -62,12 +87,36 @@ function buildSimpleFont(fontDict, context) {
|
|
|
62
87
|
const encodingObj = require_objects.dictGet(fontDict, "Encoding");
|
|
63
88
|
const encodingDict = context.resolver.resolveDict(encodingObj);
|
|
64
89
|
const baseEncodingName = require_objects.asName(encodingDict !== void 0 ? require_objects.dictGet(encodingDict, "BaseEncoding") : encodingObj);
|
|
65
|
-
|
|
90
|
+
const namedBaseGlyphName = baseEncodingName !== void 0 ? require_afm_widths.namedEncodingGlyphName(baseEncodingName) : void 0;
|
|
91
|
+
if (baseEncodingName !== void 0 && namedBaseGlyphName === void 0) context.sink({
|
|
66
92
|
code: "char/encoding-approximated",
|
|
67
93
|
severity: "info",
|
|
68
94
|
message: `base encoding "${baseEncodingName}" has no dedicated table here and is approximated as WinAnsiEncoding`
|
|
69
95
|
});
|
|
70
96
|
const differencesMap = readDifferencesMap(encodingDict !== void 0 ? require_objects.asArray(require_objects.dictGet(encodingDict, "Differences")) : void 0);
|
|
97
|
+
const programEncoding = lazyFontProgram(descriptor, context);
|
|
98
|
+
const symbolEncoded = symbolic || builtinGlyphName !== void 0;
|
|
99
|
+
const byGlyphName = (source) => (code) => {
|
|
100
|
+
const name = source(code);
|
|
101
|
+
return name === void 0 ? void 0 : require_afm_widths.glyphNameToUnicode(name);
|
|
102
|
+
};
|
|
103
|
+
const fromProgram = (code) => programEncoding()?.codeToUnicode(code);
|
|
104
|
+
const namedBase = namedBaseGlyphName === void 0 ? void 0 : byGlyphName(namedBaseGlyphName);
|
|
105
|
+
const resolvers = [byGlyphName((code) => differencesMap.get(code)), ...symbolEncoded ? [
|
|
106
|
+
fromProgram,
|
|
107
|
+
builtinGlyphName === void 0 ? void 0 : byGlyphName(builtinGlyphName),
|
|
108
|
+
namedBase
|
|
109
|
+
] : [
|
|
110
|
+
namedBase,
|
|
111
|
+
fromProgram,
|
|
112
|
+
byGlyphName(require_afm_widths.winAnsiGlyphName)
|
|
113
|
+
]].filter((resolver) => resolver !== void 0);
|
|
114
|
+
const unicodeForCode = (code) => {
|
|
115
|
+
for (const resolve of resolvers) {
|
|
116
|
+
const unicode = resolve(code);
|
|
117
|
+
if (unicode !== void 0) return unicode;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
71
120
|
const decodeToUnicode = (codes) => {
|
|
72
121
|
let out = "";
|
|
73
122
|
let unmapped = 0;
|
|
@@ -77,10 +126,9 @@ function buildSimpleFont(fontDict, context) {
|
|
|
77
126
|
out += viaToUnicode;
|
|
78
127
|
continue;
|
|
79
128
|
}
|
|
80
|
-
const
|
|
81
|
-
const unicode = name !== void 0 ? glyphNameToUnicodeWithUniFallback(name) : void 0;
|
|
129
|
+
const unicode = unicodeForCode(code);
|
|
82
130
|
if (unicode !== void 0) {
|
|
83
|
-
out += String.
|
|
131
|
+
out += String.fromCodePoint(unicode);
|
|
84
132
|
continue;
|
|
85
133
|
}
|
|
86
134
|
unmapped++;
|
|
@@ -139,6 +187,8 @@ function buildCompositeFont(fontDict, context) {
|
|
|
139
187
|
const widthMap = readCidWidths(descendantDict !== void 0 ? require_objects.asArray(require_objects.dictGet(descendantDict, "W")) : void 0);
|
|
140
188
|
const widthOf = (cid) => widthMap.get(cid) ?? dw;
|
|
141
189
|
const toUnicode = readToUnicodeCMap(fontDict, context);
|
|
190
|
+
const cidToGidMap = descendantDict !== void 0 ? require_objects.dictGet(descendantDict, "CIDToGIDMap") : void 0;
|
|
191
|
+
const programEncoding = require_objects.isName(require_objects.dictGet(fontDict, "Encoding"), "Identity-H") && (cidToGidMap === void 0 || require_objects.isName(cidToGidMap, "Identity")) ? lazyFontProgram(descriptor, context) : void 0;
|
|
142
192
|
const decodeToUnicode = (codes) => {
|
|
143
193
|
let out = "";
|
|
144
194
|
let glyphCount = 0;
|
|
@@ -151,6 +201,11 @@ function buildCompositeFont(fontDict, context) {
|
|
|
151
201
|
out += mapped;
|
|
152
202
|
continue;
|
|
153
203
|
}
|
|
204
|
+
const fromProgram = programEncoding?.()?.glyphIdToUnicode(cid);
|
|
205
|
+
if (fromProgram !== void 0) {
|
|
206
|
+
out += String.fromCodePoint(fromProgram);
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
154
209
|
unmapped++;
|
|
155
210
|
out += REPLACEMENT_CHARACTER;
|
|
156
211
|
}
|
package/dist/font-read.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 { FontMetricsPort, PdfObjectResolver } from "./interpret.cjs";
|
|
4
4
|
//#region src/font-read.d.ts
|
|
5
5
|
interface PdfFont {
|