pdf-parser.js 5.2.20 → 5.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/encrypt.cjs CHANGED
@@ -68,7 +68,6 @@ function requireStringBytes(dict, key) {
68
68
  return value.bytes;
69
69
  }
70
70
  function bytesEqual(a, b, length) {
71
- if (a.length < length || b.length < length) return false;
72
71
  for (let i = 0; i < length; i++) if (a[i] !== b[i]) return false;
73
72
  return true;
74
73
  }
@@ -82,10 +81,8 @@ function permissionsBytes(p) {
82
81
  ]);
83
82
  }
84
83
  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);
84
+ const padded = new Uint8Array(PASSWORD_PADDING);
85
+ padded.set(password.subarray(0, PASSWORD_PADDING.length));
89
86
  return padded;
90
87
  }
91
88
  function computeLegacyFileKeyFromPaddedPassword(paddedPassword, owner, permissions, fileId, revision, keyBytes, encryptMetadata) {
@@ -130,9 +127,9 @@ function hardenedHash(password, salt, userData, revision) {
130
127
  userData
131
128
  ]));
132
129
  if (revision === 5) return k;
133
- let e = new Uint8Array([0]);
130
+ let e;
134
131
  let round = 0;
135
- while (round < R6_MINIMUM_ROUNDS || e[e.length - 1] > round - R6_TERMINATION_MARGIN) {
132
+ do {
136
133
  const roundInput = require_bytes_writer.concatBytes([
137
134
  password,
138
135
  k,
@@ -146,7 +143,7 @@ function hardenedHash(password, salt, userData, revision) {
146
143
  const selector = sum % 3;
147
144
  k = selector === 0 ? require_crypto_sha2.sha256(e) : selector === 1 ? require_crypto_sha2.sha384(e) : require_crypto_sha2.sha512(e);
148
145
  round++;
149
- }
146
+ } while (round < R6_MINIMUM_ROUNDS || e[e.length - 1] > round - R6_TERMINATION_MARGIN);
150
147
  return k.subarray(0, 32);
151
148
  }
152
149
  function computeAesV3FileKey(encryptDict, revision) {
@@ -245,7 +242,7 @@ function decryptAes(key, data, sink) {
245
242
  });
246
243
  const plain = require_crypto_aes.aesCbcDecrypt(key, data.subarray(0, 16), body);
247
244
  const padLength = plain[plain.length - 1] ?? 0;
248
- if (padLength < 1 || padLength > 16 || padLength > plain.length) {
245
+ if (padLength < 1 || padLength > 16) {
249
246
  sink({
250
247
  code: "pdf/decrypt-bad-padding",
251
248
  severity: "warning",
package/dist/encrypt.js CHANGED
@@ -67,7 +67,6 @@ function requireStringBytes(dict, key) {
67
67
  return value.bytes;
68
68
  }
69
69
  function bytesEqual(a, b, length) {
70
- if (a.length < length || b.length < length) return false;
71
70
  for (let i = 0; i < length; i++) if (a[i] !== b[i]) return false;
72
71
  return true;
73
72
  }
@@ -81,10 +80,8 @@ function permissionsBytes(p) {
81
80
  ]);
82
81
  }
83
82
  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);
83
+ const padded = new Uint8Array(PASSWORD_PADDING);
84
+ padded.set(password.subarray(0, PASSWORD_PADDING.length));
88
85
  return padded;
89
86
  }
90
87
  function computeLegacyFileKeyFromPaddedPassword(paddedPassword, owner, permissions, fileId, revision, keyBytes, encryptMetadata) {
@@ -129,9 +126,9 @@ function hardenedHash(password, salt, userData, revision) {
129
126
  userData
130
127
  ]));
131
128
  if (revision === 5) return k;
132
- let e = new Uint8Array([0]);
129
+ let e;
133
130
  let round = 0;
134
- while (round < R6_MINIMUM_ROUNDS || e[e.length - 1] > round - R6_TERMINATION_MARGIN) {
131
+ do {
135
132
  const roundInput = concatBytes([
136
133
  password,
137
134
  k,
@@ -145,7 +142,7 @@ function hardenedHash(password, salt, userData, revision) {
145
142
  const selector = sum % 3;
146
143
  k = selector === 0 ? sha256(e) : selector === 1 ? sha384(e) : sha512(e);
147
144
  round++;
148
- }
145
+ } while (round < R6_MINIMUM_ROUNDS || e[e.length - 1] > round - R6_TERMINATION_MARGIN);
149
146
  return k.subarray(0, 32);
150
147
  }
151
148
  function computeAesV3FileKey(encryptDict, revision) {
@@ -244,7 +241,7 @@ function decryptAes(key, data, sink) {
244
241
  });
245
242
  const plain = aesCbcDecrypt(key, data.subarray(0, 16), body);
246
243
  const padLength = plain[plain.length - 1] ?? 0;
247
- if (padLength < 1 || padLength > 16 || padLength > plain.length) {
244
+ if (padLength < 1 || padLength > 16) {
248
245
  sink({
249
246
  code: "pdf/decrypt-bad-padding",
250
247
  severity: "warning",
@@ -42,74 +42,24 @@ function zeroCodingContext(subband, horizontal, vertical, diagonal) {
42
42
  if (secondary === 1) return 3;
43
43
  return diagonal >= 2 ? 2 : diagonal === 1 ? 1 : 0;
44
44
  }
45
- const SIGN_CONTEXT_TABLE = (() => {
46
- const rows = [
47
- [
48
- 1,
49
- 1,
50
- 4,
51
- 0
52
- ],
53
- [
54
- 1,
55
- 0,
56
- 3,
57
- 0
58
- ],
59
- [
60
- 1,
61
- -1,
62
- 2,
63
- 0
64
- ],
65
- [
66
- 0,
67
- 1,
68
- 1,
69
- 0
70
- ],
71
- [
72
- 0,
73
- 0,
74
- 0,
75
- 0
76
- ],
77
- [
78
- 0,
79
- -1,
80
- 1,
81
- 1
82
- ],
83
- [
84
- -1,
85
- 1,
86
- 2,
87
- 1
88
- ],
89
- [
90
- -1,
91
- 0,
92
- 3,
93
- 1
94
- ],
95
- [
96
- -1,
97
- -1,
98
- 4,
99
- 1
100
- ]
101
- ];
102
- const table = new Array(9).fill(0);
103
- for (const [horizontal, vertical, offset, xorBit] of rows) table[(horizontal + 1) * 3 + (vertical + 1)] = offset | xorBit << 3;
104
- return table;
105
- })();
106
45
  const SIGN_XOR_FLAG = 8;
46
+ const SIGN_CONTEXT_TABLE = [
47
+ 12,
48
+ 11,
49
+ 10,
50
+ 9,
51
+ 0,
52
+ 1,
53
+ 2,
54
+ 3,
55
+ 4
56
+ ];
107
57
  function decodeJpeg2000CodeBlock(options) {
108
58
  const { width, height, subband, zeroBitPlanes, maxBitPlanes, totalPasses, codeBlockStyle, data } = options;
109
59
  throwForUnsupportedStyle(codeBlockStyle);
110
60
  const values = new Int32Array(Math.max(width * height, 0));
111
61
  const codedBitPlanes = maxBitPlanes - zeroBitPlanes;
112
- if (width <= 0 || height <= 0 || codedBitPlanes <= 0 || totalPasses <= 0 || data.length === 0) return { values };
62
+ if (width <= 0 || height <= 0 || data.length === 0) return { values };
113
63
  const stride = width + 2;
114
64
  const cellCount = stride * (height + 2);
115
65
  const significant = new Uint8Array(cellCount);
@@ -172,7 +122,6 @@ function decodeJpeg2000CodeBlock(options) {
172
122
  const context = significanceContext(x, y, stripeEnd);
173
123
  if (context === 0) continue;
174
124
  if (mq.decode(contexts, context) === 1) becomeSignificant(x, y, plane, stripeEnd);
175
- else lastCodedPlane[n] = plane;
176
125
  codedThisPlane[n] = 1;
177
126
  }
178
127
  }
@@ -197,12 +146,8 @@ function decodeJpeg2000CodeBlock(options) {
197
146
  for (let x = 0; x < width; x++) {
198
147
  let y = stripe;
199
148
  if (fullStripe && columnIsRunLengthEligible(x, stripe, stripeEnd)) {
200
- if (mq.decode(contexts, RUN_LENGTH_CONTEXT) === 0) {
201
- for (let row = stripe; row < stripeEnd; row++) lastCodedPlane[at(x, row)] = plane;
202
- continue;
203
- }
149
+ if (mq.decode(contexts, RUN_LENGTH_CONTEXT) === 0) continue;
204
150
  const firstSignificant = mq.decode(contexts, UNIFORM_CONTEXT) << 1 | mq.decode(contexts, UNIFORM_CONTEXT);
205
- for (let row = stripe; row < stripe + firstSignificant; row++) lastCodedPlane[at(x, row)] = plane;
206
151
  y = stripe + firstSignificant;
207
152
  becomeSignificant(x, y, plane, stripeEnd);
208
153
  y++;
@@ -211,7 +156,6 @@ function decodeJpeg2000CodeBlock(options) {
211
156
  const n = at(x, y);
212
157
  if ((codedThisPlane[n] ?? 0) === 1 || (significant[n] ?? 0) === 1) continue;
213
158
  if (mq.decode(contexts, significanceContext(x, y, stripeEnd)) === 1) becomeSignificant(x, y, plane, stripeEnd);
214
- else lastCodedPlane[n] = plane;
215
159
  }
216
160
  }
217
161
  }
@@ -222,11 +166,7 @@ function decodeJpeg2000CodeBlock(options) {
222
166
  codedThisPlane.fill(0);
223
167
  };
224
168
  function columnIsRunLengthEligible(x, stripe, stripeEnd) {
225
- for (let y = stripe; y < stripeEnd; y++) {
226
- const n = at(x, y);
227
- if ((significant[n] ?? 0) === 1 || (codedThisPlane[n] ?? 0) === 1) return false;
228
- if (significanceContext(x, y, stripeEnd) !== 0) return false;
229
- }
169
+ for (let y = stripe; y < stripeEnd; y++) if (significanceContext(x, y, stripeEnd) !== 0) return false;
230
170
  return true;
231
171
  }
232
172
  let plane = codedBitPlanes - 1;
@@ -41,74 +41,24 @@ function zeroCodingContext(subband, horizontal, vertical, diagonal) {
41
41
  if (secondary === 1) return 3;
42
42
  return diagonal >= 2 ? 2 : diagonal === 1 ? 1 : 0;
43
43
  }
44
- const SIGN_CONTEXT_TABLE = (() => {
45
- const rows = [
46
- [
47
- 1,
48
- 1,
49
- 4,
50
- 0
51
- ],
52
- [
53
- 1,
54
- 0,
55
- 3,
56
- 0
57
- ],
58
- [
59
- 1,
60
- -1,
61
- 2,
62
- 0
63
- ],
64
- [
65
- 0,
66
- 1,
67
- 1,
68
- 0
69
- ],
70
- [
71
- 0,
72
- 0,
73
- 0,
74
- 0
75
- ],
76
- [
77
- 0,
78
- -1,
79
- 1,
80
- 1
81
- ],
82
- [
83
- -1,
84
- 1,
85
- 2,
86
- 1
87
- ],
88
- [
89
- -1,
90
- 0,
91
- 3,
92
- 1
93
- ],
94
- [
95
- -1,
96
- -1,
97
- 4,
98
- 1
99
- ]
100
- ];
101
- const table = new Array(9).fill(0);
102
- for (const [horizontal, vertical, offset, xorBit] of rows) table[(horizontal + 1) * 3 + (vertical + 1)] = offset | xorBit << 3;
103
- return table;
104
- })();
105
44
  const SIGN_XOR_FLAG = 8;
45
+ const SIGN_CONTEXT_TABLE = [
46
+ 12,
47
+ 11,
48
+ 10,
49
+ 9,
50
+ 0,
51
+ 1,
52
+ 2,
53
+ 3,
54
+ 4
55
+ ];
106
56
  function decodeJpeg2000CodeBlock(options) {
107
57
  const { width, height, subband, zeroBitPlanes, maxBitPlanes, totalPasses, codeBlockStyle, data } = options;
108
58
  throwForUnsupportedStyle(codeBlockStyle);
109
59
  const values = new Int32Array(Math.max(width * height, 0));
110
60
  const codedBitPlanes = maxBitPlanes - zeroBitPlanes;
111
- if (width <= 0 || height <= 0 || codedBitPlanes <= 0 || totalPasses <= 0 || data.length === 0) return { values };
61
+ if (width <= 0 || height <= 0 || data.length === 0) return { values };
112
62
  const stride = width + 2;
113
63
  const cellCount = stride * (height + 2);
114
64
  const significant = new Uint8Array(cellCount);
@@ -171,7 +121,6 @@ function decodeJpeg2000CodeBlock(options) {
171
121
  const context = significanceContext(x, y, stripeEnd);
172
122
  if (context === 0) continue;
173
123
  if (mq.decode(contexts, context) === 1) becomeSignificant(x, y, plane, stripeEnd);
174
- else lastCodedPlane[n] = plane;
175
124
  codedThisPlane[n] = 1;
176
125
  }
177
126
  }
@@ -196,12 +145,8 @@ function decodeJpeg2000CodeBlock(options) {
196
145
  for (let x = 0; x < width; x++) {
197
146
  let y = stripe;
198
147
  if (fullStripe && columnIsRunLengthEligible(x, stripe, stripeEnd)) {
199
- if (mq.decode(contexts, RUN_LENGTH_CONTEXT) === 0) {
200
- for (let row = stripe; row < stripeEnd; row++) lastCodedPlane[at(x, row)] = plane;
201
- continue;
202
- }
148
+ if (mq.decode(contexts, RUN_LENGTH_CONTEXT) === 0) continue;
203
149
  const firstSignificant = mq.decode(contexts, UNIFORM_CONTEXT) << 1 | mq.decode(contexts, UNIFORM_CONTEXT);
204
- for (let row = stripe; row < stripe + firstSignificant; row++) lastCodedPlane[at(x, row)] = plane;
205
150
  y = stripe + firstSignificant;
206
151
  becomeSignificant(x, y, plane, stripeEnd);
207
152
  y++;
@@ -210,7 +155,6 @@ function decodeJpeg2000CodeBlock(options) {
210
155
  const n = at(x, y);
211
156
  if ((codedThisPlane[n] ?? 0) === 1 || (significant[n] ?? 0) === 1) continue;
212
157
  if (mq.decode(contexts, significanceContext(x, y, stripeEnd)) === 1) becomeSignificant(x, y, plane, stripeEnd);
213
- else lastCodedPlane[n] = plane;
214
158
  }
215
159
  }
216
160
  }
@@ -221,11 +165,7 @@ function decodeJpeg2000CodeBlock(options) {
221
165
  codedThisPlane.fill(0);
222
166
  };
223
167
  function columnIsRunLengthEligible(x, stripe, stripeEnd) {
224
- for (let y = stripe; y < stripeEnd; y++) {
225
- const n = at(x, y);
226
- if ((significant[n] ?? 0) === 1 || (codedThisPlane[n] ?? 0) === 1) return false;
227
- if (significanceContext(x, y, stripeEnd) !== 0) return false;
228
- }
168
+ for (let y = stripe; y < stripeEnd; y++) if (significanceContext(x, y, stripeEnd) !== 0) return false;
229
169
  return true;
230
170
  }
231
171
  let plane = codedBitPlanes - 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdf-parser.js",
3
- "version": "5.2.20",
3
+ "version": "5.2.22",
4
4
  "description": "Hand-written, dependency-minimal PDF codec: parses arbitrary real-world PDFs and generates new ones, built on its own codec-owned LayoutDocument item model and Zod 4 codecs.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -72,7 +72,7 @@
72
72
  ],
73
73
  "license": "MIT",
74
74
  "dependencies": {
75
- "byte-codec": "1.10.1",
75
+ "byte-codec": "2.0.0",
76
76
  "document-schema.js": "7.15.0",
77
77
  "fflate": "0.8.3",
78
78
  "zod": "4.4.3"