4882 Commits

Author SHA1 Message Date
calixteman
f21fe34747
Safely serialize CSS font family names 2026-08-03 18:02:10 +02:00
calixteman
ba7bf7b26c
Merge pull request #21683 from calixteman/fix/quad-regex-writer
Don't write numbers in exponential notation when saving a pdf
2026-08-03 17:49:23 +02:00
calixteman
1da36fb6bf
Merge pull request #21686 from calixteman/fix/quad-regex-xfa-path
Anchor the regex used to extract the XFA path positions
2026-08-03 17:46:24 +02:00
calixteman
92d027eaeb
Anchor the regex used to extract the XFA path positions
Matching the name with a leading `.+` is quadratic in the length of
a component which doesn't end with a position, and every AcroForm
field name goes through this.
2026-08-03 17:07:48 +02:00
calixteman
5375bff642
Don't write numbers in exponential notation when saving a pdf
`toFixed(10)` switches to the exponential notation from 1e21 on, which isn't
valid PDF syntax, and removing the trailing zeros then dropped a digit of the
exponent: 1e30 was written "1e+3" and 1e100 "1e+1". Such a number, necessarily
an integer, is now written with all its digits.

The trailing zeros are removed with a backward scan, since `toFixed(10)` always
produces exactly 10 decimals. Below the 1e21 limit its output is at most 33
characters long, so the previous `$`-anchored regex wasn't a performance issue.
2026-08-03 16:59:12 +02:00
Tim van der Meij
ae976b924b
Merge pull request #21671 from Snuffleupagus/getFieldObjects-Map
[api-minor] Convert `getFieldObjects` to return data in a Map
2026-08-02 22:37:22 +02:00
Tim van der Meij
ec691130e6
Merge pull request #21692 from calixteman/fix/quad-regex-xml-entities
Exclude "&" from the XML entity names
2026-08-02 22:24:11 +02:00
Jonas Jenwald
82624a5e50 [api-minor] Convert getFieldObjects 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.

In the Firefox PDF Viewer sending Maps to the scripting-implementation should be fine, since it uses the browser `Cu.cloneInto` functionality; see https://searchfox.org/firefox-main/source/toolkit/components/pdfjs/content/PdfSandbox.sys.mjs
However with QuickJS, used by the GENERIC viewer, all data needs to be stringified and Maps are converted into regular Objects (see also PR 21664). Hence the `objects` property, in the scripting-implementation, is converted back into a Map using the (renamed) `createMap` helper function.
2026-08-02 21:27:07 +02:00
Jonas Jenwald
1f9fbc764e Add scripts correctly in Field.prototype.setAction (PR 12569 follow-up)
In PR 12569 the `_actions` class-field was changed from an Object into a Map, with *most* of the code updated to reflect that.
However, in the `setAction` method it's still treated as an Object which means that any added script will simply be ignored. Most likely that part of the scripting-implementation isn't being used, since this code has been "wrong" for close to six years now.
2026-08-02 20:31:15 +02:00
calixteman
f7f30dd844
Exclude "&" from the XML entity names
Scanning to the end of the string for every "&" made the entity
resolution quadratic. Stopping at the next "&" also fixes a bare
ampersand swallowing the reference which follows it.
2026-08-02 18:59:19 +02:00
Tim van der Meij
d0779c411e
Merge pull request #21687 from calixteman/fix/quad-regex-delete-word
Scan backwards to delete a word in a text field
2026-08-02 13:04:00 +02:00
Tim van der Meij
89852881b8
Merge pull request #21685 from calixteman/fix/quad-regex-pdf-filename
Find the PDF filename in a URL hash in two linear steps
2026-08-02 12:57:49 +02:00
Tim van der Meij
eb8f6af8cc
Merge pull request #21684 from calixteman/fix/quad-regex-headers
Trim the response headers with a backward scan
2026-08-02 12:46:03 +02:00
Tim van der Meij
f73978083d
Merge pull request #21680 from calixteman/fix/quad-regex
Fix the regex used to normalize css fonts in XFA
2026-08-02 12:43:14 +02:00
calixteman
08f6769390
Scan backwards to delete a word in a text field
Finding the word to delete with a regex is quadratic in the value
length, so each "delete word backward" keystroke could take a long
time in a large field.
2026-08-01 22:13:27 +02:00
calixteman
7862875438
Find the PDF filename in a URL hash in two linear steps
Searching for a name followed by ".pdf" is quadratic on a hash which
doesn't contain one, so locate the last ".pdf" first and then extend
it to the left.
2026-08-01 21:17:43 +02:00
calixteman
cba911df86
Trim the response headers with a backward scan
Removing the trailing whitespace with a `$`-anchored regex is
quadratic in the length of the run, which a server controls.
The helper lives in network_utils.js, to be unit testable.
2026-08-01 20:56:01 +02:00
calixteman
cec8d2eed6
Don't throw on an invalid XML character reference
`String.fromCodePoint` throws on anything which isn't a code point,
so e.g. "&#xZZ;" or "�" aborted the whole parsing. Such a
reference is now kept as-is, like an unknown named entity.
2026-08-01 16:24:03 +02:00
calixteman
491792f0e2
Fix the regex used to normalize css fonts in XFA
The regex was quadratic in the number of consecutive spaces,
which caused performance issues when normalizing fonts with
a large number of spaces.
2026-08-01 15:11:43 +02:00
Tim van der Meij
7fc7072f9c
Merge pull request #21674 from calixteman/touch/fix-swallowed-pointerup
Let pointerup/cancel propagate in TouchManager
2026-07-31 20:16:07 +02:00
Tim van der Meij
bb1a948397
Merge pull request #21672 from Snuffleupagus/more-ternary
Replace simple return `if` statements with ternary operators
2026-07-31 19:59:46 +02:00
calixteman
0f999e27b5 Let pointerup/cancel propagate in TouchManager
During two-finger gestures, keep preventing the default action on pointerup/pointercancel, but don't stop propagation. Resize/drag sessions need those bubble events to clean up.
2026-07-31 19:26:53 +02:00
calixteman
af38789499
Merge pull request #21659 from calixteman/fix/pinch-zoom-origin
Use the client coordinates for the pinch-zoom origin
2026-07-31 18:00:52 +02:00
Calixte Denizet
8960eddfc1 Use the client coordinates for the pinch-zoom origin
`TouchManager` computes the pinch distances with the screen coordinates, but it
was passing the pinch center in that space too, while the viewer expects a
client coordinate, like the origin coming from a wheel event.

Since a two-finger gesture can be synthesized with WebDriver BiDi, the
pinch-zoom test doesn't have to rely on CDP anymore and can run in Chrome, where
it fails without the above fix.
2026-07-31 16:44:28 +02:00
Jonas Jenwald
ee59db5018 Replace simple return if statements with ternary operators
In a couple of cases, where a boolean is returned, it's also possible to use an OR operator rather a ternary.

*Note:* This patch reduces the size of the `gulp mozcentral` bundle by `960` bytes.
2026-07-31 12:24:08 +02:00
Jonas Jenwald
ce4ff55faa
Merge pull request #21664 from Snuffleupagus/getJSActions-api
[api-minor] Convert `getJSActions` to return data in a Map
2026-07-31 11:29:21 +02:00
Tim van der Meij
a80897dc9a
Merge pull request #21666 from calixteman/bug2054348
Fix the selection rendering when a page has been destroyed and rendered again (bug 2054348)
2026-07-30 21:12:47 +02:00
Tim van der Meij
0163438e1a
Merge pull request #21660 from calixteman/fix/pdf-editor-preserve-widget-parent
Avoid mutating source widget parents
2026-07-30 21:02:29 +02:00
Tim van der Meij
f70f55d743
Merge pull request #21658 from calixteman/fix/pdf-editor-clone-reference-race
Avoid duplicate shared object clones
2026-07-30 20:52:35 +02:00
Calixte Denizet
9e02ceed09 Fix the selection rendering when a page has been destroyed and rendered again (bug 2054348)
The draw layer keeps a reference on the text layer div in order to render the
selection, but it was destroyed only along with the annotation editor layer.
Hence, when the editor is disabled, like in Firefox for Android, scrolling far
enough to destroy a page view left the draw layer with a reference on a removed
text layer: the new one was never registered, consequently no selection was
rendered anymore on that page.
2026-07-30 18:37:03 +02:00
Jonas Jenwald
803c9d7d21 [api-minor] Convert getJSActions 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.

Note also how in the scripting-implementation the `actions` were already converted into a Map, via the `createActionsMap` helper.
In the Firefox PDF Viewer sending `Map`s to the scripting-implementation should be fine, since it uses the browser `Cu.cloneInto` functionality; see https://searchfox.org/firefox-main/source/toolkit/components/pdfjs/content/PdfSandbox.sys.mjs
However with QuickJS, used by the GENERIC viewer, all data needs to be stringified and unfortunately `JSON.stringify()` doesn't support Maps. Hence we convert Maps to Objects, via a [`replacer` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#replacer), since the existing `createActionsMap` usage will convert the actions-Objects back to Maps.
2026-07-30 16:04:58 +02:00
Calixte Denizet
aa812b531a Avoid mutating source widget parents 2026-07-29 16:03:15 +02:00
calixteman
822d3ea809 [Editor] Restore pinch-to-resize on an editor which came back from an undo
`AnnotationEditor.remove()` destroys the editor's `TouchManager`, but `remove()`
is also the undo half of an edit: deleting a drawing and undoing it, or undoing
the drawing itself and redoing it, brings the very same editor back.
2026-07-29 14:45:02 +02:00
Calixte Denizet
3a19a20d50 Avoid duplicate shared object clones 2026-07-28 22:39:35 +02:00
Tim van der Meij
0365cbde02
Merge pull request #21654 from calixteman/fix/cycles
Avoid cycles when walking some trees
2026-07-28 21:34:49 +02:00
Calixte Denizet
ac51b29777 Avoid cycles when walking some trees 2026-07-28 19:51:34 +02:00
Jonas Jenwald
f38e8b659e Update the signatures-helpers to actually handle MissingDataExceptions
The `PDFDocument.prototype.signatures` getter returns a (shadowed) Promise, however the way that it invokes various helper-methods can lead to *intermittent* failures to parse the signature data.
These helper-methods will lookup a fair amount of Dictionary data, however any one of those cases could throw `MissingDataException` during document loading.

To avoid having to re-factor those methods a lot, and adding a bunch more `pdfManager.ensureDoc()` calls, they are instead made asynchronous and the Dictionary lookups changed to use `Dict.prototype.getAsync` (similar to the existing `fieldObjects` handling).
Technically this additional asynchronicity may be ever so slightly slower, however I don't think it matters in practice since: most PDFs don't have any signatures, the signature-UI is initialized lazily in the viewer, and finally fetching/parsing of signatures do not block rendering.
Also, note how multiple values are being fetched in parallel in order to attempt to reduce overall asynchronicity.

*Note:* The unit-test changes are essentially fixing pre-existing bugs, that this patch exposed, since the test-only `Dict` instances weren't able to fetch indirect objects.
2026-07-28 16:17:52 +02:00
calixteman
1609bd87c5
Merge commit from fork
Harden the XFA layer and restrict scripting updates to known fields
2026-07-27 19:38: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
f38ea2d4cc
Merge pull request #21629 from calixteman/notification_bar
Add the Firefox features notification bar to the viewer (bug 2057608)
2026-07-26 14:24:22 +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
62d211ee8d Use the toBeTrue() matcher consistently in the unit/font/integration tests
This replaces all `toEqual(true)` and `toBe(true)` occurrences.
2026-07-25 23:52:28 +02:00
Jonas Jenwald
6963b0ef4f Use the toBeFalse() matcher consistently in the unit/integration tests
This replaces all `toEqual(false)` and `toBe(false)` occurrences.
2026-07-25 22:49:03 +02:00
Jonas Jenwald
b75ca17e85
Merge pull request #21636 from Snuffleupagus/test-toThrowError
Use the `toThrowError()` matcher consistently in the unit tests
2026-07-25 22:34:59 +02:00
Jonas Jenwald
dd41cd487d
Merge pull request #21633 from Snuffleupagus/test-toBeUndefined
Use the `toBeUndefined()` matcher consistently in the unit tests
2026-07-25 22:34:29 +02:00
Jonas Jenwald
503632a382
Merge pull request #21632 from Snuffleupagus/test-toBeNull
Use the `toBeNull()` matcher consistently in the unit/integration tests
2026-07-25 22:34:00 +02:00
Jonas Jenwald
432d5c57a4 Use the toThrowError() matcher consistently in the unit tests
Currently we mostly use `toThrow()`, which seems intended for things that throw non-Errors (something that we "forbid" with ESLint).
Hence `toThrowError()` seems more appropriate, and it also simplifies things slightly; see https://jasmine.github.io/api/edge/matchers.html#toThrowError
2026-07-25 14:30:55 +02:00
Jonas Jenwald
a9672298fc Use the toBeUndefined() matcher consistently in the unit tests
This replaces all `toEqual(undefined)` and `toBe(undefined)` occurrences.
2026-07-25 13:30:13 +02:00
Jonas Jenwald
60340d9f28 Use the toBeNull() matcher consistently in the unit/integration tests
This replaces all `toEqual(null)` and `toBe(null)` occurrences.
2026-07-25 12:58:43 +02:00