3855 Commits

Author SHA1 Message Date
Jonas Jenwald
63a0f285b8 Reduce a tiny bit of duplication in the normalizeBlendMode helper 2026-07-27 13:59:38 +02:00
Tim van der Meij
2ea8820d92
Merge pull request #21641 from calixteman/perf/pattern-color
Convert shading colors in bulk, rather than one at a time
2026-07-26 17:49:24 +02:00
calixteman
526b69651f
Convert shading colors in bulk, rather than one at a time
The axial/radial ramps and the function-based lattice converted one color per
call, i.e. one Wasm round-trip each for `IccColorSpace` (hence for
`/DeviceCMYK`). Add `ColorSpace.getRgbItems`, overridden by `IccColorSpace` and
`AlternateCS`, to convert a whole batch at once.
2026-07-26 17:02:22 +02:00
calixteman
a0f100c4a8
Convert the /Indexed palette in a single base color space call
`IndexedCS` invoked the base color space once per palette entry, which is
cheap for e.g. `DeviceRgbCS` but not for `IccColorSpace` where every call
is a Wasm round-trip.
2026-07-26 14:54:24 +02:00
Tim van der Meij
d246a6c495
Merge pull request #21630 from calixteman/fix/formInfo-inherited-document-signatures
Detect inherited signature fields in form info
2026-07-26 11:57:59 +02:00
Tim van der Meij
150fbba6e0
Merge pull request #21628 from calixteman/fix/pdf-editor-inherited-signature-flags
Preserve inherited signature flags
2026-07-26 11:56:38 +02:00
Jonas Jenwald
a7b7cec2e7 Re-factor the "nested trailer dictionary" check (PR 4731 follow-up)
In the `pr4731.pdf` document the trailer is actually a Stream, rather than the expected Dictionary, hence update the "nested trailer dictionary" check to make that clearer.

*Note:* This is something that I happened to noticed while working on the previous patch.
2026-07-25 12:18:45 +02:00
Jonas Jenwald
1ee8705093 Re-factor the XRef class to use private fields
Part of this is very old code, hence modernizing it a little bit more really shouldn't hurt.
This patch also shortens some `XRef` code by using nullish coalescing assignment respectively ternary operators more.

Finally, adds the recently introduced `countUpdatesAfter` method to the `XRefMock`/`XRefWrapper` classes to avoid having to check for its existence.
2026-07-25 12:18:43 +02:00
Calixte Denizet
ac75b10be1 Detect inherited signature fields in form info 2026-07-24 21:43:32 +02:00
Calixte Denizet
27cf9e24f3 Preserve inherited signature flags 2026-07-24 20:42:26 +02:00
Tim van der Meij
05e100c76e
Merge pull request #21626 from calixteman/fix/pdf-editor-inherited-default-appearance
Preserve inherited text field appearances
2026-07-24 20:35:14 +02:00
Calixte Denizet
a97939b0d7 Preserve inherited text field appearances 2026-07-24 18:58:01 +02:00
Jonas Jenwald
675e9219b5 Remove the objectSize helper function
Given that Maps are used a lot more these days, this helper function is now used very sparingly and inlining the necessary code seems reasonable.

*Note:* Once [this proposal](https://github.com/tc39/proposal-object-keys-length) makes it into Firefox, we should be able to simplify all `Object.keys(...).length` call-sites.
2026-07-24 12:49:44 +02:00
Tim van der Meij
47969a5953
Merge pull request #21620 from calixteman/improve_modif_detections
Improve the detection of the changes made after a document has been signed
2026-07-23 20:57:59 +02:00
Tim van der Meij
e58091a769
Merge pull request #21621 from Snuffleupagus/openAction-Map
[api-minor] Convert `getOpenAction` to return data in a Map
2026-07-23 20:57:42 +02:00
Jonas Jenwald
c474a97932 [api-minor] Convert getOpenAction to return data in a Map
Compared to regular Objects there's a number of advantages to using Maps:
 - They support proper iteration.
 - They have a simple way to check for the existence of data.
 - They have a simple/efficient way to check the number of elements.

If this functionality was added today, I cannot imagine that we'd choose an Object for this data.
2026-07-23 13:52:02 +02:00
Calixte Denizet
ed81227557 Improve the detection of the changes made after a document has been signed 2026-07-23 12:44:20 +02:00
Jonas Jenwald
27a8002f7e Improve the Ref.prototype.toString method a tiny bit
When getting/creating a new `Ref` instance, via the static `Ref.get` method, we already need to compute a cache-key.
Since this key is identical to the format used by the `toString` method, we can avoid having to re-create that string (a lot) by also providing it to the `Ref` constructor.
2026-07-22 13:27:26 +02:00
calixteman
0c8f67059e
Merge pull request #21616 from calixteman/fix/pdf-editor-indirect-default-resources
Preserve indirect AcroForm resources
2026-07-21 21:45:13 +02:00
Calixte Denizet
f0bbfa6f9e Preserve indirect AcroForm resources 2026-07-21 19:41:45 +02:00
Jonas Jenwald
69e26ad319 Re-use the NS_DATASETS constant more in the src/core/xfa/bind.js file 2026-07-21 16:04:24 +02:00
Jonas Jenwald
028c02f539
Merge pull request #21607 from Snuffleupagus/viewerPreferences-Map
[api-minor] Convert `getViewerPreferences` to return data in a Map
2026-07-20 22:14:55 +02:00
Jonas Jenwald
de3eecca11 [api-minor] Convert getViewerPreferences to return data in a Map
Compared to regular Objects there's a number of advantages to using Maps:
 - They support proper iteration.
 - They have a simple way to check for the existence of data.
 - They have a simple/efficient way to check the number of elements.

If this functionality was added today, I cannot imagine that we'd choose an Object for this data.
2026-07-20 16:52:36 +02:00
calixteman
09a45ad2af
Merge pull request #21601 from uwezkhan/fix-postscript-wasm-i32const-sleb128
Encode i32.const immediates as signed LEB128 in the PostScript Wasm compiler
2026-07-20 15:29:20 +02:00
uwezkhan
778aa450d9 Encode i32.const immediates as signed LEB128 in the PostScript Wasm compiler
The Type-4 PostScript -> Wasm compiler emitted i32.const immediates with the
unsigned LEB128 encoder (_emitULEB128). Wasm decodes i32.const as a *signed*
LEB128, so any immediate whose final 7-bit group has bit 0x40 set is
mis-decoded (e.g. 64 -> single byte 0x40 -> read back as -64).

The output-store address for the i-th result is emitted as i32.const (i*8).
For a function with >= 9 outputs the 9th offset is 64, which decodes as -64, so
f64.store targets 0xFFFFFFC0 and traps (memory access out of bounds). The module
still validates and instantiates, so the JS fallback in function.js is not
engaged; the trap only surfaces at render time (the affected shading / tint
transform silently fails to render). The same mis-encoding affects the constant
bitshift amount.

Add a signed-LEB128 emitter (_emitSLEB128) and use it for the three i32.const
immediate sites; local/import/type indices remain unsigned (correct). Add a unit
test covering functions with 9+ outputs, and a reference test rendering a shading
whose colour function has 9 outputs.
2026-07-20 14:56:04 +05:30
Jonas Jenwald
ee56dc7719 Ignore Annotations with fieldValue = null when saving (issue 21582)
Some Annotations, e.g. `SignatureWidgetAnnotation`, set `fieldValue = null` which may causing saving to fail during `writeXFADataForAcroform`, hence we simply ignore any such Annotation-data during saving.
2026-07-19 23:00:31 +02:00
Jonas Jenwald
02027ba381 Combine the getPathJs and hasBuiltPath methods in the CompiledFont class
This avoids duplicating the charCode/glyphId lookup, and (slightly) shortens the code. In particular:
 - Given that the path-data is returned as a TypedArray, it's easy enough to instead return `null` to indicate that the glyph was previously compiled.

 - The charCode-cache can be changed into a Set, since we only need to track the "seen" charCodes and not their relation to the glyphIds.

 - The `compileFontPathInfo` call is moved into `CompiledFont` class, since that simplifies the `src/core/evaluator.js` code a tiny bit.
2026-07-19 16:48:07 +02:00
Jonas Jenwald
eddd70a2ca
Merge pull request #21597 from Snuffleupagus/destinations-Map
[api-minor] Convert `getDestinations` to return data in a Map
2026-07-19 16:06:12 +02:00
Tim van der Meij
b83274803c
Merge pull request #21588 from calixteman/fix/pdf-editor-struct-attribute-revisions
Handle revisioned structure attributes
2026-07-19 14:11:08 +02:00
Tim van der Meij
fd77b3ea9f
Merge pull request #21591 from calixteman/fix/pdf-editor-missing-acroform-fields
Rebuild missing AcroForm fields
2026-07-19 14:08:40 +02:00
Tim van der Meij
4f7f3baed4
Merge pull request #21587 from calixteman/smask_in_data
Implement SmaskInData == 2 for JPX images
2026-07-19 13:57:41 +02:00
Tim van der Meij
8c3941a0d5
Merge pull request #21595 from Snuffleupagus/CompiledFont-Maps
Change the `CompiledFont` glyph/charCode caches to use `Map`s
2026-07-19 13:53:12 +02:00
Tim van der Meij
0a3ed983be
Merge pull request #21596 from Snuffleupagus/pattern-bCache-Map
Re-factor the `bCache`, used with /Mesh Shadings
2026-07-19 13:50:44 +02:00
Tim van der Meij
be89d6475d
Merge pull request #21585 from Snuffleupagus/Iterator-join
Start using `Iterator.prototype.join` in the code-base
2026-07-19 13:48:06 +02:00
Jonas Jenwald
6fbd2227db [api-minor] Convert getDestinations to return data in a Map
Compared to regular Objects there's a number of advantages to using Maps:
 - They support proper iteration.
 - They have a simple way to check for the existence of data.
 - They have a simple/efficient way to check the number of elements.

If this functionality was added today, I cannot imagine that we'd choose an Object for this data.
2026-07-19 12:07:08 +02:00
Jonas Jenwald
344736bcad Re-factor the bCache, used with /Mesh Shadings
- Initialize the `bCache` lazily, since many/most PDF documents don't need it.
 - Change the `bCache` to a `Map`, rather than an Object, which thanks to `getOrInsertComputed` allows the `buildB` function to be inlined.

Also, while unrelated here, move the `this.matrix = null;` definition to the `BaseShadingPattern` class to reduce (a tiny bit of) unnecessary duplication.
2026-07-18 14:15:24 +02:00
Jonas Jenwald
b2cf8527c6 Change the CompiledFont glyph/charCode caches to use Maps
This code is old enough that it predates the general availability of `Map`, and these changes allow us to shorten the code a tiny bit.
2026-07-18 11:44:27 +02:00
Jonas Jenwald
47f2b22842 Use Iterator methods to avoid some unnecessary Array creation
Currently there are some spots in the code-base where intermediate Arrays are unnecessarily created from Iterators, before `filter` and `map` is used to create a final Array.
Thanks to newer Iterators methods, see e.g. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/filter, that can be now be avoided.
2026-07-17 21:23:08 +02:00
Calixte Denizet
922d57631b Rebuild missing AcroForm fields 2026-07-17 13:51:08 +02:00
Calixte Denizet
eb58ccc100 Handle revisioned structure attributes 2026-07-16 22:18:26 +02:00
Calixte Denizet
f554d0c9c8 Implement SmaskInData == 2 for JPX images 2026-07-16 21:04:45 +02:00
Jonas Jenwald
9a7335d26b Start using Iterator.prototype.join in the code-base
This is an upcoming JavaScript feature, which helps avoid creating intermediate Arrays in some cases; see https://github.com/tc39/proposal-iterator-join

Firefox implemented this in [bug 2004803](https://bugzilla.mozilla.org/show_bug.cgi?id=2004803), and it was enabled by default in [bug 2047995](https://bugzilla.mozilla.org/show_bug.cgi?id=2047995).

This patch changes two Objects to Maps, in the XFA-parsing respectively the find-implementation, to make use of the new feature.
2026-07-16 20:45:01 +02:00
Tim van der Meij
d473678201
Merge pull request #21577 from calixteman/fix/pdf-editor-acroform-resource-xref
Fix AcroForm appearance resources when merging pages
2026-07-16 20:13:44 +02:00
Tim van der Meij
f472cb081c
Merge pull request #21575 from calixteman/fix/signature-fields-with-widget-kids
Fix signature fields with widget children
2026-07-16 20:08:35 +02:00
calixteman
6e18a52b86
Merge pull request #21583 from calixteman/sasl_prep
Support SASLprep for AES-256 revision 6 passwords
2026-07-16 19:21:39 +02:00
Jonas Jenwald
244fb9e822
Merge pull request #21581 from Snuffleupagus/createCipherTransform-rm-AES256Cipher-duplication
Reduce duplication in `CipherTransformFactory.prototype.createCipherTransform`
2026-07-16 17:03:26 +02:00
Calixte Denizet
2ea9c26d77 Support SASLprep for AES-256 revision 6 passwords 2026-07-16 16:58:58 +02:00
Calixte Denizet
5f09f797ab Fix decryption of AES-256 revision 5 PDFs with non-ASCII passwords
It fixes #21579.
2026-07-16 16:34:15 +02:00
Jonas Jenwald
01454570a7 Reduce duplication in CipherTransformFactory.prototype.createCipherTransform
After PR 21485 the `AES256Cipher` case is effectively duplicated, and while it's not a lot of code it's easy enough to avoid that.
2026-07-16 15:31:36 +02:00
Calixte Denizet
914545dea3 Fix AcroForm appearance resources when merging pages
Merging pages with conflicting AcroForm /DR must inline the resources
each field's appearance relies on, since only one /DR survives in the
output. That fixup:
- resolved the appearance /Resources ref against the source document's
  xref instead of the merged one, so the lookup failed and merging threw
  (null.has(...));
- skipped checkbox/radio widgets, whose /AP /N is a sub-dictionary of
  appearance states rather than a single stream;
- threw on a non-dictionary /Resources (e.g. a stray name) instead of
  falling back to the default resources.
2026-07-15 16:56:04 +02:00