79 Commits

Author SHA1 Message Date
Jonas Jenwald
e73224ded7 Introduce Math.sumPrecise usage in the code-base
This is a new JavaScript feature that makes it easy to compute the sum of list of values; see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sumPrecise

This allows us to remove most cases of `Array.prototype.reduce`, which helps improve readability since that (in my opinion) often isn't the most intuitive code.
2025-03-23 13:03:56 +01:00
Jonas Jenwald
0e15f709c4 Remove unnecessary else if when checking the encryptionKey in the CipherTransformFactory constructor
This can be simplified a tiny bit since we already throw `PasswordException` when no password is provided.
2025-03-13 11:58:13 +01:00
Jonas Jenwald
cc63ffa6bb Reduce duplication when checking the userPassword, in CipherTransformFactory.prototype.#prepareKeyData
Currently we duplicate the exact same code in both the `if`- and `else`-branches, which seems unnecessary, and we can also replace the manual loop.
2025-03-13 11:58:02 +01:00
Jonas Jenwald
2ff6829e47 Introduce a common base class for the PDF17 and PDF20 crypto classes
With the exception of a different hashing function these classes are identical, and the base class thus help reduce code duplication.

This patch reduces the size of the `gulp mozcentral` build with 1344 bytes, which isn't a lot but still cannot hurt.
2025-03-12 12:25:55 +01:00
Jonas Jenwald
67065e43f5 Replace loops with TypedArray.prototype.set in the CipherTransformFactory class
Also, adds `TypedArray.prototype.fill` usage in one spot.
2025-03-08 16:17:45 +01:00
Jonas Jenwald
c65f1b0dae Move a couple of AESBaseCipher fields from the constructors
Thanks to modern JS class features we can, ever so slightly, shorten some class field definitions.
2025-03-08 16:06:30 +01:00
Jonas Jenwald
461488cb16 Initialize the defaultPasswordBytes, in CipherTransformFactory, lazily 2025-03-08 16:06:30 +01:00
Jonas Jenwald
facf34606f Move the calculateSHA384 and calculateSHA512 functions into their own file
This allows us to remove a closure, and we also change the code to initialize various constants lazily.
2025-03-08 15:56:22 +01:00
Jonas Jenwald
a1eac86037 Move the calculateSHA256 function into its own file
This allows us to remove a closure, and we also change the code to initialize various constants lazily.
2025-03-08 15:56:16 +01:00
Jonas Jenwald
3e8d01ad7c Move the calculateMD5 function into its own file
This allows us to remove a closure, and we also change the code to initialize various constants lazily.
2025-03-08 15:56:05 +01:00
Ross Johnson
4f25d7f6cd Fix decryption of R=4, V=4 files with < 16-byte keys by 0-padding - undocumented but matches Acrobat behavior (issue #19484) 2025-02-24 15:36:37 -06:00
Jonas Jenwald
a722ca4de5 Shorten the CipherTransformFactory.prototype.#buildObjectKey method
- Use `TypedArray.prototype.set()` rather than a manual loop when building the `key`.

 - Use an existing local variable to avoid re-computing the length of the `encryptionKey`.
2025-02-15 13:00:42 +01:00
Jonas Jenwald
7919f4e84f Use crypto.getRandomValues unconditionally in the src/core/crypto.js file
This functionality is now available in all browsers/environments that we support, please see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#browser_compatibility
2025-02-09 11:42:17 +01:00
Jonas Jenwald
aebb8534f3 Limit base-class initialization checks to development and TESTING modes
We have a number of base-classes that are only intended to be extended, but never to be used directly. To help enforce this during development these base-class constructors will check for direct usage, however that code is obviously not needed in the actual builds.

*Note:* This patch reduces the size of the `gulp mozcentral` output by `~2.7` kilo-bytes, which isn't a lot but still cannot hurt.
2024-08-12 12:26:35 +02:00
Jonas Jenwald
0304b65fcd Remove the closure from the CipherTransformFactory class
Now that modern JavaScript is fully supported also in the worker-thread we no longer need to keep old closures, which slightly reduces the size of the code.
2023-09-16 16:34:24 +02:00
Jonas Jenwald
c0fe96b8fe Additional *manual* unicorn/prefer-ternary changes
Not all cases could be automatically fixed, and the changes also triggered a number of `prefer-const` errors that needed to be handled manually.
2023-07-27 09:48:24 +02:00
Jonas Jenwald
674e7ee381 Enable the unicorn/prefer-ternary ESLint plugin rule
To limit the readability impact of these changes, the `only-single-line` option was used; please find additional details at https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-ternary.md

These changes were done automatically, using the `gulp lint --fix` command.
2023-07-27 09:18:26 +02:00
Jonas Jenwald
fee850737b Enable the unicorn/prefer-optional-catch-binding ESLint plugin rule
According to MDN this format is available in all browsers/environments that we currently support, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch#browser_compatibility

Please also see https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-optional-catch-binding.md
2023-06-12 11:46:11 +02:00
Jonas Jenwald
1b4a7c5965 Introduce more optional chaining in the src/core/ folder
After PR 12563 we're now free to use optional chaining in the worker-thread as well. (This patch also fixes one previously "missed" case in the `web/` folder.)

For the MOZCENTRAL build-target this patch reduces the total bundle-size by `1.6` kilobytes.
2023-05-15 12:38:28 +02:00
Jonas Jenwald
e12535457f Avoid some repeated stringToBytes-calls in the src/core/crypto.js file
Currently we repeatedly lookup, and convert to bytes, the "O" and "U" encryption-dictionary entries.
2023-04-26 17:52:46 +02:00
Jonas Jenwald
74585c7c59 Remove the unused PDF20.hash method
This method was added in PR 4938, almost nine years ago, however it doesn't appear to ever have been used.
Given the similarities between the `PDF17` and `PDF20` classes, and how they're used, if the `PDF20.hash` method was actually necessary you'd also expect a similiar method in the `PDF17` class.
2023-04-23 10:13:46 +02:00
Jonas Jenwald
5e0722e4c2 Remove the PDF20 closure, in the src/core/crypto.js file
To allow doing this the existing helper function was changed into a "private" method instead.
2023-04-23 10:08:17 +02:00
Calixte Denizet
c0e165bf97 Simplify the way to compute the remainder modulo 3 in PDF20Hash function
I noticed the 256 % 3 (which is equal to 1) so I slighty simplify the code.
The sum of the 16 Uint8 doesn't exceed 2^12, hence we can just take the
sum modulo 3.
2022-10-07 14:43:31 +02:00
Calixte Denizet
d092a85b6c Fix wrong order of arguments when calling the CipherTransform ctor (bug 1782186) 2022-07-29 12:46:45 +02:00
Jonas Jenwald
9ac4536693 Enable the unicorn/prefer-at ESLint plugin rule (PR 15008 follow-up)
Please find additional information here:
 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at
 - https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-at.md
2022-06-09 21:21:19 +02:00
Jonas Jenwald
b282814e38 Prefer instanceof Name rather than calling isName() with one argument
Unless you actually need to check that something is both a `Name` and also of the *correct* type, using `instanceof Name` directly should be a tiny bit more efficient since it avoids one function call and an unnecessary `undefined` check.

This patch uses ESLint to enforce this, since we obviously still want to keep the `isName` helper function for where it makes sense.
2022-02-21 12:45:00 +01:00
Jonas Jenwald
4df82ad31e Prefer instanceof Dict rather than calling isDict() with one argument
Unless you actually need to check that something is both a `Dict` and also of the *correct* type, using `instanceof Dict` directly should be a tiny bit more efficient since it avoids one function call and an unnecessary `undefined` check.

This patch uses ESLint to enforce this, since we obviously still want to keep the `isDict` helper function for where it makes sense.
2022-02-21 12:44:56 +01:00
Jane-Kotovich
91fc643ff9 [api-minor] Implement securityHandler in the scripting API (bug 1731578) 2021-10-26 23:42:04 +10:00
Calixte Denizet
9619bf92be Correctly pad strings when saving an encrypted pdf (bug 1726789) 2021-09-02 10:37:21 +02:00
Jonas Jenwald
901b24e8af Enable the ESLint operator-assignment rule
This patch was generated automatically, using the `gulp lint --fix` command.

Please find additional details about the ESLint rule at https://eslint.org/docs/rules/operator-assignment
2021-07-04 12:57:45 +02:00
Jonas Jenwald
1a8d05fdcf Remove some, with Prettier 2.3.0, unnecessary // prettier-ignore comments
To get the maximum benefit from something like Prettier, you obviously don't want to disable the automatic formatting unless absolutely necessary. When we added Prettier there were a number of cases, mostly involving larger Arrays, which required disabling of the automatic formatting for overall readability and/or to not break inline comments.

With changes in Prettier version `2.3.0`, see [the release notes](https://prettier.io/blog/2021/05/09/2.3.0.html#concise-formatting-of-number-only-arrays-10106httpsgithubcomprettierprettierpull10106-10160httpsgithubcomprettierprettierpull10160-by-thorn0httpsgithubcomthorn0), there's now better formatting support for Arrays containing only numbers. Hence we can now remove a number of `// prettier-ignore` comments, and thus get the benefit of automatic formatting in (slightly) more of the code-base.
2021-05-19 11:36:03 +02:00
Tim van der Meij
b661cf2b80
Fix no-var linting rule violations in src/core/crypto.js that couldn't be changed automatically by ESLint
This is done in a separate commit due to the required number of changes
so that reviewing is easier than in a plain-text diff in the commit
message.
2021-05-02 13:32:34 +02:00
Tim van der Meij
1f8b452354
Enable the no-var linting rule in src/core/crypto.js
This is done automatically with `gulp lint --fix`.
2021-05-01 20:34:35 +02:00
Jonas Jenwald
28b0809e60 Move the DecryptStream from src/core/stream.js and into its own file 2021-04-28 10:16:51 +02:00
Jonas Jenwald
6b4c4f80e4 Convert code in src/core/crypto.js to use "normal" classes
All of this code predates the existence of native JS classes, however we can now clean this up a bit. This patch thus let us remove some variable "shadowing" from the code.
2021-02-26 15:51:45 +01:00
Jonas Jenwald
b884757873 Inline the concatArrays function in calculatePDF20Hash
This helper function is first of all only called *twice*, and secondly it also leads to unnecessary intermediate allocations given how the `TypedArray`s are handled.
Hence we can simply inline this small function, and thus directly allocate the combined `TypedArray` instead.
2021-02-26 15:51:39 +01:00
Jonas Jenwald
9a9a5b2365 Replace the compareByteArrays functions, in src/core/crypto.js, with the isArrayEqual helper function
The `compareByteArrays` is first of all duplicated in multiple closures in the `src/core/crypto.js` file. Secondly, despite its name, it's also functionally equivalent to the now existing `isArrayEqual` helper function.

The `isArrayEqual` helper function is changed to use a standard `for`-loop, rather than `Array.prototype.every`, since that ought to be slightly more efficient given that we're now using it with (potentially) larger data.
2021-02-26 15:51:32 +01:00
Jonas Jenwald
81525fd446 Use ESLint to ensure that exports are sorted alphabetically
There's built-in ESLint rule, see `sort-imports`, to ensure that all `import`-statements are sorted alphabetically, since that often helps with readability.
Unfortunately there's no corresponding rule to sort `export`-statements alphabetically, however there's an ESLint plugin which does this; please see https://www.npmjs.com/package/eslint-plugin-sort-exports

The only downside here is that it's not automatically fixable, but the re-ordering is a one-time "cost" and the plugin will help maintain a *consistent* ordering of `export`-statements in the future.
*Note:* To reduce the possibility of introducing any errors here, the re-ordering was done by simply selecting the relevant lines and then using the built-in sort-functionality of my editor.
2021-01-09 20:37:51 +01:00
Jonas Jenwald
9416b14e8b Re-factor how the ESLint no-var rule is enabled in the src/ folder
This simplifies/consolidates the ESLint configuration slightly in the `src/` folder, and prevents the addition of any new files where `var` is being used.[1]
Hence we no longer need to manually add `/* eslint no-var: error */` in files, which is easy to forget, and can instead disable the rule in the `src/core/` files where `var` is still in use.

---
[1] Obviously the `no-var` rule can, in the same way as every other rule, be disabled on a case-by-case basis where actually necessary.
2020-10-03 20:15:29 +02:00
Calixte Denizet
1a6816ba98 Add support for saving forms 2020-08-12 10:32:59 +02:00
Jonas Jenwald
dcb16af968 Whitelist closure related cases to address the remaining no-shadow linting errors
Given the way that "classes" were previously implemented in PDF.js, using regular functions and closures, there's a fair number of false positives when the `no-shadow` ESLint rule was enabled.

Note that while *some* of these `eslint-disable` statements can be removed if/when the relevant code is converted to proper `class`es, we'll probably never be able to get rid of all of them given our naming/coding conventions (however I don't really see this being a problem).
2020-03-25 11:57:12 +01:00
Jonas Jenwald
83bdb525a4 Fix remaining linting errors, from enabling the prefer-const ESLint rule globally
This covers cases that the `--fix` command couldn't deal with, and in a few cases (notably `src/core/jbig2.js`) the code was changed to use block-scoped variables instead.
2020-01-25 00:20:23 +01:00
Jonas Jenwald
9e262ae7fa Enable the ESLint prefer-const rule globally (PR 11450 follow-up)
Please find additional details about the ESLint rule at https://eslint.org/docs/rules/prefer-const

With the recent introduction of Prettier this sort of mass enabling of ESLint rules becomes a lot easier, since the code will be automatically reformatted as necessary to account for e.g. changed line lengths.

Note that this patch is generated automatically, by using the ESLint `--fix` argument, and will thus require some additional clean-up (which is done separately).
2020-01-25 00:20:22 +01:00
Jonas Jenwald
36881e3770 Ensure that all import and require statements, in the entire code-base, have a .js file extension
In order to eventually get rid of SystemJS and start using native `import`s instead, we'll need to provide "complete" file identifiers since otherwise there'll be MIME type errors when attempting to use `import`.
2020-01-04 13:01:43 +01:00
Jonas Jenwald
de36b2aaba Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes).

Prettier is being used for a couple of reasons:

 - To be consistent with `mozilla-central`, where Prettier is already in use across the tree.

 - To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters.

Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some).
Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long.

*Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit.

(On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
2019-12-26 12:34:24 +01:00
Jonas Jenwald
8ec1dfde49 Add // prettier-ignore comments to prevent re-formatting of certain data structures
There's a fair number of (primarily) `Array`s/`TypedArray`s whose formatting we don't want disturb, since in many cases that would lead to the code becoming much more difficult to read and/or break existing inline comments.

*Please note:* It may be a good idea to look through these cases individually, and possibly re-write some of the them (especially the `String` ones) to reduce the need for all of these ignore commands.
2019-12-26 00:14:03 +01:00
Tim van der Meij
73436c0d12
Implement the AESBaseCipher class and let the AES128Cipher and AES256Cipher classes extend it 2018-02-03 20:16:33 +01:00
Tim van der Meij
9a959e4df7
Update the AES128Cipher and AES256Cipher implementations to be more similar
This commit is the first step for extracting a base class for the
`AES128Cipher` and the `AES256Cipher` classes. The objective here is to
make code changes (not altering the logic) to make the implementations
as similar as possible as found by creating a diff of both classes.

In particular, we extract the key size and cycles of repetitions
constants since they are different for AES-128 and AES-256. Moreover, we
rename functions to be similar.

In the `AES256Cipher` class, there was an additional assignment to
`this` in the decryption function. However, this was unnecessary because
the assignment would also be done when the loop was exited.
2018-02-03 20:16:29 +01:00
Max Schaefer
3ab1a9922a Rearrange a few declarations so that they precede their uses. 2017-11-03 10:14:32 +00:00
Jonas Jenwald
11408da340 Replace the isInt helper function with the native Number.isInteger function
*Follow-up to PR 8643.*
2017-09-01 16:52:50 +02:00