Compare commits

..

79 Commits

Author SHA1 Message Date
ad0p
f887fa45df chore: cherry-pick 6b4af5d82083 from chromium (#36447)
* chore: cherry-pick 6b4af5d82083 from chromium

* chore: cherry-pick 6b4af5d82083 from chromium

Co-authored-by: Adam Prasil <adamprasil@microsoft.com>
2022-11-28 07:30:00 -08:00
trop[bot]
de3776f580 chore: cherry-pick ecad352cd614 from chromium (#35053)
* chore: cherry-pick ecad352cd614 from chromium (#34689)

* Update .patches

* resolve conflicts

Co-authored-by: Jeremy Rose <jeremya@chromium.org>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2022-11-28 07:29:17 -08:00
trop[bot]
165d5a2547 build: remove out cache (#36360)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2022-11-15 16:17:59 -05:00
trop[bot]
bd67fd8814 build: make src cache smaller (#36350)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2022-11-15 12:04:03 -05:00
Samuel Attard
0eef6897cd build: provide moduleVersion to docs-parser directly (#36340)
build: provide moduleVersion to docs-parser directly (#36329)
2022-11-14 21:53:20 +01:00
Pedro Pontes
4450b7bc23 chore: cherry-pick 2ac0620a5bbb from v8 (#36295)
* chore: [19-x-y] cherry-pick 2ac0620a5bbb from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-14 00:15:40 -08:00
Milan Burda
bd5166a85d fix: crash-on-close for Mac UDP sockets (#36318)
Backport: https://chromium-review.googlesource.com/c/chromium/src/+/3682001

Co-authored-by: Milan Burda <miburda@microsoft.com>
2022-11-13 23:46:08 -08:00
Pedro Pontes
23c0c7af5b chore: cherry-pick 81cb17c24788 from chromium (#36312)
* chore: cherry-pick 81cb17c24788 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-10 20:06:56 -05:00
Pedro Pontes
eda34ceb2e chore: cherry-pick 1894458e04a2 from chromium (#36301)
* chore: [19-x-y] cherry-pick 1894458e04a2 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-11-10 20:04:08 -05:00
Pedro Pontes
d4a9ee7e43 chore: cherry-pick a1cbf05b4163 from chromium (#36297)
* chore: [19-x-y] cherry-pick a1cbf05b4163 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2022-11-10 12:14:06 -05:00
Pedro Pontes
bac4d3469d chore: cherry-pick 80ed4b917477 from v8 (#36299)
* chore: [19-x-y] cherry-pick 80ed4b917477 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-10 16:44:26 +01:00
Pedro Pontes
9b2d260c12 chore: cherry-pick ac4785387fff from chromium (#36305)
* chore: cherry-pick ac4785387fff from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-10 15:47:22 +01:00
Milan Burda
7ede4aeaf1 fix: crash in AXNodeObject::TextFromDescendants() (#36285)
Backport:
- https://chromium-review.googlesource.com/c/chromium/src/+/3633568
- https://chromium-review.googlesource.com/c/chromium/src/+/3657488

Co-authored-by: Milan Burda <miburda@microsoft.com>
2022-11-09 17:08:22 -05:00
Pedro Pontes
3d8827fb9d revert: cherry-pick eef098d1c7d5 from webrtc (#36262)
Revert "chore: cherry-pick eef098d1c7d5 from webrtc (#36218)"

This reverts commit 7e5adf5e56.
2022-11-08 11:26:37 +01:00
Pedro Pontes
2331e9192c chore: cherry-pick ec236fef54b8 from v8 (#36225)
* chore: [19-x-y] cherry-pick ec236fef54b8 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-03 09:54:12 -04:00
Pedro Pontes
87b0a0d984 chore: cherry-pick 933cc81c6bad from chromium (#36224)
* chore: cherry-pick 933cc81c6bad from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-11-03 09:51:00 -04:00
Pedro Pontes
aab45e6ed5 chore: cherry-pick 67c9cbc784d6 from chromium (#36221)
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2022-11-02 14:22:33 -04:00
Pedro Pontes
9e58c1bff8 chore: cherry-pick 06c87f9f42ff from chromium (#36207)
chore: [19-x-y] cherry-pick 06c87f9f42ff from chromium

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-11-02 14:18:52 -04:00
Pedro Pontes
7e5adf5e56 chore: cherry-pick eef098d1c7d5 from webrtc (#36218)
* chore: cherry-pick eef098d1c7d5 from webrtc

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-02 11:51:42 -04:00
Pedro Pontes
726839761f chore: cherry-pick b8636b57b8f2 from angle (#36209)
* chore: [19-x-y] cherry-pick b8636b57b8f2 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-02 10:31:58 -04:00
Pedro Pontes
21e1f6398e chore: cherry-pick d5ffb4dd4112 from chromium (#36215)
* chore: cherry-pick d5ffb4dd4112 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-02 10:13:49 -04:00
Pedro Pontes
6b75a958c2 chore: cherry-pick 194bcc127f21 from v8 (#36205)
* chore: [19-x-y] cherry-pick 194bcc127f21 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-02 09:08:36 -04:00
George Xu
7842c6d075 build: use python3 for appveyor commands (#36229) 2022-11-01 16:58:52 -07:00
Keeley Hammond
f2e2fc34f2 build: determine electron version from tags not files (#36137)
* build: determine electron version from tags not files (#36106)

* build: determine electron version from tags not files

* build: make electron_version dependent on packed-refs and git HEAD

* build: do not delete electron/.git

* build: do not revert a commit we didn't make

* build: gen version file instead of just writing it

* build: update cache and ninja targets

* build: copy resource.h to generated electron.rc

* build: electron_win32_resources should be public deps

* build: also copy the icon

Co-authored-by: MarshallOfSound <marshallofsound@electronjs.org>

* chore: fixup patches

* chore: update patches

* build: ensure get-version runs in the electron git checkout (#36128)

* build: strip v in the getElectronVersion helper

* build: use npm@7 for npm view command

Co-authored-by: Samuel Attard <sam@electronjs.org>
Co-authored-by: MarshallOfSound <marshallofsound@electronjs.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-10-30 15:38:01 -07:00
trop[bot]
b4d98668cf build: prefix version in uploader script (#36175)
build: prefix v in uploader script

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
2022-10-27 17:47:56 -07:00
trop[bot]
7ce8eaf7f3 test: fixup HID test for ARM CI (#36170)
(cherry picked from commit caf28066d6)

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-10-27 16:12:51 -04:00
Pedro Pontes
9fe4c52219 chore: cherry-pick 07a2ce61e31a from skia (#36081)
* chore: cherry-pick 07a2ce61e31a from skia

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-10-27 16:19:07 +09:00
trop[bot]
7a40212cc8 chore: move main process only accessible API bindings away from common (#36144)
Co-authored-by: Milan Burda <milan.burda@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-10-26 16:52:12 -04:00
George Xu
5ce7d5f81d refactor: migrate from asar to @electron/asar (#36070) (#36082)
* refactor: migrate from asar to @electron/asar (#36070)

* refactor: migrate from asar to @electron/asar

* fix: update asar require calls

* kick ci

Co-authored-by: Samuel Attard <sam@electronjs.org>
2022-10-24 14:47:18 -07:00
trop[bot]
0ab4aa8519 test: disable flaky linux arm/arm64 crash test case (#36100)
test: disable failing linux arm/arm64 crash test case

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-10-24 14:32:21 -04:00
Pedro Pontes
2c457e3cb5 chore: cherry-pick d7feae867b83 from sqlite (#36086)
* chore: cherry-pick d7feae867b83 from sqlite

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-10-20 17:30:44 -04:00
Pedro Pontes
d3fe374952 chore: cherry-pick cb9dff93f3d4 from chromium (#36077)
* chore: [19-x-y] cherry-pick cb9dff93f3d4 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-10-20 14:04:24 -04:00
Sudowoodo Release Bot
83077e9b97 Bump v19.1.3 2022-10-12 08:31:50 -07:00
ad0p
4c1bab160e chore: cherry-pick 05a0d99c9715 from chromium (#35918)
* chore: cherry-pick 05a0d99c9715 from chromium

* chore: cherry-pick 05a0d99c9715 from chromium

Co-authored-by: Adam Prasil <adamprasil@microsoft.com>
2022-10-12 10:26:57 -04:00
Jeremy Rose
3085f29451 chore: cherry-pick fefd6198da31 from chromium (#35882)
* chore: [19-x-y] cherry-pick fefd6198da31 from chromium

* chore: update patches

* fix build

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2022-10-11 16:06:59 -07:00
Milan Burda
5e7d79baa3 fix: pass rfh instances through to the permission helper (#35986)
fix: pass rfh instances through to the permission helper (#35419)

Co-authored-by: Samuel Attard <sam@electronjs.org>
2022-10-11 16:05:47 -07:00
Jeremy Rose
87da7ebd6e chore: cherry-pick 1eb1e18ad41d from chromium (#35879)
* chore: [19-x-y] cherry-pick 1eb1e18ad41d from chromium

* resolve conflict

Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2022-10-05 09:11:02 -07:00
Sudowoodo Release Bot
4748751005 Bump v19.1.2 2022-10-05 08:31:53 -07:00
Jeremy Rose
033c3eded3 chore: cherry-pick 2f6a2939514f from v8 (#35891)
* chore: [19-x-y] cherry-pick 2f6a2939514f from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-10-04 13:52:31 -04:00
Jeremy Rose
a58099974c chore: cherry-pick 8b040cb69e96 from v8 (#35888)
* chore: [19-x-y] cherry-pick 8b040cb69e96 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-10-04 15:46:58 +02:00
Jeremy Rose
8517c72503 chore: cherry-pick 9bebe8549a36 from chromium (#35885)
* chore: [19-x-y] cherry-pick 9bebe8549a36 from chromium

* resolve conflict
2022-10-03 23:47:48 -07:00
trop[bot]
5dfff3a70a fix: set display_id in desktop capturer on Linux (#35835)
fix: set display_id in desktop capturer on Linux (#33861)

Previously, display_id was an empty string, pending Chrome support for
sharing individual screens. Now that this has been added, it is
desirable to have this property set correctly.

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

Co-authored-by: James Cash <james.nvc@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-09-28 22:22:48 +02:00
Sudowoodo Release Bot
ddee4efb07 Bump v19.1.1 2022-09-28 08:31:43 -07:00
trop[bot]
d961b39ed7 fix: set macOS crypto keychain name earlier (#35795)
* fix: set macOS crypto keychain name earlier

* spec: ensure arm64 mac tests are cleaned up

* fixup for password name difference in 19-x-y

Co-authored-by: Samuel Attard <sattard@salesforce.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-09-27 20:15:53 -04:00
Pedro Pontes
bb5c7430db chore: cherry-pick 3eca8ad6b0b5 from libaom (#35826) 2022-09-27 12:16:17 -04:00
trop[bot]
17b7b78993 docs: add Electron deps to license credits file (#35330)
* docs: add Electron deps to license credits file

* fixup! docs: add Electron deps to license credits file

remove nan; it is dev-only

* chore: update patches

Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2022-09-26 15:19:48 -04:00
Pedro Pontes
dbecf7f3c4 chore: cherry-pick a66438897056 from pdfium (#35787)
* chore: cherry-pick a66438897056 from pdfium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-09-26 11:04:14 -04:00
trop[bot]
92ebdb4766 build: remove unused GitHub app config file (#35812)
chore: remove unused GitHub action config file

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2022-09-26 13:13:51 +02:00
trop[bot]
b077402f2c fix: allow docking DevTools with WCO (#35763)
fix: allow for docking devtools with WCO

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-09-26 10:15:20 +02:00
Pedro Pontes
7f89857058 chore: cherry-pick 497f077a1d46 from pdfium (#35789)
* chore: cherry-pick 497f077a1d46 from pdfium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
2022-09-26 10:12:59 +02:00
Pedro Pontes
8d545255c9 chore: cherry-pick 7f0bb5197ed1 from pdfium (#35791)
* chore: cherry-pick 7f0bb5197ed1 from pdfium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
2022-09-23 21:26:10 -07:00
Pedro Pontes
b999fd31f2 chore: cherry-pick 3704cf78f471 from v8 (#35774)
* chore: cherry-pick 3704cf78f471 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-09-23 12:42:18 -07:00
Pedro Pontes
73923c862e chore: cherry-pick c2c8cac2131b from ffmpeg (#35793)
* chore: cherry-pick c2c8cac2131b from ffmpeg

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-09-23 12:39:12 -07:00
Sudowoodo Release Bot
4817e82e89 Bump v19.1.0 2022-09-23 12:36:07 -07:00
trop[bot]
7d84b3bc87 fix: Node.js atob input validation (#35444)
* fix: Node.js atob input validation

* chore: update patches

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-09-22 09:54:33 +02:00
John Kleinschmidt
13445df1fb Revert "Bump v19.1.0"
This reverts commit e75e4420eb.
2022-09-21 19:49:32 -04:00
Sudowoodo Release Bot
e75e4420eb Bump v19.1.0 2022-09-21 16:00:13 -07:00
Pedro Pontes
9947b55cc2 chore: cherry-pick eb4d31309df7 from chromium (#35750)
* chore: [19-x-y] cherry-pick eb4d31309df7 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-09-21 15:49:01 -04:00
Sudowoodo Release Bot
a79258f77e Revert "Bump v19.1.0"
This reverts commit 09cf05df5c.
2022-09-21 10:34:55 -07:00
Sudowoodo Release Bot
09cf05df5c Bump v19.1.0 2022-09-21 08:32:04 -07:00
trop[bot]
2dfd69ea90 fix: edge case in app.isInApplicationsFolder() (#35729) 2022-09-21 10:54:23 +02:00
trop[bot]
51d097662e chore: add missing .eslintrc.json files to limit imports properly (#35745)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-09-20 22:04:48 -05:00
trop[bot]
08c02d2013 test: disable flaky transparent window test (#35708)
Co-authored-by: Jeremy Rose <japthorp@slack-corp.com>
2022-09-19 09:26:54 -04:00
trop[bot]
58f7ab8a5c chore: cherry-pick 47968ed from chromium (#35701) 2022-09-16 20:37:59 +02:00
trop[bot]
770a38e21c fix: uv_os_gethostname failing on Windows 7 (libuv patch regression) (#35703)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2022-09-16 08:15:15 -07:00
trop[bot]
1289823c67 build: fix building with enable_basic_printing false (#35690)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2022-09-16 04:49:54 +02:00
trop[bot]
3ade6e1b08 build: make check-symlinks.js aware of BRANDING.json changes (#35668)
Right now the `check-symlinks.js` assumes that the branding product name
is "Electron". If users change `BRANDING.json` on custom builds, the
script will fail.

Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>

Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
Co-authored-by: Juan Cruz Viotti <jv@jviotti.com>
2022-09-15 13:13:59 -07:00
Milan Burda
c2d73ae79c feat: webFrameMain.origin (#35624)
feat: webFrameMain.origin (#35438)

Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-09-15 10:27:20 -07:00
Pedro Pontes
14c64ed2e0 chore: cherry-pick 51daffbf5cd8 from chromium (#35548)
* chore: [19-x-y] cherry-pick 51daffbf5cd8 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2022-09-15 19:25:48 +02:00
Raymond Zhao
0e0b638e5f fix: allow maximizing when window enters tablet mode with WCO (#35677) 2022-09-14 15:12:19 -07:00
Sudowoodo Release Bot
0e6da36264 Bump v19.0.17 2022-09-14 08:31:46 -07:00
Samuel Attard
3160e0d7fd chore: cherry-pick 9b5207569882 from chromium (#35545)
* chore: cherry-pick 9b5207569882 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-09-14 00:40:00 -07:00
trop[bot]
d0293c81c0 fix: remove extra dot in extension (#35660)
* fix: remove extra period of extension

* update comment

Co-authored-by: mlaurencin <mlaurencin@electronjs.org>
2022-09-13 14:11:28 -07:00
trop[bot]
178db41204 docs: fix typescript error in code samples (#35654)
Fixed typescript error

Co-authored-by: Leon Schwanitz <leon@28minds.com>
2022-09-13 13:37:07 -07:00
trop[bot]
d3976e68c8 fix: potential "Object has been destroyed" error in BrowserWindow.getFocusedWindow (#35643)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-09-13 08:06:55 -07:00
trop[bot]
9e3039775e docs: Use inline image link in faq.md (#35647)
* Use absolute URL in faq.md image link

The relative link is rendered relative to the host domain, which works fine when viewing it on Github, but since you also use the same generated HTML in your doc site, the link is broken. See here: https://www.electronjs.org/docs/latest/faq#the-font-looks-blurry-what-is-this-and-what-can-i-do

Using an absolute URL here should fix the issue on the main site.

* Use inline image reference for subpixel rendering example

As suggested by @dsanders11

Co-authored-by: Adrian Petrescu <adrian@apetre.sc>
2022-09-13 08:02:35 -07:00
trop[bot]
820e0ca3b5 fix: ensure history navigations are sandboxed-iframe-aware (#35621)
Co-authored-by: Jeremy Spiegel <jeremy.spiegel@frontapp.com>
2022-09-12 03:03:38 -07:00
trop[bot]
397a5c6194 fix: Set background for WCO container (#35610)
* fix: Set background for WCO container

* Add background when invalidating as well

Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>
2022-09-08 13:46:37 -07:00
trop[bot]
4d62f9648f fix: session.getBlobData never resolves with blob sizes > 65536 (#35600)
fix: session.getBlobData never resolves with blob sizes > 65536 (#35277)

* fix: session.getBlobData never resolves with blob sizes > 65536 (#34398)

* Add unit test case for session.getBlobData

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

Co-authored-by: Frank Pian <bianyongfang@vip.qq.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-09-08 10:30:07 +02:00
121 changed files with 6769 additions and 439 deletions

View File

@@ -216,6 +216,7 @@ step-maybe-cleanup-arm64-mac: &step-maybe-cleanup-arm64-mac
rm -rf ~/Library/Application\ Support/electron*
security delete-generic-password -l "Chromium Safe Storage" || echo "✓ Keychain does not contain password from tests"
security delete-generic-password -l "Electron Test Main Safe Storage" || echo "✓ Keychain does not contain password from tests"
security delete-generic-password -a "electron-safe-storage" || echo "✓ Keychain does not contain password from tests"
elif [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
XVFB=/usr/bin/Xvfb
/sbin/start-stop-daemon --stop --exec $XVFB || echo "Xvfb not running"
@@ -454,7 +455,7 @@ step-delete-git-directories: &step-delete-git-directories
command: |
if [ "`uname`" == "Darwin" ]; then
cd src
( find . -type d -name ".git" -not -path "./third_party/angle/*" -not -path "./third_party/dawn/*" ) | xargs rm -rf
( find . -type d -name ".git" -not -path "./third_party/angle/*" -not -path "./third_party/dawn/*" -not -path "./electron/*" ) | xargs rm -rf
fi
# On macOS the yarn install command during gclient sync was run on a linux
@@ -825,7 +826,7 @@ step-maybe-zip-symbols: &step-maybe-zip-symbols
cd src
export BUILD_PATH="$PWD/out/Default"
ninja -C out/Default electron:licenses
ninja -C out/Default electron:electron_version
ninja -C out/Default electron:electron_version_file
DELETE_DSYMS_AFTER_ZIP=1 electron/script/zip-symbols.py -b $BUILD_PATH
step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
@@ -885,12 +886,12 @@ step-touch-sync-done: &step-touch-sync-done
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
restore_cache:
keys:
- v14-src-cache-{{ checksum "src/electron/.depshash" }}
- v16-src-cache-{{ checksum "src/electron/.depshash" }}
name: Restoring src cache
step-maybe-restore-src-cache-marker: &step-maybe-restore-src-cache-marker
restore_cache:
keys:
- v14-src-cache-marker-{{ checksum "src/electron/.depshash" }}
- v16-src-cache-marker-{{ checksum "src/electron/.depshash" }}
name: Restoring src cache marker
# Restore exact or closest git cache based on the hash of DEPS and .circle-sync-done
@@ -905,14 +906,6 @@ step-maybe-restore-git-cache: &step-maybe-restore-git-cache
- v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}
name: Conditionally restoring git cache
step-restore-out-cache: &step-restore-out-cache
restore_cache:
paths:
- ./src/out/Default
keys:
- v10-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
name: Restoring out cache
step-set-git-cache-path: &step-set-git-cache-path
run:
name: Set GIT_CACHE_PATH to make gclient to use the cache
@@ -930,13 +923,6 @@ step-save-git-cache: &step-save-git-cache
key: v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
name: Persisting git cache
step-save-out-cache: &step-save-out-cache
save_cache:
paths:
- ./src/out/Default
key: v10-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
name: Persisting out cache
step-run-electron-only-hooks: &step-run-electron-only-hooks
run:
name: Run Electron Only Hooks
@@ -966,13 +952,16 @@ step-minimize-workspace-size-from-checkout: &step-minimize-workspace-size-from-c
rm -rf third_party/electron_node/deps/openssl
rm -rf third_party/electron_node/deps/v8
rm -rf chrome/test/data/xr/webvr_info
rm -rf src/third_party/angle/third_party/VK-GL-CTS/src
rm -rf src/third_party/swift-toolchain
rm -rf src/third_party/swiftshader/tests/regres/testlists
# Save the src cache based on the deps hash
step-save-src-cache: &step-save-src-cache
save_cache:
paths:
- /var/portal
key: v14-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
key: v16-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
name: Persisting src cache
step-make-src-cache-marker: &step-make-src-cache-marker
run:
@@ -982,7 +971,7 @@ step-save-src-cache-marker: &step-save-src-cache-marker
save_cache:
paths:
- .src-cache-marker
key: v14-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
key: v16-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
step-maybe-early-exit-no-doc-change: &step-maybe-early-exit-no-doc-change
run:
@@ -1353,9 +1342,6 @@ commands:
build:
type: boolean
default: true
use-out-cache:
type: boolean
default: true
restore-src-cache:
type: boolean
default: true
@@ -1478,10 +1464,6 @@ commands:
- *step-delete-git-directories
# Electron app
- when:
condition: << parameters.use-out-cache >>
steps:
- *step-restore-out-cache
- *step-gn-gen-default
- *step-electron-build
- *step-maybe-electron-dist-strip
@@ -1524,22 +1506,6 @@ commands:
condition: << parameters.build >>
steps:
- move_and_store_all_artifacts
- run:
name: Remove the big things on macOS, this seems to be better on average
command: |
if [ "`uname`" == "Darwin" ]; then
mkdir -p src/out/Default
cd src/out/Default
find . -type f -size +50M -delete
mkdir -p gen/electron
cd gen/electron
# These files do not seem to like being in a cache, let us remove them
find . -type f -name '*_pkg_info' -delete
fi
- when:
condition: << parameters.use-out-cache >>
steps:
- *step-save-out-cache
- *step-maybe-notify-slack-failure
@@ -1693,7 +1659,6 @@ jobs:
persist: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-x64-testing-asan:
executor:
@@ -1710,7 +1675,6 @@ jobs:
- electron-build:
persist: true
checkout: true
use-out-cache: false
build-nonproprietary-ffmpeg: false
linux-x64-testing-no-run-as-node:
@@ -1727,7 +1691,6 @@ jobs:
- electron-build:
persist: false
checkout: true
use-out-cache: false
linux-x64-testing-gn-check:
executor:
@@ -1778,7 +1741,6 @@ jobs:
persist: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-arm-publish:
executor:
@@ -1821,7 +1783,6 @@ jobs:
persist: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-arm64-testing-gn-check:
executor:

View File

@@ -1,2 +0,0 @@
# Always validate the PR title, and ignore the commits
titleOnly: true

View File

@@ -100,6 +100,14 @@ branding = read_file("shell/app/BRANDING.json", "json")
electron_project_name = branding.project_name
electron_product_name = branding.product_name
electron_mac_bundle_id = branding.mac_bundle_id
electron_version = exec_script("script/print-version.py",
[],
"trim string",
[
".git/packed-refs",
".git/HEAD",
"script/lib/get-version.js",
])
if (is_mas_build) {
assert(is_mac,
@@ -294,12 +302,9 @@ npm_action("electron_version_args") {
outputs = [ "$target_gen_dir/electron_version.args" ]
args = rebase_path(outputs)
args = rebase_path(outputs) + [ "$electron_version" ]
inputs = [
"ELECTRON_VERSION",
"script/generate-version-json.js",
]
inputs = [ "script/generate-version-json.js" ]
}
templated_file("electron_version_header") {
@@ -311,6 +316,39 @@ templated_file("electron_version_header") {
args_files = get_target_outputs(":electron_version_args")
}
templated_file("electron_win_rc") {
deps = [ ":electron_version_args" ]
template = "build/templates/electron_rc.tmpl"
output = "$target_gen_dir/win-resources/electron.rc"
args_files = get_target_outputs(":electron_version_args")
}
copy("electron_win_resource_files") {
sources = [
"shell/browser/resources/win/electron.ico",
"shell/browser/resources/win/resource.h",
]
outputs = [ "$target_gen_dir/win-resources/{{source_file_part}}" ]
}
templated_file("electron_version_file") {
deps = [ ":electron_version_args" ]
template = "build/templates/version_string.tmpl"
output = "$root_build_dir/version"
args_files = get_target_outputs(":electron_version_args")
}
group("electron_win32_resources") {
public_deps = [
":electron_win_rc",
":electron_win_resource_files",
]
}
action("electron_fuses") {
script = "build/fuses/build.py"
@@ -749,7 +787,6 @@ if (is_mac) {
electron_helper_name = "$electron_product_name Helper"
electron_login_helper_name = "$electron_product_name Login Helper"
electron_framework_version = "A"
electron_version = read_file("ELECTRON_VERSION", "trim string")
mac_xib_bundle_data("electron_xibs") {
sources = [ "shell/common/resources/mac/MainMenu.xib" ]
@@ -1179,6 +1216,7 @@ if (is_mac) {
":default_app_asar",
":electron_app_manifest",
":electron_lib",
":electron_win32_resources",
":packed_resources",
"//components/crash/core/app",
"//content:sandbox_helper_win",
@@ -1212,8 +1250,7 @@ if (is_mac) {
if (is_win) {
sources += [
# TODO: we should be generating our .rc files more like how chrome does
"shell/browser/resources/win/electron.rc",
"$target_gen_dir/win-resources/electron.rc",
"shell/browser/resources/win/resource.h",
]
@@ -1395,15 +1432,10 @@ group("licenses") {
]
}
copy("electron_version") {
sources = [ "ELECTRON_VERSION" ]
outputs = [ "$root_build_dir/version" ]
}
dist_zip("electron_dist_zip") {
data_deps = [
":electron_app",
":electron_version",
":electron_version_file",
":licenses",
]
if (is_linux) {

View File

@@ -1 +0,0 @@
19.0.16

View File

@@ -182,14 +182,14 @@ build_script:
}
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
python electron\script\zip-symbols.py
python3 electron\script\zip-symbols.py
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
} else {
# It's useful to have pdb files when debugging testing builds that are
# built on CI.
7z a pdb.zip out\Default\*.pdb
}
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
test_script:
# Workaround for https://github.com/appveyor/ci/issues/2420
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
@@ -210,11 +210,11 @@ test_script:
- if "%RUN_TESTS%"=="true" ( echo Running remote test suite & node script/yarn test -- --trace-uncaught --runners=remote --runTestFilesSeperately --enable-logging=file --log-file=%cd%\electron.log --disable-features=CalculateNativeWinOcclusion )
- if "%RUN_TESTS%"=="true" ( echo Running native test suite & node script/yarn test -- --trace-uncaught --runners=native --enable-logging=file --log-file=%cd%\electron.log --disable-features=CalculateNativeWinOcclusion )
- cd ..
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python3 electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
- echo "About to verify mksnapshot"
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python3 electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
- echo "Done verifying mksnapshot"
- if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )
- if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python3 electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )
- echo "Done verifying chromedriver"
deploy_script:
- cd electron
@@ -222,10 +222,10 @@ deploy_script:
if (Test-Path Env:\ELECTRON_RELEASE) {
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
Write-Output "Uploading Electron release distribution to azure"
& python script\release\uploaders\upload.py --verbose --upload_to_storage
& python3 script\release\uploaders\upload.py --verbose --upload_to_storage
} else {
Write-Output "Uploading Electron release distribution to github releases"
& python script\release\uploaders\upload.py --verbose
& python3 script\release\uploaders\upload.py --verbose
}
} elseif (Test-Path Env:\TEST_WOA) {
node script/release/ci-release-build.js --job=electron-woa-testing --ci=GHA --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH

View File

@@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 19,0,16,0
PRODUCTVERSION 19,0,16,0
FILEVERSION $major,$minor,$patch,$prerelease_number
PRODUCTVERSION $major,$minor,$patch,$prerelease_number
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -68,12 +68,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron"
VALUE "FileVersion", "19.0.16"
VALUE "FileVersion", "$major.$minor.$patch"
VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron"
VALUE "ProductVersion", "19.0.16"
VALUE "ProductVersion", "$major.$minor.$patch"
VALUE "SquirrelAwareVersion", "1"
END
END

View File

@@ -0,0 +1 @@
$full_version

View File

@@ -610,7 +610,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
* `notifications` - Request notification creation and the ability to display them in the user's system tray.
* `midi` - Request MIDI access in the `webmidi` API.
* `midiSysex` - Request the use of system exclusive messages in the `webmidi` API.
* `pointerLock` - Request to directly interpret mouse movements as an input method. Click [here](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) to know more.
* `pointerLock` - Request to directly interpret mouse movements as an input method. Click [here](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) to know more. These requests always appear to originate from the main frame.
* `fullscreen` - Request for the app to enter fullscreen mode.
* `openExternal` - Request to open links in external applications.
* `unknown` - An unrecognized permission request

View File

@@ -144,6 +144,16 @@ ipcRenderer.on('port', (e, msg) => {
A `string` representing the current URL of the frame.
#### `frame.origin` _Readonly_
A `string` representing the current origin of the frame, serialized according
to [RFC 6454](https://www.rfc-editor.org/rfc/rfc6454). This may be different
from the URL. For instance, if the frame is a child window opened to
`about:blank`, then `frame.origin` will return the parent frame's origin, while
`frame.url` will return the empty string. Pages without a scheme/host/port
triple origin will have the serialized origin of `"null"` (that is, the string
containing the letters n, u, l, l).
#### `frame.top` _Readonly_
A `WebFrameMain | null` representing top frame in the frame hierarchy to which `frame`

View File

@@ -135,7 +135,7 @@ is only available in renderer processes.
If [sub-pixel anti-aliasing](https://alienryderflex.com/sub_pixel/) is deactivated, then fonts on LCD screens can look blurry. Example:
![subpixel rendering example]
![Subpixel rendering example](images/subpixel-rendering-screenshot.gif)
Sub-pixel anti-aliasing needs a non-transparent background of the layer containing the font glyphs. (See [this issue](https://github.com/electron/electron/issues/6344#issuecomment-420371918) for more info).
@@ -161,4 +161,3 @@ Notice that just setting the background in the CSS does not have the desired eff
[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
[message-port]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
[browser-window]: api/browser-window.md
[subpixel rendering example]: images/subpixel-rendering-screenshot.gif

View File

@@ -28,12 +28,16 @@ function createWindow () {
if (permission === 'serial' && details.securityOrigin === 'file:///') {
return true
}
return false
})
mainWindow.webContents.session.setDevicePermissionHandler((details) => {
if (details.deviceType === 'serial' && details.origin === 'file://') {
return true
}
return false
})
mainWindow.loadFile('index.html')

View File

@@ -18,4 +18,4 @@
}
]
}
}
}

View File

@@ -72,9 +72,8 @@ BrowserWindow.getAllWindows = () => {
BrowserWindow.getFocusedWindow = () => {
for (const window of BrowserWindow.getAllWindows()) {
const hasWC = window.webContents && !window.webContents.isDestroyed();
if (!window.isDestroyed() && hasWC) {
if (window.isFocused() || window.isDevToolsFocused()) return window;
if (!window.isDestroyed() && window.webContents && !window.webContents.isDestroyed()) {
if (window.isFocused() || window.webContents.isDevToolsFocused()) return window;
}
}
return null;

View File

@@ -1,3 +1,3 @@
const { nativeTheme } = process._linkedBinding('electron_common_native_theme');
const { nativeTheme } = process._linkedBinding('electron_browser_native_theme');
module.exports = nativeTheme;

View File

@@ -1,7 +1,7 @@
const {
Notification: ElectronNotification,
isSupported
} = process._linkedBinding('electron_common_notification');
} = process._linkedBinding('electron_browser_notification');
ElectronNotification.isSupported = isSupported;

View File

@@ -1,6 +1,6 @@
import { EventEmitter } from 'events';
const { createScreen } = process._linkedBinding('electron_common_screen');
const { createScreen } = process._linkedBinding('electron_browser_screen');
let _screen: Electron.Screen;

23
lib/common/.eslintrc.json Normal file
View File

@@ -0,0 +1,23 @@
{
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
"electron",
"electron/main",
"electron/renderer"
],
"patterns": [
"./*",
"../*",
"@electron/internal/browser/*",
"@electron/internal/isolated_renderer/*",
"@electron/internal/renderer/*",
"@electron/internal/sandboxed_worker/*",
"@electron/internal/worker/*"
]
}
]
}
}

View File

@@ -1,5 +1,6 @@
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
// eslint-disable-next-line no-restricted-imports
import type * as ipcRendererUtilsModule from '@electron/internal/renderer/ipc-renderer-internal-utils';
const clipboard = process._linkedBinding('electron_common_clipboard');

View File

@@ -0,0 +1,18 @@
{
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
"electron",
"electron/main"
],
"patterns": [
"./*",
"../*",
"@electron/internal/browser/*"
]
}
]
}
}

View File

@@ -0,0 +1,18 @@
{
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
"electron",
"electron/main"
],
"patterns": [
"./*",
"../*",
"@electron/internal/browser/*"
]
}
]
}
}

View File

@@ -1,4 +1,4 @@
import { ipcRenderer } from 'electron';
import { ipcRenderer } from 'electron/renderer';
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
import type * as webViewInitModule from '@electron/internal/renderer/web-view/web-view-init';

View File

@@ -2,7 +2,7 @@ import { internalContextBridge } from '@electron/internal/renderer/api/context-b
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
import { webFrame } from 'electron/renderer';
import { IPC_MESSAGES } from '../common/ipc-messages';
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
const { contextIsolationEnabled } = internalContextBridge;

View File

@@ -1,4 +1,4 @@
import { webFrame, WebFrame } from 'electron';
import { webFrame, WebFrame } from 'electron/renderer';
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';

View File

@@ -0,0 +1,18 @@
{
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
"electron",
"electron/main"
],
"patterns": [
"./*",
"../*",
"@electron/internal/browser/*"
]
}
]
}
}

18
lib/worker/.eslintrc.json Normal file
View File

@@ -0,0 +1,18 @@
{
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
"electron",
"electron/main"
],
"patterns": [
"./*",
"../*",
"@electron/internal/browser/*"
]
}
]
}
}

View File

@@ -1,12 +1,13 @@
{
"name": "electron",
"version": "19.0.16",
"version": "0.0.0-development",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
"@azure/storage-blob": "^12.9.0",
"@electron/docs-parser": "^0.12.4",
"@electron/typescript-definitions": "^8.9.5",
"@electron/asar": "^3.2.1",
"@electron/docs-parser": "^1.0.0",
"@electron/typescript-definitions": "^8.10.0",
"@octokit/auth-app": "^2.10.0",
"@octokit/rest": "^18.0.3",
"@primer/octicons": "^10.0.0",
@@ -31,7 +32,6 @@
"@types/webpack-env": "^1.16.3",
"@typescript-eslint/eslint-plugin": "^4.4.1",
"@typescript-eslint/parser": "^4.4.1",
"asar": "^3.1.0",
"aws-sdk": "^2.814.0",
"check-for-leaks": "^1.2.1",
"colors": "1.4.0",
@@ -89,7 +89,7 @@
"lint:docs-relative-links": "python3 ./script/check-relative-doc-links.py",
"lint:markdownlint": "markdownlint \"*.md\" \"docs/**/*.md\"",
"lint:js-in-markdown": "standard-markdown docs",
"create-api-json": "electron-docs-parser --dir=./",
"create-api-json": "node script/create-api-json.js",
"create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --api=electron-api.json && node spec/ts-smoke/runner.js",
"gn-typescript-definitions": "npm run create-typescript-definitions && shx cp electron.d.ts",
"pre-flight": "pre-flight",
@@ -143,4 +143,4 @@
"node script/gen-hunspell-filenames.js"
]
}
}
}

View File

@@ -1,2 +1,3 @@
m104_vulkan_fix_garbage_collection_vs_outside-rp-only_flush.patch
m104_vulkan_fix_xfb_buffer_redefine_to_smaller_size.patch
cherry-pick-b8636b57b8f2.patch

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Mon, 29 Aug 2022 16:25:46 -0400
Subject: Vulkan: Ensure we sync the draw FB before beingQuery.
Bug: chromium:1354271
(cherry picked from commit 4ebdac790c76b65abf5703bcef9482c638076195)
Change-Id: I7b715a9c28badfe58a0ae1a478d2b4e8bbd23c47
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3956939
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
index f8c1d9daaf31b5edb98edf3ca0a5c1983d6039cb..79403b13a94447c07bf0bfa6f9e6567e43346505 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -600,6 +600,11 @@ class State : angle::NonCopyable
bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
+ bool isDrawFramebufferBindingDirty() const
+ {
+ return mDirtyBits.test(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
+ }
+
// Sets the dirty bit for the program executable.
angle::Result onProgramExecutableChange(const Context *context, Program *program);
// Sets the dirty bit for the program pipeline executable.
diff --git a/src/libANGLE/renderer/vulkan/QueryVk.cpp b/src/libANGLE/renderer/vulkan/QueryVk.cpp
index 921adfc6e02984cb9b0ded70065df16f9241e4e7..f806326113d0804862481ac5508f07eab4d5ebe1 100644
--- a/src/libANGLE/renderer/vulkan/QueryVk.cpp
+++ b/src/libANGLE/renderer/vulkan/QueryVk.cpp
@@ -302,6 +302,13 @@ angle::Result QueryVk::begin(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
+ // Ensure that we start with the right RenderPass when we begin a new query.
+ if (contextVk->getState().isDrawFramebufferBindingDirty())
+ {
+ ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass(
+ RenderPassClosureReason::FramebufferBindingChange));
+ }
+
mCachedResultValid = false;
// Transform feedback query is handled by a CPU-calculated value when emulated.

View File

@@ -119,6 +119,7 @@ build_disable_print_content_analysis.patch
feat_move_firstpartysets_to_content_browser_client.patch
custom_protocols_plzserviceworker.patch
posix_replace_doubleforkandexec_with_forkandspawn.patch
cherry-pick-ecad352cd614.patch
cherry-pick-22c61cfae5d1.patch
remove_default_window_title.patch
keep_handling_scroll_update_if_you_can.patch
@@ -137,3 +138,26 @@ cherry-pick-c643d18a078d.patch
feat_add_set_can_resize_mutator.patch
cherry-pick-2083e894852c.patch
cherry-pick-079105b7ebba.patch
cherry-pick-51daffbf5cd8.patch
cherry-pick-9b5207569882.patch
dpwa_enable_window_controls_overlay_by_default.patch
cherry-pick-eb4d31309df7.patch
add_electron_deps_to_license_credits_file.patch
cherry-pick-fefd6198da31.patch
cherry-pick-1eb1e18ad41d.patch
cherry-pick-9bebe8549a36.patch
cherry-pick-05a0d99c9715.patch
cherry-pick-cb9dff93f3d4.patch
build_allow_electron_to_use_exec_script.patch
cherry-pick-933cc81c6bad.patch
cherry-pick-67c9cbc784d6.patch
cherry-pick-d5ffb4dd4112.patch
cherry-pick-06c87f9f42ff.patch
refresh_cached_attributes_before_name_computation_traversal.patch
review_add_clear_children_checks_during_accname_traversal.patch
cherry-pick-1894458e04a2.patch
cherry-pick-a1cbf05b4163.patch
cherry-pick-ac4785387fff.patch
cherry-pick-81cb17c24788.patch
fix_crash-on-close_for_mac_udp_sockets.patch
cherry-pick-6b4af5d82083.patch

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Charles Kerr <charles@charleskerr.com>
Date: Tue, 9 Aug 2022 12:35:36 -0500
Subject: add electron deps to license credits file
Ensure that licenses for the dependencies introduced by Electron
are included in `LICENSES.chromium.html`
diff --git a/tools/licenses.py b/tools/licenses.py
index b083d3509433aa97aa85c59a4269def5ef5a5359..c032e1f9dc058ff2c76b54ac5da6805163d1eadf 100755
--- a/tools/licenses.py
+++ b/tools/licenses.py
@@ -340,6 +340,32 @@ SPECIAL_CASES = {
"License File":
"/third_party/swiftshader/third_party/SPIRV-Tools/LICENSE",
},
+
+ os.path.join('third_party', 'electron_node'): {
+ "Name": "Node.js",
+ "URL": "https://github.com/nodejs/node",
+ "License": "MIT",
+ "License File": "/third_party/electron_node/LICENSE",
+ },
+ os.path.join('third_party', 'squirrel.mac'): {
+ "Name": "Squirrel",
+ "URL": "https://github.com/Squirrel/Squirrel.Mac",
+ "License": "MIT",
+ "License File": "/third_party/squirrel.mac/LICENSE",
+ },
+ os.path.join('third_party', 'squirrel.mac', 'vendor', 'mantle'): {
+ "Name": "Mantle",
+ "URL": "https://github.com/Mantle/Mantle",
+ "License": "MIT",
+ "License File": "/third_party/squirrel.mac/vendor/mantle/LICENSE.md",
+ },
+ os.path.join('third_party', 'squirrel.mac', 'vendor', 'ReactiveObjC'): {
+ "Name": "ReactiveObjC",
+ "URL": "https://github.com/ReactiveCocoa/ReactiveObjC",
+ "License": "MIT",
+ "License File":
+ "/third_party/squirrel.mac/vendor/ReactiveObjC/LICENSE.md",
+ },
}
# Special value for 'License File' field used to indicate that the license file

View File

@@ -0,0 +1,18 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <sattard@salesforce.com>
Date: Fri, 21 Oct 2022 16:29:06 -0700
Subject: build: allow electron to use exec_script
This is similar to the //build usecase so we're OK adding ourselves here
diff --git a/.gn b/.gn
index 5a11496a47ae7cd2b74992c58760ce1786f7b7df..210463041fa2e46bb368f515afdd4f25e1ca6616 100644
--- a/.gn
+++ b/.gn
@@ -171,4 +171,6 @@ exec_script_whitelist =
"//tools/grit/grit_rule.gni",
"//tools/gritsettings/BUILD.gn",
+
+ "//electron/BUILD.gn"
]

View File

@@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: David Bokan <bokan@chromium.org>
Date: Thu, 28 Jul 2022 18:09:13 +0000
Subject: Prevent handling input for provisional frames
Bug: 1347644,1322812
Change-Id: Ifd60f6aa593ce23ca6cbb65552fc9fb8f8690035
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3791883
Commit-Queue: David Bokan <bokan@chromium.org>
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1029361}
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index c7d6c63a3c3b640436835e986d2e03ee232b65f0..6106168562e5300b5d15666e1278b207358c63b8 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -2448,10 +2448,15 @@ WebInputEventResult WebFrameWidgetImpl::HandleInputEvent(
DCHECK(!WebInputEvent::IsTouchEventType(input_event.GetType()));
CHECK(LocalRootImpl());
+ // Clients shouldn't be dispatching events to a provisional frame but this
+ // can happen. Ensure that event handling can assume we're in a committed
+ // frame.
+ if (IsProvisional())
+ return WebInputEventResult::kHandledSuppressed;
+
// Only record metrics for the root frame.
- if (ForTopMostMainFrame()) {
+ if (ForTopMostMainFrame())
GetPage()->GetVisualViewport().StartTrackingPinchStats();
- }
// If a drag-and-drop operation is in progress, ignore input events except
// PointerCancel and GestureLongPress.

View File

@@ -0,0 +1,153 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rune Lillesveen <futhark@chromium.org>
Date: Fri, 14 Oct 2022 09:52:34 +0000
Subject: Avoid layout roots in subtrees skipped for style recalc
Layout roots are laid out from inner to outer in LocalFrameView. DOM
mutations may have added layout roots inside size container subtrees
before style recalc. If we decide to postpone style recalc until layout
of the size container, it means we may try to layout a root inside a
subtree skipped for style recalc. That causes a DCHECK and possibly
other issues.
This also fixes the use-after-poison issue 1365330.
(cherry picked from commit 0f0f1e99201fadb3c68518350e1cd6af1b665346)
Bug: 1371820, 1365330
Change-Id: Ia48890c08aacfe7b9a3e660817702abce0570564
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3934847
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1055853}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3953455
Auto-Submit: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/branch-heads/5249@{#836}
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc
index 80a400738536e80683ec6e7eba78f891966d4e9c..c06274949131f17253c614984402fe13eee66809 100644
--- a/third_party/blink/renderer/core/css/style_engine.cc
+++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -2643,6 +2643,7 @@ void StyleEngine::RecalcStyle(StyleRecalcChange change,
DCHECK(GetDocument().documentElement());
ScriptForbiddenScope forbid_script;
HasMatchedCacheScope has_matched_cache_scope(&GetDocument());
+ SkipStyleRecalcScope skip_scope(*this);
Element& root_element = style_recalc_root_.RootElement();
Element* parent = FlatTreeTraversal::ParentElement(root_element);
@@ -3231,4 +3232,17 @@ void StyleEngine::MarkForLayoutTreeChangesAfterDetach() {
parent_for_detached_subtree_ = nullptr;
}
+bool StyleEngine::AllowSkipStyleRecalcForScope() const {
+ if (InContainerQueryStyleRecalc())
+ return true;
+ if (LocalFrameView* view = GetDocument().View()) {
+ // Existing layout roots before starting style recalc may end up being
+ // inside skipped subtrees if we allowed skipping. If we start out with an
+ // empty list, any added ones will be a result of an element style recalc,
+ // which means the will not be inside a skipped subtree.
+ return !view->IsSubtreeLayout();
+ }
+ return true;
+}
+
} // namespace blink
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h
index cb18cdff2e2b782a486dcebdda75761a68428a2b..512010d021ae8e726efb02206af6f739fa610346 100644
--- a/third_party/blink/renderer/core/css/style_engine.h
+++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -177,6 +177,20 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
base::AutoReset<bool> allow_marking_;
};
+ // Set up the condition for allowing to skip style recalc before starting
+ // RecalcStyle().
+ class SkipStyleRecalcScope {
+ STACK_ALLOCATED();
+
+ public:
+ explicit SkipStyleRecalcScope(StyleEngine& engine)
+ : allow_skip_(&engine.allow_skip_style_recalc_,
+ engine.AllowSkipStyleRecalcForScope()) {}
+
+ private:
+ base::AutoReset<bool> allow_skip_;
+ };
+
explicit StyleEngine(Document&);
~StyleEngine() override;
@@ -337,6 +351,10 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
void UpdateStyleRecalcRoot(ContainerNode* ancestor, Node* dirty_node);
void UpdateLayoutTreeRebuildRoot(ContainerNode* ancestor, Node* dirty_node);
+ // Returns true if we can skip style recalc for a size container subtree and
+ // resume it during layout.
+ bool SkipStyleRecalcAllowed() const { return allow_skip_style_recalc_; }
+
CSSFontSelector* GetFontSelector() { return font_selector_; }
void RemoveFontFaceRules(const HeapVector<Member<const StyleRuleFontFace>>&);
@@ -719,6 +737,9 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
Element* parent,
Element* previous_sibling);
+ // Initialization value for SkipStyleRecalcScope.
+ bool AllowSkipStyleRecalcForScope() const;
+
Member<Document> document_;
// Tracks the number of currently loading top-level stylesheets. Sheets loaded
@@ -788,6 +809,9 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
// AllowMarkStyleDirtyFromRecalcScope.
bool allow_mark_for_reattach_from_rebuild_layout_tree_{false};
+ // Set to true if we are allowed to skip recalc for a size container subtree.
+ bool allow_skip_style_recalc_{false};
+
// See enum ViewportUnitFlag.
unsigned viewport_unit_dirty_flags_{0};
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 8f60e1e6e2c929e5f58682c924478a62725f73b3..bfbf6b3c103f0b5d79570c9372bfc0f81166a2d7 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3334,6 +3334,10 @@ bool Element::SkipStyleRecalcForContainer(
const ComputedStyle& style,
const StyleRecalcChange& child_change) {
DCHECK(RuntimeEnabledFeatures::CSSContainerSkipStyleRecalcEnabled());
+
+ if (!GetDocument().GetStyleEngine().SkipStyleRecalcAllowed())
+ return false;
+
if (!child_change.TraversePseudoElements(*this)) {
// If none of the children or pseudo elements need to be traversed for style
// recalc, there is no point in marking the subtree as skipped.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/crashtests/chrome-layout-root-crash.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/crashtests/chrome-layout-root-crash.html
new file mode 100644
index 0000000000000000000000000000000000000000..e3e709a240bd870250b2747c94fe96880bdf52e3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/crashtests/chrome-layout-root-crash.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<html class="reftest-wait">
+<link rel="help" href="https://crbug.com/1371820">
+<style>
+ body, div, img { container-type: size; }
+</style>
+<p>Pass if no crash.</p>
+<div id="div"><img id="img" alt="a"></div>
+<script>
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ // Adds a layout root inside the div size container.
+ img.alt = img.src = "b";
+ // Marks div size container for layout which skips style recalc for the sub-tree.
+ div.style.width = "500px";
+ document.documentElement.classList.remove("reftest-wait");
+ }));
+</script>

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Joshua Peraza <jperaza@chromium.org>
Date: Thu, 3 Nov 2022 21:18:35 +0000
Subject: Validate number of bytes read
Original commit:
https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3994208
(cherry picked from commit 7585111a6c1dfa502f3ca1e3d27aed066e479fd9)
Bug: chromium:1380083
Change-Id: If9708ccdbf6957ef169b35f8f89e2b0744d066d7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4000305
Reviewed-by: Mark Mentovai <mark@chromium.org>
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/5359@{#529}
Cr-Original-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4004067
Cr-Commit-Position: refs/branch-heads/5249@{#905}
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
diff --git a/third_party/crashpad/crashpad/util/linux/ptrace_client.cc b/third_party/crashpad/crashpad/util/linux/ptrace_client.cc
index 1863841f73f64d89391646f5c3e5fc2e2766a6cc..32cc35d9567117fe0eb6f1ec4736ac4a15ddfd83 100644
--- a/third_party/crashpad/crashpad/util/linux/ptrace_client.cc
+++ b/third_party/crashpad/crashpad/util/linux/ptrace_client.cc
@@ -331,6 +331,11 @@ ssize_t PtraceClient::ReadUpTo(VMAddress address, size_t size, void* buffer) {
return total_read;
}
+ if (static_cast<size_t>(bytes_read) > size) {
+ LOG(ERROR) << "invalid size " << bytes_read;
+ return -1;
+ }
+
if (!LoggingReadFileExactly(sock_, buffer_c, bytes_read)) {
return -1;
}

View File

@@ -0,0 +1,184 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Anders Hartvoll Ruud <andruud@chromium.org>
Date: Tue, 20 Sep 2022 17:43:47 +0000
Subject: Add CSSTokenizer-created strings to CSSVariableData's backing strings
When computing the value of a registered custom property, we create
a CSSVariableData object equivalent to the computed CSSValue by
serializing that CSSValue to a String, then tokenizing that value.
The problem is that CSSTokenizer can create *new* string objects
during the tokenization process (see calls to CSSTokenizer::
RegisterString), without communicating that fact to the call-site.
Therefore, this CL adds a way to access those strings so they can
be added to the backing strings of the CSSVariableData.
Also added a DCHECK to verify that we don't have any tokens with
non-backed string pointers.
Fixed: 1358907
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3892782
Reviewed-by: Steinar H Gunderson <sesse@chromium.org>
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1046868}
Change-Id: Ifb6d194508e99030a5a3ed5fbad5496b7263bdc1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3905727
Auto-Submit: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/branch-heads/5249@{#518}
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
diff --git a/third_party/blink/renderer/core/css/css_variable_data.cc b/third_party/blink/renderer/core/css/css_variable_data.cc
index a2294cc70c59ac0357dddf0f7719cc3c09d23554..b3a61b312eb5f0360e8aa4cb706c60f0085fead9 100644
--- a/third_party/blink/renderer/core/css/css_variable_data.cc
+++ b/third_party/blink/renderer/core/css/css_variable_data.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/css/css_variable_data.h"
+#include "base/containers/span.h"
#include "third_party/blink/renderer/core/css/css_syntax_definition.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
@@ -109,6 +110,51 @@ void CSSVariableData::ConsumeAndUpdateTokens(const CSSParserTokenRange& range) {
UpdateTokens<UChar>(range, backing_string, tokens_);
}
+#if EXPENSIVE_DCHECKS_ARE_ON()
+
+namespace {
+
+template <typename CharacterType>
+bool IsSubspan(base::span<const CharacterType> inner,
+ base::span<const CharacterType> outer) {
+ // Note that base::span uses CheckedContiguousIterator, which restricts
+ // which comparisons are allowed. Therefore we must avoid begin()/end() here.
+ return inner.data() >= outer.data() &&
+ (inner.data() + inner.size()) <= (outer.data() + outer.size());
+}
+
+bool TokenValueIsBacked(const CSSParserToken& token,
+ const String& backing_string) {
+ StringView value = token.Value();
+ if (value.Is8Bit() != backing_string.Is8Bit())
+ return false;
+ return value.Is8Bit() ? IsSubspan(value.Span8(), backing_string.Span8())
+ : IsSubspan(value.Span16(), backing_string.Span16());
+}
+
+bool TokenValueIsBacked(const CSSParserToken& token,
+ const Vector<String>& backing_strings) {
+ DCHECK(token.HasStringBacking());
+ for (const String& backing_string : backing_strings) {
+ if (TokenValueIsBacked(token, backing_string)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+void CSSVariableData::VerifyStringBacking() const {
+ for (const CSSParserToken& token : tokens_) {
+ DCHECK(!token.HasStringBacking() ||
+ TokenValueIsBacked(token, backing_strings_))
+ << "Token value is not backed: " << token.Value().ToString();
+ }
+}
+
+#endif // EXPENSIVE_DCHECKS_ARE_ON()
+
CSSVariableData::CSSVariableData(const CSSTokenizedValue& tokenized_value,
bool is_animation_tainted,
bool needs_variable_resolution,
@@ -120,6 +166,9 @@ CSSVariableData::CSSVariableData(const CSSTokenizedValue& tokenized_value,
base_url_(base_url.IsValid() ? base_url.GetString() : String()),
charset_(charset) {
ConsumeAndUpdateTokens(tokenized_value.range);
+#if EXPENSIVE_DCHECKS_ARE_ON()
+ VerifyStringBacking();
+#endif // EXPENSIVE_DCHECKS_ARE_ON()
}
const CSSValue* CSSVariableData::ParseForSyntax(
diff --git a/third_party/blink/renderer/core/css/css_variable_data.h b/third_party/blink/renderer/core/css/css_variable_data.h
index f042f85736c2c49f8337c29cb742976c5e97a14b..7be7d201313ec3e591e2c45c9fd5bda327856645 100644
--- a/third_party/blink/renderer/core/css/css_variable_data.h
+++ b/third_party/blink/renderer/core/css/css_variable_data.h
@@ -100,11 +100,18 @@ class CORE_EXPORT CSSVariableData : public RefCounted<CSSVariableData> {
has_font_units_(has_font_units),
has_root_font_units_(has_root_font_units),
base_url_(base_url),
- charset_(charset) {}
+ charset_(charset) {
+#if EXPENSIVE_DCHECKS_ARE_ON()
+ VerifyStringBacking();
+#endif // EXPENSIVE_DCHECKS_ARE_ON()
+ }
CSSVariableData(const CSSVariableData&) = delete;
CSSVariableData& operator=(const CSSVariableData&) = delete;
void ConsumeAndUpdateTokens(const CSSParserTokenRange&);
+#if EXPENSIVE_DCHECKS_ARE_ON()
+ void VerifyStringBacking() const;
+#endif // EXPENSIVE_DCHECKS_ARE_ON()
// tokens_ may have raw pointers to string data, we store the String objects
// owning that data in backing_strings_ to keep it alive alongside the
diff --git a/third_party/blink/renderer/core/css/parser/css_tokenizer.h b/third_party/blink/renderer/core/css/parser/css_tokenizer.h
index 817bcbd4b6b9a9a5519bb92d6870c5b16a19278f..682a44a478bcd0ee3aa1638601650fd420033625 100644
--- a/third_party/blink/renderer/core/css/parser/css_tokenizer.h
+++ b/third_party/blink/renderer/core/css/parser/css_tokenizer.h
@@ -33,6 +33,7 @@ class CORE_EXPORT CSSTokenizer {
wtf_size_t Offset() const { return input_.Offset(); }
wtf_size_t PreviousOffset() const { return prev_offset_; }
StringView StringRangeAt(wtf_size_t start, wtf_size_t length) const;
+ const Vector<String>& StringPool() const { return string_pool_; }
private:
CSSParserToken TokenizeSingle();
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index ae863c8df923f55b116ed1c70557e5d5916794d3..dbc654e9079f4f79fe6883a6ea34e8fa00e1a26f 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -2170,6 +2170,10 @@ StyleBuilderConverter::ConvertRegisteredPropertyVariableData(
Vector<String> backing_strings;
backing_strings.push_back(text);
+ // CSSTokenizer may allocate new strings for some tokens (e.g. for escapes)
+ // and produce tokens that point to those strings. We need to retain those
+ // strings (if any) as well.
+ backing_strings.AppendVector(tokenizer.StringPool());
const bool has_font_units = false;
const bool has_root_font_units = false;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt
index 3823a752b99f506d11c50aee36474c6c51c849cd..eeed0dfc0def17b1ba636f7f6a076caf770e1327 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt
@@ -1,5 +1,5 @@
This is a testharness.js-based test.
-Found 60 tests; 59 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 61 tests; 60 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS <length> values computed are correctly via var()-reference
PASS <length> values computed are correctly via var()-reference when font-size is inherited
PASS <length> values are computed correctly when font-size is inherited [14em]
@@ -60,5 +60,6 @@ PASS * values are computed correctly [50dpi]
PASS <resolution> values are computed correctly [1dppx]
PASS <resolution> values are computed correctly [96dpi]
FAIL <resolution> values are computed correctly [calc(1dppx + 96dpi)] assert_equals: expected "2dppx" but got "0dppx"
+PASS * values are computed correctly [url(why)]
Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation.html b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation.html
index f03b257246e520bd93055203a5cb27188babc8ca..168495247a3b16a2203fb361f662b6db83044d09 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/registered-property-computation.html
@@ -167,4 +167,6 @@ test_computed_value('<resolution>', '1dppx', '1dppx');
test_computed_value('<resolution>', '96dpi', '1dppx');
test_computed_value('<resolution>', 'calc(1dppx + 96dpi)', '2dppx');
+test_computed_value('*', 'url(why)', 'url(why)');
+
</script>

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yutaka Hirano <yhirano@chromium.org>
Date: Mon, 4 Jul 2022 11:48:20 +0000
Subject: Fix UAF on network::URLLoader
network::URLLoader::SetUpUpload calls NotifyCompleted asynchronously,
as it can be called in the constructor and we don't want to run
NotifyCompleted in the constructor.
The problem is that it attaches a raw pointer to the method, which leads to a use-after-free problem if the URLLoader is destructed before
NotifyCompleted is called.
Use weak pointers instead of raw pointers to avoid the problem.
Bug: 1340253
Change-Id: Iacb1e772bf7a8e3de4a7bb9de342fea9ba0f3f3c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3740150
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1020539}
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index dbe9e809898ee720c0670e9c6db73c38658613b2..666e82ee2f14a77592b52159ee81a2029de28172 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -793,8 +793,8 @@ void URLLoader::OpenFilesForUpload(const ResourceRequest& request) {
// initializing before getting deleted.
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(&URLLoader::NotifyCompleted, base::Unretained(this),
- net::ERR_ACCESS_DENIED));
+ base::BindOnce(&URLLoader::NotifyCompleted,
+ weak_ptr_factory_.GetWeakPtr(), net::ERR_ACCESS_DENIED));
return;
}
url_request_->LogBlockedBy("Opening Files");
@@ -813,7 +813,7 @@ void URLLoader::SetUpUpload(const ResourceRequest& request,
// initializing before getting deleted.
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&URLLoader::NotifyCompleted,
- base::Unretained(this), error_code));
+ weak_ptr_factory_.GetWeakPtr(), error_code));
return;
}
scoped_refptr<base::SequencedTaskRunner> task_runner =

View File

@@ -0,0 +1,675 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lukasz Anforowicz <lukasza@chromium.org>
Date: Tue, 30 Aug 2022 19:18:15 +0000
Subject: Validate `source_context` in ExtensionHostMsg_OpenChannelToNativeApp.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
After this CL, the Browser process will verify `source_context` in the
IPC payload of the ExtensionHostMsg_OpenChannelToNativeApp message and
avoid processing malformed or spoofed IPCs.
Change-Id: I9466dc076c4d07dbb4bec38973000dc0418565f6
Bug: 1356234
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3854987
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
Reviewed-by: Devlin Cronin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1041118}
diff --git a/chrome/browser/extensions/extension_security_exploit_browsertest.cc b/chrome/browser/extensions/extension_security_exploit_browsertest.cc
index d4c4c8fc301940bbeba31bc49ba63961db92a7ed..2ef2f61da9ae3ed7736575424dd5cbb50eca6a3b 100644
--- a/chrome/browser/extensions/extension_security_exploit_browsertest.cc
+++ b/chrome/browser/extensions/extension_security_exploit_browsertest.cc
@@ -10,6 +10,7 @@
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/test/bind.h"
+#include "build/build_config.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_tab_util.h"
@@ -40,6 +41,10 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_database.mojom-forward.h"
#include "url/gurl.h"
+#if !(BUILDFLAG(IS_FUCHSIA))
+#include "chrome/browser/extensions/api/messaging/native_messaging_test_util.h"
+#endif
+
namespace extensions {
// Waits for a kill of the given RenderProcessHost and returns the
@@ -233,6 +238,10 @@ class OpenChannelToExtensionExploitTest : public ExtensionBrowserTest {
return ipc_message_waiter_->WaitForMessage();
}
+ content::WebContents* active_web_contents() {
+ return browser()->tab_strip_model()->GetActiveWebContents();
+ }
+
// Asks the `extension_id` to inject `content_script` into `web_contents`.
// Returns true if the content script execution started successfully.
bool ExecuteProgrammaticContentScript(content::WebContents* web_contents,
@@ -246,61 +255,88 @@ class OpenChannelToExtensionExploitTest : public ExtensionBrowserTest {
browser()->profile(), extension_id, background_script);
}
+ const Extension& active_extension() { return *active_extension_; }
const ExtensionId& active_extension_id() { return active_extension_->id(); }
const ExtensionId& spoofed_extension_id() { return spoofed_extension_->id(); }
private:
+ // Installs an `active_extension` and a separate, but otherwise identical
+ // `spoofed_extension` (the only difference will be the extension id).
void InstallTestExtensions() {
- // Install an `active_extension` and a separate, but otherwise identical
- // `spoofed_extension` (the only difference will be the extension id).
- auto install_extension = [this](TestExtensionDir& dir) -> const Extension* {
+ auto install_extension =
+ [this](TestExtensionDir& dir,
+ const char* extra_manifest_bits) -> const Extension* {
const char kManifestTemplate[] = R"(
{
+ %s
"name": "ContentScriptTrackerBrowserTest - Programmatic",
"version": "1.0",
"manifest_version": 2,
+ "permissions": [ "tabs", "<all_urls>", "storage" ],
+ "permissions": [
+ "tabs",
+ "<all_urls>",
+ "nativeMessaging"
+ ],
"permissions": [ "tabs", "<all_urls>" ],
"background": {"scripts": ["background_script.js"]}
} )";
- dir.WriteManifest(kManifestTemplate);
+ dir.WriteManifest(
+ base::StringPrintf(kManifestTemplate, extra_manifest_bits));
dir.WriteFile(FILE_PATH_LITERAL("background_script.js"), "");
+ dir.WriteFile(FILE_PATH_LITERAL("page.html"), "<p>page</p>");
return LoadExtension(dir.UnpackedPath());
};
- TestExtensionDir active_dir;
- TestExtensionDir spoofed_dir;
- active_extension_ = install_extension(active_dir);
- spoofed_extension_ = install_extension(spoofed_dir);
+#if !(BUILDFLAG(IS_FUCHSIA))
+ // The key below corresponds to the extension ID used by
+ // ScopedTestNativeMessagingHost::kExtensionId.
+ const char kActiveExtensionKey[] = R"(
+ "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaYhSpDCE9RPocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB",
+ )";
+#else
+ // Native messaging is not available on Fuchsia (i.e.
+ // //chrome/browser/extensions/BUILD.gn excludes
+ // api/messaging/native_messaging_test_util.h on Fuchsia).
+ const char kActiveExtensionKey[] = "";
+#endif
+ active_extension_ = install_extension(active_dir_, kActiveExtensionKey);
+ spoofed_extension_ = install_extension(spoofed_dir_, "");
ASSERT_TRUE(active_extension_);
ASSERT_TRUE(spoofed_extension_);
+#if !(BUILDFLAG(IS_FUCHSIA))
+ ASSERT_EQ(active_extension_id(),
+ ScopedTestNativeMessagingHost::kExtensionId);
+#endif
ASSERT_NE(active_extension_id(), spoofed_extension_id());
}
using OpenChannelMessageWaiter =
ExtensionMessageWaiter<ExtensionHostMsg_OpenChannelToExtension>;
- std::unique_ptr<OpenChannelMessageWaiter> StartInterceptingIpcs(
- const GURL& test_page_url) {
// Start capturing IPC messages in all future/new RenderProcessHosts.
- auto ipc_message_waiter = std::make_unique<OpenChannelMessageWaiter>();
+ ipc_message_waiter_ = std::make_unique<OpenChannelMessageWaiter>();
// Navigate to an arbitrary, mostly empty test page. Make sure that a new
// RenderProcessHost is created to make sure it is covered by the
- // `ipc_message_waiter`. (A WebUI -> http navigation should swap the
+ // `ipc_message_waiter_`. (A WebUI -> http navigation should swap the
// RenderProcessHost on all platforms.)
- content::WebContents* web_contents =
- browser()->tab_strip_model()->GetActiveWebContents();
- int old_process_id = web_contents->GetMainFrame()->GetProcess()->GetID();
+ GURL test_page_url =
+ embedded_test_server()->GetURL("foo.com", "/title1.html");
+ int old_process_id =
+ active_web_contents()->GetMainFrame()->GetProcess()->GetID();
EXPECT_TRUE(
ui_test_utils::NavigateToURL(browser(), GURL("chrome://version")));
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url));
- int new_process_id = web_contents->GetMainFrame()->GetProcess()->GetID();
+ int new_process_id =
+ active_web_contents()->GetMainFrame()->GetProcess()->GetID();
EXPECT_NE(old_process_id, new_process_id);
// Only intercept messages from `active_extension`'s content script running
// in the main frame's process.
std::string matching_extension_id = active_extension_id();
- int matching_process_id = new_process_id;
- ipc_message_waiter->SetIpcMatcher(base::BindLambdaForTesting(
+ int matching_process_id =
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
+ ipc_message_waiter_->SetIpcMatcher(base::BindLambdaForTesting(
[matching_extension_id, matching_process_id](
int captured_render_process_id,
const ExtensionHostMsg_OpenChannelToExtension::Param& param) {
@@ -317,14 +353,21 @@ class OpenChannelToExtensionExploitTest : public ExtensionBrowserTest {
return true;
}));
+ }
- return ipc_message_waiter;
+ // Waits for ExtensionHostMsg_OpenChannelToExtension IPC and returns its
+ // payload.
+ ExtensionHostMsg_OpenChannelToExtension::Param WaitForMessage() {
+ return ipc_message_waiter_->WaitForMessage();
}
+ private:
std::unique_ptr<OpenChannelMessageWaiter> ipc_message_waiter_;
raw_ptr<const Extension> active_extension_ = nullptr;
raw_ptr<const Extension> spoofed_extension_ = nullptr;
+ TestExtensionDir active_dir_;
+ TestExtensionDir spoofed_dir_;
};
IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
@@ -338,24 +381,22 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
// from a content script of an `active_extension_id`.
- content::WebContents* web_contents =
- browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(ExecuteProgrammaticContentScript(
- web_contents, active_extension_id(),
+ active_web_contents(), active_extension_id(),
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
// Capture the IPC.
auto [source_context, info, channel_name, port_id] = WaitForMessage();
-
- // Mutate the IPC payload.
EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
EXPECT_EQ(active_extension_id(), info.source_endpoint.extension_id);
+
+ // Mutate the IPC payload.
info.source_endpoint.extension_id = spoofed_extension_id();
// Inject the malformed/mutated IPC and verify that the renderer is terminated
// as expected.
content::RenderProcessHost* main_frame_process =
- web_contents->GetMainFrame()->GetProcess();
+ active_web_contents()->GetMainFrame()->GetProcess();
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
IPC::IpcSecurityTestUtil::PwnMessageReceived(
main_frame_process->GetChannel(),
@@ -369,24 +410,22 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
FromContentScript_UnexpectedNativeAppType) {
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
// from a content script of an `active_extension_id`.
- content::WebContents* web_contents =
- browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(ExecuteProgrammaticContentScript(
- web_contents, active_extension_id(),
+ active_web_contents(), active_extension_id(),
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
// Capture the IPC.
auto [source_context, info, channel_name, port_id] = WaitForMessage();
-
- // Mutate the IPC payload.
EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
EXPECT_EQ(active_extension_id(), info.source_endpoint.extension_id);
+
+ // Mutate the IPC payload.
info.source_endpoint.type = MessagingEndpoint::Type::kNativeApp;
// Inject the malformed/mutated IPC and verify that the renderer is terminated
// as expected.
content::RenderProcessHost* main_frame_process =
- web_contents->GetMainFrame()->GetProcess();
+ active_web_contents()->GetMainFrame()->GetProcess();
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
IPC::IpcSecurityTestUtil::PwnMessageReceived(
main_frame_process->GetChannel(),
@@ -399,24 +438,22 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
FromContentScript_UnexpectedExtensionType) {
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
// from a content script of an `active_extension_id`.
- content::WebContents* web_contents =
- browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(ExecuteProgrammaticContentScript(
- web_contents, active_extension_id(),
+ active_web_contents(), active_extension_id(),
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
// Capture the IPC.
auto [source_context, info, channel_name, port_id] = WaitForMessage();
-
- // Mutate the IPC payload.
EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
EXPECT_EQ(active_extension_id(), info.source_endpoint.extension_id);
+
+ // Mutate the IPC payload.
info.source_endpoint.type = MessagingEndpoint::Type::kExtension;
// Inject the malformed/mutated IPC and verify that the renderer is terminated
// as expected.
content::RenderProcessHost* main_frame_process =
- web_contents->GetMainFrame()->GetProcess();
+ active_web_contents()->GetMainFrame()->GetProcess();
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
IPC::IpcSecurityTestUtil::PwnMessageReceived(
main_frame_process->GetChannel(),
@@ -430,25 +467,23 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
FromContentScript_NoExtensionIdForExtensionType) {
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
// from a content script of an `active_extension_id`.
- content::WebContents* web_contents =
- browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(ExecuteProgrammaticContentScript(
- web_contents, active_extension_id(),
+ active_web_contents(), active_extension_id(),
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
// Capture the IPC.
auto [source_context, info, channel_name, port_id] = WaitForMessage();
-
- // Mutate the IPC payload.
EXPECT_EQ(MessagingEndpoint::Type::kTab, info.source_endpoint.type);
EXPECT_EQ(active_extension_id(), info.source_endpoint.extension_id);
+
+ // Mutate the IPC payload.
info.source_endpoint.type = MessagingEndpoint::Type::kExtension;
info.source_endpoint.extension_id = absl::nullopt;
// Inject the malformed/mutated IPC and verify that the renderer is terminated
// as expected.
content::RenderProcessHost* main_frame_process =
- web_contents->GetMainFrame()->GetProcess();
+ active_web_contents()->GetMainFrame()->GetProcess();
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
IPC::IpcSecurityTestUtil::PwnMessageReceived(
main_frame_process->GetChannel(),
@@ -462,18 +497,16 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
FromContentScript_UnexpectedWorkerContext) {
// Trigger sending of a valid ExtensionHostMsg_OpenChannelToExtension IPC
// from a content script of an `active_extension_id`.
- content::WebContents* web_contents =
- browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(ExecuteProgrammaticContentScript(
- web_contents, active_extension_id(),
+ active_web_contents(), active_extension_id(),
"chrome.runtime.sendMessage({greeting: 'hello'}, (response) => {});"));
// Capture the IPC.
auto [source_context, info, channel_name, port_id] = WaitForMessage();
-
- // Mutate the IPC payload.
EXPECT_TRUE(source_context.is_for_render_frame());
EXPECT_FALSE(source_context.is_for_service_worker());
+
+ // Mutate the IPC payload.
source_context.frame = absl::nullopt;
source_context.worker = PortContext::WorkerContext(
/* thread_id = */ 123, /* version_id = */ 456,
@@ -482,7 +515,7 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
// Inject the malformed/mutated IPC and verify that the renderer is terminated
// as expected.
content::RenderProcessHost* main_frame_process =
- web_contents->GetMainFrame()->GetProcess();
+ active_web_contents()->GetMainFrame()->GetProcess();
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
IPC::IpcSecurityTestUtil::PwnMessageReceived(
main_frame_process->GetChannel(),
@@ -492,4 +525,148 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
kill_waiter.Wait());
}
+// Native messaging is not available on Fuchsia (i.e.
+// //chrome/browser/extensions/BUILD.gn excludes
+// api/messaging/native_messaging_test_util.h on Fuchsia).
+#if !(BUILDFLAG(IS_FUCHSIA))
+
+// Test suite for covering ExtensionHostMsg_OpenChannelToNativeApp IPC.
+class OpenChannelToNativeAppExploitTest
+ : public ExtensionSecurityExploitBrowserTest {
+ public:
+ OpenChannelToNativeAppExploitTest() = default;
+
+ using OpenChannelMessageWaiter =
+ ExtensionMessageWaiter<ExtensionHostMsg_OpenChannelToNativeApp>;
+ void SetUpOnMainThread() override {
+ // Set up ExtensionMessageWaiter *before* installing the extensions (i.e.
+ // *before* the corresponding RenderProcessHost objects are created).
+ ipc_message_waiter_ = std::make_unique<OpenChannelMessageWaiter>();
+
+ // SetUpOnMainThread in the base class will install the test extensions.
+ ExtensionSecurityExploitBrowserTest::SetUpOnMainThread();
+
+ // Register a (fake, test-only) native messaging host.
+ test_native_messaging_host_.RegisterTestHost(/* user_level= */ false);
+
+ // Navigate the test tab to an extension page.
+ GURL test_page_url = active_extension().GetResourceURL("page.html");
+ EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url));
+
+ // Only intercept messages from the test process.
+ int matching_process_id =
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
+ ipc_message_waiter_->SetIpcMatcher(base::BindLambdaForTesting(
+ [matching_process_id](
+ int captured_render_process_id,
+ const ExtensionHostMsg_OpenChannelToNativeApp::Param& param) {
+ if (captured_render_process_id != matching_process_id)
+ return false;
+
+ return true;
+ }));
+ }
+
+ // Waits for ExtensionHostMsg_OpenChannelToNativeApp IPC and returns its
+ // payload.
+ ExtensionHostMsg_OpenChannelToNativeApp::Param WaitForMessage() {
+ return ipc_message_waiter_->WaitForMessage();
+ }
+
+ private:
+ ScopedTestNativeMessagingHost test_native_messaging_host_;
+ std::unique_ptr<OpenChannelMessageWaiter> ipc_message_waiter_;
+};
+
+IN_PROC_BROWSER_TEST_F(OpenChannelToNativeAppExploitTest,
+ SourceContextWithSpoofedExtensionId) {
+ // Trigger sending of a valid ExtensionHostMsg_OpenChannelToNativeApp IPC
+ // from a frame of an `active_extension`.
+ const char kScript[] = R"(
+ var message = {text: 'Hello!'};
+ var host = $1;
+ chrome.runtime.sendNativeMessage(host, message);
+ )";
+ ASSERT_EQ(
+ active_extension().origin(),
+ active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
+ ASSERT_TRUE(content::ExecuteScript(
+ active_web_contents(),
+ content::JsReplace(kScript, ScopedTestNativeMessagingHost::kHostName)));
+
+ // Capture the IPC.
+ auto [source_context, native_app_name, port_id] = WaitForMessage();
+ EXPECT_EQ(native_app_name, ScopedTestNativeMessagingHost::kHostName);
+ EXPECT_TRUE(source_context.is_for_render_frame());
+
+ // Mutate the IPC payload.
+ source_context = PortContext::ForWorker(123, // thread_id
+ 456, // version_id
+ spoofed_extension_id());
+
+ // Inject the malformed/mutated IPC and verify that the renderer is terminated
+ // as expected.
+ content::RenderProcessHost* main_frame_process =
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
+ RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
+ IPC::IpcSecurityTestUtil::PwnMessageReceived(
+ main_frame_process->GetChannel(),
+ ExtensionHostMsg_OpenChannelToNativeApp(source_context, native_app_name,
+ port_id));
+ EXPECT_EQ(bad_message::EMF_INVALID_EXTENSION_ID_FOR_WORKER_CONTEXT,
+ kill_waiter.Wait());
+}
+
+#endif // !(BUILDFLAG(IS_FUCHSIA)) - native messaging is available
+
+IN_PROC_BROWSER_TEST_F(ExtensionSecurityExploitBrowserTest,
+ SpoofedExtensionId_ExtensionFunctionDispatcher) {
+ // Navigate to a test page.
+ GURL test_page_url =
+ embedded_test_server()->GetURL("foo.com", "/title1.html");
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url));
+ content::RenderFrameHost* main_frame =
+ active_web_contents()->GetPrimaryMainFrame();
+
+ // Verify the test setup by checking if the non-intercepted `chrome.storage`
+ // API call will succeed.
+ {
+ ExtensionTestMessageListener listener("Got chrome.storage response");
+ ExecuteProgrammaticContentScript(active_web_contents(),
+ active_extension_id(), R"(
+ chrome.storage.local.set(
+ { test_key: 'test value'},
+ () => {
+ chrome.test.sendMessage('Got chrome.storage response');
+ }
+ ); )");
+ ASSERT_TRUE(listener.WaitUntilSatisfied());
+ }
+
+ // Prepare to mutate the extension id in the IPC associated with the
+ // `chrome.storage.local.set`.
+ auto interceptor = std::make_unique<ExtensionFrameHostInterceptor>(
+ main_frame,
+ base::BindLambdaForTesting([this](mojom::RequestParams& request_params) {
+ if (request_params.name != "storage.set")
+ return;
+
+ EXPECT_EQ(active_extension_id(), request_params.extension_id);
+ request_params.extension_id = spoofed_extension_id();
+ }));
+
+ // Trigger an IPC associated with the `chrome.storage.local.set` API and
+ // verify that the mutated/spoofed extension id is detected and leads to
+ // terminating the misbehaving renderer process.
+ content::RenderProcessHostBadMojoMessageWaiter kill_waiter(
+ main_frame->GetProcess());
+ ExecuteProgrammaticContentScript(active_web_contents(), active_extension_id(),
+ R"(
+ chrome.storage.local.set({ test_key: 'test value2'}, () => {}); )");
+ EXPECT_EQ(
+ "Received bad user message: LocalFrameHost::Request: renderer never "
+ "hosted such extension",
+ kill_waiter.Wait());
+}
+
} // namespace extensions
diff --git a/docs/security/compromised-renderers.md b/docs/security/compromised-renderers.md
index b7e56be454f2d42dc4ae4ac875586a01f2354d9a..2155a399e0e432fedc2792b6893440efd7fca572 100644
--- a/docs/security/compromised-renderers.md
+++ b/docs/security/compromised-renderers.md
@@ -213,14 +213,21 @@ Compromised renderers shouldnt be able to:
- Spoof the `MessageEvent.origin` seen by a recipient of a `postMessage`.
- Bypass enforcement of the `targetOrigin` argument of `postMessage`.
- Send or receive `BroadcastChannel` messages for another origin.
-- Spoof the `MessageSender.origin` seen by a recipient of a
- `chrome.runtime.sendMessage`
- (see also [MessageSender documentation](https://developers.chrome.com/extensions/runtime#type-MessageSender) and [content script security guidance](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/0ei-UCHNm34)).
+- Spoof the `MessageSender.origin`, nor `MessageSender.id` (i.e. an
+ extension id which can differ from the origin when the message is sent
+ from a content script), as seen by a recipient of a
+ `chrome.runtime.sendMessage`.
+ See also [MessageSender documentation](https://developers.chrome.com/extensions/runtime#type-MessageSender) and [content script security guidance](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/0ei-UCHNm34).
+- Spoof the id of a Chrome extension initiating
+ [native messaging](https://developer.chrome.com/docs/apps/nativeMessaging/)
+ communication.
Protection techniques:
- Using `CanAccessDataForOrigin` to verify IPCs sent by a renderer process
(e.g. in `RenderFrameProxyHost::OnRouteMessageEvent` or
`BroadcastChannelProvider::ConnectToChannel`).
+- Using `ContentScriptTracker` to check if IPCs from a given renderer process
+ can legitimately claim to act on behalf content scripts of a given extension.
**Known gaps in protection**:
- Spoofing of `MessageSender.id` object
diff --git a/extensions/browser/api/messaging/messaging_api_message_filter.cc b/extensions/browser/api/messaging/messaging_api_message_filter.cc
index 5469f5e91bfbb98aece208e9fffa8139dc9dacdf..e57cffb46d74229fff2534f7bb9f9fa3ddbc3d26 100644
--- a/extensions/browser/api/messaging/messaging_api_message_filter.cc
+++ b/extensions/browser/api/messaging/messaging_api_message_filter.cc
@@ -156,6 +156,16 @@ bool IsValidSourceContext(RenderProcessHost& process,
}
}
+ // This function doesn't validate frame-flavoured `source_context`s, because
+ // PortContext::FrameContext only contains frame's `routing_id` and therefore
+ // inherently cannot spoof frames in another process (a frame is identified
+ // by its `routing_id` *and* the `process_id` of the Renderer process hosting
+ // the frame; the latter is trustworthy / doesn't come from an IPC payload).
+
+ // This function doesn't validate native app `source_context`s, because
+ // `PortContext::ForNativeHost()` is called with trustoworthy inputs (e.g. it
+ // doesn't take input from IPCs sent by a Renderer process).
+
return true;
}
@@ -227,6 +237,18 @@ void MessagingAPIMessageFilter::Shutdown() {
shutdown_notifier_subscription_ = {};
}
+content::RenderProcessHost* MessagingAPIMessageFilter::GetRenderProcessHost() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!browser_context_)
+ return nullptr;
+
+ // The IPC might race with RenderProcessHost destruction. This may only
+ // happen in scenarios that are already inherently racey, so returning nullptr
+ // (and dropping the IPC) is okay and won't lead to any additional risk of
+ // data loss.
+ return content::RenderProcessHost::FromID(render_process_id_);
+}
+
void MessagingAPIMessageFilter::OverrideThreadForMessage(
const IPC::Message& message,
BrowserThread::ID* thread) {
@@ -272,19 +294,14 @@ void MessagingAPIMessageFilter::OnOpenChannelToExtension(
const std::string& channel_name,
const PortId& port_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!browser_context_)
- return;
-
- // The IPC might race with RenderProcessHost destruction. This may only
- // happen in scenarios that are already inherently racey, so dropping the IPC
- // is okay and won't lead to any additional risk of data loss.
- auto* process = content::RenderProcessHost::FromID(render_process_id_);
+ auto* process = GetRenderProcessHost();
if (!process)
return;
TRACE_EVENT("extensions", "MessageFilter::OnOpenChannelToExtension",
ChromeTrackEvent::kRenderProcessHost, *process);
ScopedExternalConnectionInfoCrashKeys info_crash_keys(info);
+ debug::ScopedPortContextCrashKeys port_context_crash_keys(source_context);
if (!IsValidMessagingSource(*process, info.source_endpoint) ||
!IsValidSourceContext(*process, source_context)) {
return;
@@ -303,7 +320,14 @@ void MessagingAPIMessageFilter::OnOpenChannelToNativeApp(
const std::string& native_app_name,
const PortId& port_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!browser_context_)
+ auto* process = GetRenderProcessHost();
+ if (!process)
+ return;
+ TRACE_EVENT("extensions", "MessageFilter::OnOpenChannelToNativeApp",
+ ChromeTrackEvent::kRenderProcessHost, *process);
+
+ debug::ScopedPortContextCrashKeys port_context_crash_keys(source_context);
+ if (!IsValidSourceContext(*process, source_context))
return;
ChannelEndpoint source_endpoint(browser_context_, render_process_id_,
diff --git a/extensions/browser/api/messaging/messaging_api_message_filter.h b/extensions/browser/api/messaging/messaging_api_message_filter.h
index 6a0ccd698629f650d68f2b4ee168aa2b3b3a116c..3358187387cd9a5765a7bd4e522aeecfd787e06b 100644
--- a/extensions/browser/api/messaging/messaging_api_message_filter.h
+++ b/extensions/browser/api/messaging/messaging_api_message_filter.h
@@ -14,6 +14,7 @@ struct ExtensionMsg_TabTargetConnectionInfo;
namespace content {
class BrowserContext;
+class RenderProcessHost;
}
namespace extensions {
@@ -40,6 +41,11 @@ class MessagingAPIMessageFilter : public content::BrowserMessageFilter {
void Shutdown();
+ // Returns the process that the IPC came from, or `nullptr` if the IPC should
+ // be dropped (in case the IPC arrived racily after the process or its
+ // BrowserContext already got destructed).
+ content::RenderProcessHost* GetRenderProcessHost();
+
// content::BrowserMessageFilter implementation:
void OverrideThreadForMessage(const IPC::Message& message,
content::BrowserThread::ID* thread) override;
diff --git a/extensions/common/api/messaging/port_context.cc b/extensions/common/api/messaging/port_context.cc
index 6872179450d8295de7f15dc1437e9d6edefe4fde..319e2f34eca730c5eb7cf94ef8cdede0ddc3f8e1 100644
--- a/extensions/common/api/messaging/port_context.cc
+++ b/extensions/common/api/messaging/port_context.cc
@@ -40,4 +40,27 @@ PortContext PortContext::ForNativeHost() {
return PortContext();
}
+namespace debug {
+
+namespace {
+
+base::debug::CrashKeyString* GetServiceWorkerExtensionIdCrashKey() {
+ static auto* crash_key = base::debug::AllocateCrashKeyString(
+ "PortContext-worker-extension_id", base::debug::CrashKeySize::Size64);
+ return crash_key;
+}
+
+} // namespace
+
+ScopedPortContextCrashKeys::ScopedPortContextCrashKeys(
+ const PortContext& port_context) {
+ if (port_context.is_for_service_worker()) {
+ extension_id_.emplace(GetServiceWorkerExtensionIdCrashKey(),
+ port_context.worker->extension_id);
+ }
+}
+
+ScopedPortContextCrashKeys::~ScopedPortContextCrashKeys() = default;
+
+} // namespace debug
} // namespace extensions
diff --git a/extensions/common/api/messaging/port_context.h b/extensions/common/api/messaging/port_context.h
index b2e9f057b531d90dc256773959cd586953e4915c..53d94c2ad73c58d45b186a32989e2f4864e67d79 100644
--- a/extensions/common/api/messaging/port_context.h
+++ b/extensions/common/api/messaging/port_context.h
@@ -9,6 +9,7 @@
#include <string>
+#include "base/debug/crash_logging.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace extensions {
@@ -59,6 +60,19 @@ struct PortContext {
absl::optional<WorkerContext> worker;
};
+namespace debug {
+
+class ScopedPortContextCrashKeys {
+ public:
+ explicit ScopedPortContextCrashKeys(const PortContext& port_context);
+ ~ScopedPortContextCrashKeys();
+
+ private:
+ absl::optional<base::debug::ScopedCrashKeyString> extension_id_;
+};
+
+} // namespace debug
+
} // namespace extensions
#endif // EXTENSIONS_COMMON_API_MESSAGING_PORT_CONTEXT_H_

View File

@@ -0,0 +1,292 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peng Huang <penghuang@chromium.org>
Date: Wed, 23 Nov 2022 00:16:49 +0000
Subject: Fix potential OOB problem with validating command decoder
Bug: 1392715
Change-Id: If51b10cc08e5b3ca4b6012b97261347a5e4c134e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4048203
Auto-Submit: Peng Huang <penghuang@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1074966}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 4847ff3403f318d66b70eaa4444a90e5de8689f2..83055ae687e85fafb6c498aee471d58ecc47880a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -8655,10 +8655,18 @@ void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
service_id = texture_ref->service_id();
}
+ bool valid_target = false;
+ if (texture_ref) {
+ valid_target = texture_manager()->ValidForTextureTarget(
+ texture_ref->texture(), level, 0, 0, 1);
+ } else {
+ valid_target = texture_manager()->ValidForTarget(textarget, level, 0, 0, 1);
+ }
+
if ((level > 0 && !feature_info_->IsWebGL2OrES3Context() &&
!(fbo_render_mipmap_explicitly_enabled_ &&
feature_info_->feature_flags().oes_fbo_render_mipmap)) ||
- !texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
+ !valid_target) {
LOCAL_SET_GL_ERROR(
GL_INVALID_VALUE,
name, "level out of range");
@@ -8730,8 +8738,8 @@ void GLES2DecoderImpl::DoFramebufferTextureLayer(
"texture is neither TEXTURE_3D nor TEXTURE_2D_ARRAY");
return;
}
- if (!texture_manager()->ValidForTarget(texture_target, level,
- 0, 0, layer)) {
+ if (!texture_manager()->ValidForTextureTarget(texture_ref->texture(), level,
+ 0, 0, layer)) {
LOCAL_SET_GL_ERROR(
GL_INVALID_VALUE, function_name, "invalid level or layer");
return;
@@ -15112,11 +15120,6 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage(
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "imageSize < 0");
return error::kNoError;
}
- if (!texture_manager()->ValidForTarget(target, level, width, height, depth) ||
- border != 0) {
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
- return error::kNoError;
- }
TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
&state_, target);
if (!texture_ref) {
@@ -15125,6 +15128,12 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage(
return error::kNoError;
}
Texture* texture = texture_ref->texture();
+ if (!texture_manager()->ValidForTextureTarget(texture, level, width, height,
+ depth) ||
+ border != 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
+ return error::kNoError;
+ }
if (texture->IsImmutable()) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, "texture is immutable");
return error::kNoError;
@@ -15494,10 +15503,6 @@ error::Error GLES2DecoderImpl::DoCompressedTexSubImage(
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "imageSize < 0");
return error::kNoError;
}
- if (!texture_manager()->ValidForTarget(target, level, width, height, depth)) {
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
- return error::kNoError;
- }
TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
&state_, target);
if (!texture_ref) {
@@ -15505,7 +15510,14 @@ error::Error GLES2DecoderImpl::DoCompressedTexSubImage(
GL_INVALID_OPERATION, func_name, "no texture bound at target");
return error::kNoError;
}
+
Texture* texture = texture_ref->texture();
+ if (!texture_manager()->ValidForTextureTarget(texture, level, width, height,
+ depth)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, func_name, "dimensions out of range");
+ return error::kNoError;
+ }
+
GLenum type = 0;
GLenum internal_format = 0;
if (!texture->GetLevelType(target, level, &type, &internal_format)) {
@@ -15630,7 +15642,8 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
GL_INVALID_OPERATION, func_name, "texture is immutable");
return;
}
- if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
+ if (!texture_manager()->ValidForTextureTarget(texture, level, width, height,
+ 1) ||
border != 0) {
LOCAL_SET_GL_ERROR(
GL_INVALID_VALUE, func_name, "dimensions out of range");
@@ -18227,8 +18240,8 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
}
// Check that this type of texture is allowed.
- if (!texture_manager()->ValidForTarget(source_target, source_level,
- source_width, source_height, 1)) {
+ if (!texture_manager()->ValidForTextureTarget(
+ source_texture, source_level, source_width, source_height, 1)) {
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "Bad dimensions");
return;
}
@@ -18395,8 +18408,8 @@ void GLES2DecoderImpl::CopySubTextureHelper(const char* function_name,
}
// Check that this type of texture is allowed.
- if (!texture_manager()->ValidForTarget(source_target, source_level,
- source_width, source_height, 1)) {
+ if (!texture_manager()->ValidForTextureTarget(
+ source_texture, source_level, source_width, source_height, 1)) {
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
"source texture bad dimensions");
return;
@@ -18636,11 +18649,20 @@ void GLES2DecoderImpl::TexStorageImpl(GLenum target,
return;
}
}
+ TextureRef* texture_ref =
+ texture_manager()->GetTextureInfoForTarget(&state_, target);
+ if (!texture_ref) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
+ "unknown texture for target");
+ return;
+ }
+ Texture* texture = texture_ref->texture();
// The glTexStorage entry points require width, height, and depth to be
// at least 1, but the other texture entry points (those which use
- // ValidForTarget) do not. So we have to add an extra check here.
+ // ValidForTextureTarget) do not. So we have to add an extra check here.
bool is_invalid_texstorage_size = width < 1 || height < 1 || depth < 1;
- if (!texture_manager()->ValidForTarget(target, 0, width, height, depth) ||
+ if (!texture_manager()->ValidForTextureTarget(texture, 0, width, height,
+ depth) ||
is_invalid_texstorage_size) {
LOCAL_SET_GL_ERROR(
GL_INVALID_VALUE, function_name, "dimensions out of range");
@@ -18653,14 +18675,6 @@ void GLES2DecoderImpl::TexStorageImpl(GLenum target,
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "too many levels");
return;
}
- TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
- &state_, target);
- if (!texture_ref) {
- LOCAL_SET_GL_ERROR(
- GL_INVALID_OPERATION, function_name, "unknown texture for target");
- return;
- }
- Texture* texture = texture_ref->texture();
if (texture->IsAttachedToFramebuffer()) {
framebuffer_state_.clear_state_dirty = true;
}
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index b20b875b6b37c36623b41e648e393ded96bae93b..f5df8270a8192d36b95e619248c128167455ef46 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -1641,7 +1641,7 @@ void Texture::Update() {
return;
if (face_infos_.empty() ||
- static_cast<size_t>(base_level_) >= face_infos_[0].level_infos.size()) {
+ static_cast<size_t>(base_level_) >= MaxValidMipLevel()) {
texture_complete_ = false;
cube_complete_ = false;
return;
@@ -2028,8 +2028,7 @@ bool Texture::CanRenderTo(const FeatureInfo* feature_info, GLint level) const {
// the time.
if (face_infos_.size() == 6 && !cube_complete())
return false;
- DCHECK(level >= 0 &&
- level < static_cast<GLint>(face_infos_[0].level_infos.size()));
+ DCHECK(level >= 0 && level < static_cast<GLint>(MaxValidMipLevel()));
if (level > base_level_ && !texture_complete()) {
return false;
}
@@ -2064,7 +2063,7 @@ void Texture::SetCompatibilitySwizzle(const CompatibilitySwizzle* swizzle) {
void Texture::ApplyFormatWorkarounds(const FeatureInfo* feature_info) {
if (feature_info->gl_version_info().NeedsLuminanceAlphaEmulation()) {
- if (static_cast<size_t>(base_level_) >= face_infos_[0].level_infos.size())
+ if (static_cast<size_t>(base_level_) >= MaxValidMipLevel())
return;
const Texture::LevelInfo& info = face_infos_[0].level_infos[base_level_];
SetCompatibilitySwizzle(GetCompatibilitySwizzleInternal(info.format));
@@ -2298,8 +2297,11 @@ scoped_refptr<TextureRef>
return default_texture;
}
-bool TextureManager::ValidForTarget(
- GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth) {
+bool TextureManager::ValidForTarget(GLenum target,
+ GLint level,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth) {
if (level < 0 || level >= MaxLevelsForTarget(target))
return false;
GLsizei max_size = MaxSizeForTarget(target) >> level;
@@ -2319,6 +2321,18 @@ bool TextureManager::ValidForTarget(
(target != GL_TEXTURE_2D || (depth == 1));
}
+bool TextureManager::ValidForTextureTarget(const Texture* texture,
+ GLint level,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth) {
+ if (texture->target() == 0)
+ return false;
+ if (level < 0 || static_cast<size_t>(level) >= texture->MaxValidMipLevel())
+ return false;
+ return ValidForTarget(texture->target(), level, width, height, depth);
+}
+
void TextureManager::SetTarget(TextureRef* ref, GLenum target) {
DCHECK(ref);
ref->texture()->SetTarget(target, MaxLevelsForTarget(target));
@@ -2802,14 +2816,6 @@ bool TextureManager::ValidateTexImage(ContextState* state,
args.internal_format, args.level)) {
return false;
}
- if (!ValidForTarget(args.target, args.level,
- args.width, args.height, args.depth) ||
- args.border != 0) {
- ERRORSTATE_SET_GL_ERROR(
- error_state, GL_INVALID_VALUE, function_name,
- "dimensions out of range");
- return false;
- }
if ((GLES2Util::GetChannelsForFormat(args.format) &
(GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && args.pixels
&& !feature_info_->IsWebGL2OrES3Context()) {
@@ -2832,7 +2838,13 @@ bool TextureManager::ValidateTexImage(ContextState* state,
"texture is immutable");
return false;
}
-
+ if (!ValidForTextureTarget(local_texture_ref->texture(), args.level,
+ args.width, args.height, args.depth) ||
+ args.border != 0) {
+ ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_VALUE, function_name,
+ "dimensions out of range");
+ return false;
+ }
Buffer* buffer = state->bound_pixel_unpack_buffer.get();
if (buffer) {
if (buffer->GetMappedRange()) {
diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
index c78c914cbad58abb17439354eeb9f77a9891f21d..8f68e70e6d1c9a4b75f6bec0df7179320bc167c0 100644
--- a/gpu/command_buffer/service/texture_manager.h
+++ b/gpu/command_buffer/service/texture_manager.h
@@ -470,6 +470,11 @@ class GPU_GLES2_EXPORT Texture final : public TextureBase {
sampler_state_.min_filter != GL_LINEAR;
}
+ size_t MaxValidMipLevel() const {
+ DCHECK(!face_infos_.empty());
+ return face_infos_[0].level_infos.size();
+ }
+
private:
friend class MailboxManagerTest;
friend class TextureManager;
@@ -932,6 +937,11 @@ class GPU_GLES2_EXPORT TextureManager
bool ValidForTarget(
GLenum target, GLint level,
GLsizei width, GLsizei height, GLsizei depth);
+ bool ValidForTextureTarget(const Texture* texture,
+ GLint level,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
// True if this texture meets all the GLES2 criteria for rendering.
// See section 3.8.2 of the GLES2 spec.

View File

@@ -0,0 +1,115 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christoph Schwering <schwering@google.com>
Date: Fri, 4 Nov 2022 00:56:32 +0000
Subject: Handle misaligned FormData, FormStructure.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This CL handles the case where the fields of the cached FormStructure
and the FormData are misaligned in
BrowserAutofillManager::WillFillCreditCardNumber.
(cherry picked from commit 1ad751f7dfa30a12a85824c291394b73c5c47eff)
Bug: 1376637, 1376639
Change-Id: Id7c3357a274b4d6624009ecf52b95a24cf3bfa1d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3965141
Commit-Queue: Christoph Schwering <schwering@google.com>
Quick-Run: Christoph Schwering <schwering@google.com>
Reviewed-by: Dominic Battré <battre@chromium.org>
Auto-Submit: Christoph Schwering <schwering@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#1061790}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4003032
Commit-Queue: Dominic Battré <battre@chromium.org>
Cr-Commit-Position: refs/branch-heads/5249@{#907}
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
diff --git a/chrome/test/data/autofill/captured_sites/testcases.json b/chrome/test/data/autofill/captured_sites/testcases.json
index bb7ac2a638a410b3e83b9871314eae27aa8ef229..2e69d8f8532760103b9cccd5efc4ca7a4ad016a1 100644
--- a/chrome/test/data/autofill/captured_sites/testcases.json
+++ b/chrome/test/data/autofill/captured_sites/testcases.json
@@ -17,7 +17,7 @@
{ "site_name": "bath_and_body_works" },
{ "site_name": "beachbody" },
{ "site_name": "bed_bath_beyond" },
- { "site_name": "belk" },
+ { "site_name": "belk", "bug_number": 1376637 },
{ "site_name": "bestbuy" },
{ "site_name": "bhphotovideo", "bug_number":1173033 },
{ "site_name": "bloomingdales" },
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
index bc16e80e580b0c800391501e022c2ea011e65ef1..b3ca85044a094e639f492a12d10ca0ed4cce11e9 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -1056,26 +1056,36 @@ void BrowserAutofillManager::OnAskForValuesToFillImpl(
bool BrowserAutofillManager::WillFillCreditCardNumber(
const FormData& form,
- const FormFieldData& field) {
+ const FormFieldData& triggered_field_data) {
FormStructure* form_structure = nullptr;
- AutofillField* autofill_field = nullptr;
- if (!GetCachedFormAndField(form, field, &form_structure, &autofill_field))
+ AutofillField* triggered_field = nullptr;
+ if (!GetCachedFormAndField(form, triggered_field_data, &form_structure,
+ &triggered_field)) {
return false;
+ }
- if (autofill_field->Type().GetStorableType() == CREDIT_CARD_NUMBER)
+ if (triggered_field->Type().GetStorableType() == CREDIT_CARD_NUMBER)
return true;
- DCHECK_EQ(form_structure->field_count(), form.fields.size());
- for (size_t i = 0; i < form_structure->field_count(); ++i) {
- if (form_structure->field(i)->section == autofill_field->section &&
- form_structure->field(i)->Type().GetStorableType() ==
- CREDIT_CARD_NUMBER &&
- form.fields[i].value.empty() && !form.fields[i].is_autofilled) {
- return true;
- }
- }
+ // `form` is the latest version of the form received from the renderer and may
+ // be more up to date than the `form_structure` in the cache. Therefore, we
+ // need to validate for each `field` in the cache we try to fill whether
+ // it still exists in the renderer and whether it is fillable.
+ auto IsFillableField = [&form](FieldGlobalId id) {
+ auto it = base::ranges::find(form.fields, id, &FormFieldData::global_id);
+ return it != form.fields.end() && it->value.empty() && !it->is_autofilled;
+ };
- return false;
+ auto IsFillableCreditCardNumberField = [&triggered_field,
+ &IsFillableField](const auto& field) {
+ return field->Type().GetStorableType() == CREDIT_CARD_NUMBER &&
+ field->section == triggered_field->section &&
+ IsFillableField(field->global_id());
+ };
+
+ // This runs O(N^2) in the worst case, but usually there aren't too many
+ // credit card number fields in a form.
+ return base::ranges::any_of(*form_structure, IsFillableCreditCardNumberField);
}
void BrowserAutofillManager::FillOrPreviewCreditCardForm(
diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h
index 0040d007eea8e69f7cccb069afe1103cfdd84d75..2d5aa6171bc4634bc98a5c123a25979675de4f10 100644
--- a/components/autofill/core/browser/browser_autofill_manager.h
+++ b/components/autofill/core/browser/browser_autofill_manager.h
@@ -503,11 +503,11 @@ class BrowserAutofillManager : public AutofillManager,
// profile does not exist.
AutofillProfile* GetProfile(int unique_id);
- // Determines whether a fill on |form| initiated from |field| will wind up
- // filling a credit card number. This is useful to determine if we will need
- // to unmask a card.
+ // Determines whether a fill on |form| initiated from |triggered_field| will
+ // wind up filling a credit card number. This is useful to determine if we
+ // will need to unmask a card.
bool WillFillCreditCardNumber(const FormData& form,
- const FormFieldData& field);
+ const FormFieldData& triggered_field);
// Fills or previews the credit card form.
// Assumes the form and field are valid.

View File

@@ -0,0 +1,323 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Xiaocheng Hu <xiaochengh@chromium.org>
Date: Sat, 10 Sep 2022 05:53:49 +0000
Subject: Remove symlinks from FileChooserImpl folder upload result
FileChooserImpl is the browser-side implementation of
<input type=file>. When uploading a whole folder, it
currently uses DirectoryLister to list all the files in a
directory. The result also includes resolved symbolic links
(which may even hide deep in some subfolder), which is not a
desired behavior.
Therefore, this patch removes all symbolic links from the
result by checking each file against `base::IsLink()`. Since
the function needs blocking calls to access file data, the
job is sent to a worker pool thread.
Fixed: 1345275
Change-Id: I8ab58214c87944408c64b177e915247a7485925b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3866767
Reviewed-by: Austin Sullivan <asully@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: Mason Freed <masonf@chromium.org>
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1045491}
diff --git a/content/browser/web_contents/file_chooser_impl.cc b/content/browser/web_contents/file_chooser_impl.cc
index 7a3ea45d32c97980c141662f6a071cc517a15ad8..1aa19f7a735b444f2c33d5084edcdd14e3c2f5c5 100644
--- a/content/browser/web_contents/file_chooser_impl.cc
+++ b/content/browser/web_contents/file_chooser_impl.cc
@@ -4,8 +4,11 @@
#include "content/browser/web_contents/file_chooser_impl.h"
+#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
+#include "base/ranges/algorithm.h"
+#include "base/task/thread_pool.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/renderer_host/back_forward_cache_disable.h"
#include "content/browser/renderer_host/render_frame_host_delegate.h"
@@ -18,6 +21,19 @@
namespace content {
+namespace {
+
+std::vector<blink::mojom::FileChooserFileInfoPtr> RemoveSymlinks(
+ std::vector<blink::mojom::FileChooserFileInfoPtr> files) {
+ auto new_end = base::ranges::remove_if(
+ files, &base::IsLink,
+ [](const auto& file) { return file->get_native_file()->file_path; });
+ files.erase(new_end, files.end());
+ return files;
+}
+
+} // namespace
+
FileChooserImpl::FileSelectListenerImpl::~FileSelectListenerImpl() {
#if DCHECK_IS_ON()
if (!was_file_select_listener_function_called_) {
@@ -51,8 +67,20 @@ void FileChooserImpl::FileSelectListenerImpl::FileSelected(
"FileSelectListener::FileSelectionCanceled()";
was_file_select_listener_function_called_ = true;
#endif
- if (owner_)
- owner_->FileSelected(std::move(files), base_dir, mode);
+ if (!owner_)
+ return;
+
+ if (mode != blink::mojom::FileChooserParams::Mode::kUploadFolder) {
+ owner_->FileSelected(base_dir, mode, std::move(files));
+ return;
+ }
+
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE,
+ {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+ base::BindOnce(&RemoveSymlinks, std::move(files)),
+ base::BindOnce(&FileChooserImpl::FileSelected, owner_->GetWeakPtr(),
+ base_dir, mode));
}
void FileChooserImpl::FileSelectListenerImpl::FileSelectionCanceled() {
@@ -162,9 +190,9 @@ void FileChooserImpl::EnumerateChosenDirectory(
}
void FileChooserImpl::FileSelected(
- std::vector<blink::mojom::FileChooserFileInfoPtr> files,
const base::FilePath& base_dir,
- blink::mojom::FileChooserParams::Mode mode) {
+ blink::mojom::FileChooserParams::Mode mode,
+ std::vector<blink::mojom::FileChooserFileInfoPtr> files) {
listener_impl_ = nullptr;
if (!render_frame_host_) {
std::move(callback_).Run(nullptr);
diff --git a/content/browser/web_contents/file_chooser_impl.h b/content/browser/web_contents/file_chooser_impl.h
index b9f11f9e6a0b548cb5ab8ca721ae823e079ce6fa..b628b29a5f84264e62bb3fa9e92550787b8342de 100644
--- a/content/browser/web_contents/file_chooser_impl.h
+++ b/content/browser/web_contents/file_chooser_impl.h
@@ -37,6 +37,8 @@ class CONTENT_EXPORT FileChooserImpl : public blink::mojom::FileChooser,
// FileSelectListener overrides:
+ // TODO(xiaochengh): Move |file| to the end of the argument list to match
+ // the argument ordering of FileChooserImpl::FileSelected().
void FileSelected(std::vector<blink::mojom::FileChooserFileInfoPtr> files,
const base::FilePath& base_dir,
blink::mojom::FileChooserParams::Mode mode) override;
@@ -68,9 +70,9 @@ class CONTENT_EXPORT FileChooserImpl : public blink::mojom::FileChooser,
~FileChooserImpl() override;
- void FileSelected(std::vector<blink::mojom::FileChooserFileInfoPtr> files,
- const base::FilePath& base_dir,
- blink::mojom::FileChooserParams::Mode mode);
+ void FileSelected(const base::FilePath& base_dir,
+ blink::mojom::FileChooserParams::Mode mode,
+ std::vector<blink::mojom::FileChooserFileInfoPtr> files);
void FileSelectionCanceled();
@@ -82,6 +84,10 @@ class CONTENT_EXPORT FileChooserImpl : public blink::mojom::FileChooser,
const base::FilePath& directory_path,
EnumerateChosenDirectoryCallback callback) override;
+ base::WeakPtr<FileChooserImpl> GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+ }
+
private:
explicit FileChooserImpl(RenderFrameHostImpl* render_frame_host);
@@ -95,6 +101,8 @@ class CONTENT_EXPORT FileChooserImpl : public blink::mojom::FileChooser,
raw_ptr<RenderFrameHostImpl> render_frame_host_;
scoped_refptr<FileSelectListenerImpl> listener_impl_;
base::OnceCallback<void(blink::mojom::FileChooserResultPtr)> callback_;
+
+ base::WeakPtrFactory<FileChooserImpl> weak_factory_{this};
};
} // namespace content
diff --git a/content/browser/web_contents/file_chooser_impl_browsertest.cc b/content/browser/web_contents/file_chooser_impl_browsertest.cc
index ced9bfd8fe905acbb6ab5c3e52a9882fc23a7303..f7519189638ece437c4285ddd490be3ea59e638d 100644
--- a/content/browser/web_contents/file_chooser_impl_browsertest.cc
+++ b/content/browser/web_contents/file_chooser_impl_browsertest.cc
@@ -5,14 +5,18 @@
#include "content/browser/web_contents/file_chooser_impl.h"
#include "base/bind.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
#include "base/run_loop.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/web_contents_delegate.h"
+#include "content/public/common/content_paths.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
#include "url/gurl.h"
#include "url/url_constants.h"
@@ -143,11 +147,52 @@ IN_PROC_BROWSER_TEST_F(FileChooserImplBrowserTest,
->SetListenerFunctionCalledTrueForTesting();
std::vector<blink::mojom::FileChooserFileInfoPtr> files;
files.emplace_back(blink::mojom::FileChooserFileInfoPtr(nullptr));
- chooser->FileSelected(std::move(files), base::FilePath(),
- blink::mojom::FileChooserParams::Mode::kOpen);
+ chooser->FileSelected(base::FilePath(),
+ blink::mojom::FileChooserParams::Mode::kOpen,
+ std::move(files));
// Test passes if this run_loop.Run() returns instead of timing out.
run_loop.Run();
}
+// https://crbug.com/1345275
+IN_PROC_BROWSER_TEST_F(FileChooserImplBrowserTest, UploadFolderWithSymlink) {
+ EXPECT_TRUE(NavigateToURL(
+ shell(), GetTestUrl(".", "file_input_webkitdirectory.html")));
+
+ // The folder contains a regular file and a symbolic link.
+ // When uploading the folder, the symbolic link should be excluded.
+ base::FilePath dir_test_data;
+ ASSERT_TRUE(base::PathService::Get(DIR_TEST_DATA, &dir_test_data));
+ base::FilePath folder_to_upload =
+ dir_test_data.AppendASCII("file_chooser").AppendASCII("dir_with_symlink");
+
+ base::FilePath text_file = folder_to_upload.AppendASCII("text_file.txt");
+ base::FilePath symlink_file = folder_to_upload.AppendASCII("symlink");
+
+ // Skip the test if symbolic links are not supported.
+ {
+ base::ScopedAllowBlockingForTesting allow_blocking;
+ if (!base::IsLink(symlink_file))
+ return;
+ }
+
+ std::unique_ptr<FileChooserDelegate> delegate(
+ new FileChooserDelegate({text_file, symlink_file}, base::OnceClosure()));
+ shell()->web_contents()->SetDelegate(delegate.get());
+ EXPECT_TRUE(ExecJs(shell(),
+ "(async () => {"
+ " let listener = new Promise("
+ " resolve => fileinput.onchange = resolve);"
+ " fileinput.click();"
+ " await listener;"
+ "})()"));
+
+ EXPECT_EQ(
+ 1, EvalJs(shell(), "document.getElementById('fileinput').files.length;"));
+ EXPECT_EQ(
+ "text_file.txt",
+ EvalJs(shell(), "document.getElementById('fileinput').files[0].name;"));
+}
+
} // namespace content
diff --git a/content/test/content_browser_test_utils_internal.cc b/content/test/content_browser_test_utils_internal.cc
index d8e63b56c8ac89a08cd7c40cabb156eb4d1923aa..c70d088bfd007e9a6cd9cfcb6f92b07b99653048 100644
--- a/content/test/content_browser_test_utils_internal.cc
+++ b/content/test/content_browser_test_utils_internal.cc
@@ -446,9 +446,14 @@ Shell* OpenPopup(const ToRenderFrameHost& opener,
return new_shell_observer.GetShell();
}
+FileChooserDelegate::FileChooserDelegate(std::vector<base::FilePath> files,
+ base::OnceClosure callback)
+ : files_(std::move(files)), callback_(std::move(callback)) {}
+
FileChooserDelegate::FileChooserDelegate(const base::FilePath& file,
base::OnceClosure callback)
- : file_(file), callback_(std::move(callback)) {}
+ : FileChooserDelegate(std::vector<base::FilePath>(1, file),
+ std::move(callback)) {}
FileChooserDelegate::~FileChooserDelegate() = default;
@@ -456,16 +461,18 @@ void FileChooserDelegate::RunFileChooser(
RenderFrameHost* render_frame_host,
scoped_refptr<content::FileSelectListener> listener,
const blink::mojom::FileChooserParams& params) {
- // Send the selected file to the renderer process.
- auto file_info = blink::mojom::FileChooserFileInfo::NewNativeFile(
- blink::mojom::NativeFileInfo::New(file_, std::u16string()));
+ // Send the selected files to the renderer process.
std::vector<blink::mojom::FileChooserFileInfoPtr> files;
- files.push_back(std::move(file_info));
- listener->FileSelected(std::move(files), base::FilePath(),
- blink::mojom::FileChooserParams::Mode::kOpen);
+ for (const auto& file : files_) {
+ auto file_info = blink::mojom::FileChooserFileInfo::NewNativeFile(
+ blink::mojom::NativeFileInfo::New(file, std::u16string()));
+ files.push_back(std::move(file_info));
+ }
+ listener->FileSelected(std::move(files), base::FilePath(), params.mode);
params_ = params.Clone();
- std::move(callback_).Run();
+ if (callback_)
+ std::move(callback_).Run();
}
FrameTestNavigationManager::FrameTestNavigationManager(
diff --git a/content/test/content_browser_test_utils_internal.h b/content/test/content_browser_test_utils_internal.h
index 73be6e8a2f458128b08aae34d951c7a80139997d..43c6aabc5414d0cc12fb5a03142e8b20e2a7fab3 100644
--- a/content/test/content_browser_test_utils_internal.h
+++ b/content/test/content_browser_test_utils_internal.h
@@ -176,9 +176,11 @@ Shell* OpenPopup(const ToRenderFrameHost& opener,
class FileChooserDelegate : public WebContentsDelegate {
public:
// Constructs a WebContentsDelegate that mocks a file dialog.
- // The mocked file dialog will always reply that the user selected |file|.
- // |callback| is invoked when RunFileChooser() is called.
+ // The mocked file dialog will always reply that the user selected |file| or
+ // |files|. |callback| is invoked when RunFileChooser() is called.
FileChooserDelegate(const base::FilePath& file, base::OnceClosure callback);
+ FileChooserDelegate(std::vector<base::FilePath> files,
+ base::OnceClosure callback);
~FileChooserDelegate() override;
// Implementation of WebContentsDelegate::RunFileChooser.
@@ -190,7 +192,7 @@ class FileChooserDelegate : public WebContentsDelegate {
const blink::mojom::FileChooserParams& params() const { return *params_; }
private:
- base::FilePath file_;
+ std::vector<base::FilePath> files_;
base::OnceClosure callback_;
blink::mojom::FileChooserParamsPtr params_;
};
diff --git a/content/test/data/file_chooser/dir_with_symlink/symlink b/content/test/data/file_chooser/dir_with_symlink/symlink
new file mode 120000
index 0000000000000000000000000000000000000000..7857c689f7043265b4e6d4dcdf6d40d0be2d3d60
--- /dev/null
+++ b/content/test/data/file_chooser/dir_with_symlink/symlink
@@ -0,0 +1 @@
+../linked_text_file.txt
\ No newline at end of file
diff --git a/content/test/data/file_chooser/dir_with_symlink/text_file.txt b/content/test/data/file_chooser/dir_with_symlink/text_file.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8e27be7d6154a1f68ea9160ef0e18691d20560dc
--- /dev/null
+++ b/content/test/data/file_chooser/dir_with_symlink/text_file.txt
@@ -0,0 +1 @@
+text
diff --git a/content/test/data/file_chooser/linked_text_file.txt b/content/test/data/file_chooser/linked_text_file.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9a1f4bc60917c014eac1464ad664a0271c288b84
--- /dev/null
+++ b/content/test/data/file_chooser/linked_text_file.txt
@@ -0,0 +1 @@
+linked text file
diff --git a/content/test/data/file_input_webkitdirectory.html b/content/test/data/file_input_webkitdirectory.html
new file mode 100644
index 0000000000000000000000000000000000000000..5b7bb501f7eb5d9f28751f36380e4ad01d2da0c7
--- /dev/null
+++ b/content/test/data/file_input_webkitdirectory.html
@@ -0,0 +1 @@
+<input type="file" id="fileinput" webkitdirectory />

View File

@@ -0,0 +1,179 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Wed, 31 Aug 2022 15:39:45 +0000
Subject: Mojo: Validate response message type
Ensures that a response message is actually the type expected by the
original request.
Fixed: 1358134
Change-Id: I8f8f58168764477fbf7a6d2e8aeb040f07793d45
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3864274
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/main@{#1041553}
diff --git a/mojo/public/cpp/bindings/interface_endpoint_client.h b/mojo/public/cpp/bindings/interface_endpoint_client.h
index 01cba995429b0accc21986aba0e3de17d013ee95..d3a1ab3a13a6662239ec28f99e5865afa54356b3 100644
--- a/mojo/public/cpp/bindings/interface_endpoint_client.h
+++ b/mojo/public/cpp/bindings/interface_endpoint_client.h
@@ -222,20 +222,32 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) InterfaceEndpointClient
void ForgetAsyncRequest(uint64_t request_id);
private:
- // Maps from the id of a response to the MessageReceiver that handles the
- // response.
- using AsyncResponderMap =
- std::map<uint64_t, std::unique_ptr<MessageReceiver>>;
+ struct PendingAsyncResponse {
+ public:
+ PendingAsyncResponse(uint32_t request_message_name,
+ std::unique_ptr<MessageReceiver> responder);
+ PendingAsyncResponse(PendingAsyncResponse&&);
+ PendingAsyncResponse(const PendingAsyncResponse&) = delete;
+ PendingAsyncResponse& operator=(PendingAsyncResponse&&);
+ PendingAsyncResponse& operator=(const PendingAsyncResponse&) = delete;
+ ~PendingAsyncResponse();
+
+ uint32_t request_message_name;
+ std::unique_ptr<MessageReceiver> responder;
+ };
+
+ using AsyncResponderMap = std::map<uint64_t, PendingAsyncResponse>;
struct SyncResponseInfo {
public:
- explicit SyncResponseInfo(bool* in_response_received);
+ SyncResponseInfo(uint32_t request_message_name, bool* in_response_received);
SyncResponseInfo(const SyncResponseInfo&) = delete;
SyncResponseInfo& operator=(const SyncResponseInfo&) = delete;
~SyncResponseInfo();
+ uint32_t request_message_name;
Message response;
// Points to a stack-allocated variable.
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
index b9db8f31a42b956c6125852cf162dc524d5308e6..6e87db197c603d8ac44b591f2cd70023217dcbe2 100644
--- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
+++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -28,6 +28,7 @@
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
#include "mojo/public/cpp/bindings/sync_event_watcher.h"
#include "mojo/public/cpp/bindings/thread_safe_proxy.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.h"
namespace mojo {
@@ -314,9 +315,27 @@ class ResponderThunk : public MessageReceiverWithStatus {
// ----------------------------------------------------------------------------
+InterfaceEndpointClient::PendingAsyncResponse::PendingAsyncResponse(
+ uint32_t request_message_name,
+ std::unique_ptr<MessageReceiver> responder)
+ : request_message_name(request_message_name),
+ responder(std::move(responder)) {}
+
+InterfaceEndpointClient::PendingAsyncResponse::PendingAsyncResponse(
+ PendingAsyncResponse&&) = default;
+
+InterfaceEndpointClient::PendingAsyncResponse&
+InterfaceEndpointClient::PendingAsyncResponse::operator=(
+ PendingAsyncResponse&&) = default;
+
+InterfaceEndpointClient::PendingAsyncResponse::~PendingAsyncResponse() =
+ default;
+
InterfaceEndpointClient::SyncResponseInfo::SyncResponseInfo(
+ uint32_t request_message_name,
bool* in_response_received)
- : response_received(in_response_received) {}
+ : request_message_name(request_message_name),
+ response_received(in_response_received) {}
InterfaceEndpointClient::SyncResponseInfo::~SyncResponseInfo() {}
@@ -604,6 +623,7 @@ bool InterfaceEndpointClient::SendMessageWithResponder(
// message before calling |SendMessage()| below.
#endif
+ const uint32_t message_name = message->name();
const bool is_sync = message->has_flag(Message::kFlagIsSync);
const bool exclusive_wait = message->has_flag(Message::kFlagNoInterrupt);
if (!controller_->SendMessage(message))
@@ -620,7 +640,8 @@ bool InterfaceEndpointClient::SendMessageWithResponder(
controller_->RegisterExternalSyncWaiter(request_id);
}
base::AutoLock lock(async_responders_lock_);
- async_responders_[request_id] = std::move(responder);
+ async_responders_.emplace(
+ request_id, PendingAsyncResponse{message_name, std::move(responder)});
return true;
}
@@ -628,7 +649,8 @@ bool InterfaceEndpointClient::SendMessageWithResponder(
bool response_received = false;
sync_responses_.insert(std::make_pair(
- request_id, std::make_unique<SyncResponseInfo>(&response_received)));
+ request_id,
+ std::make_unique<SyncResponseInfo>(message_name, &response_received)));
base::WeakPtr<InterfaceEndpointClient> weak_self =
weak_ptr_factory_.GetWeakPtr();
@@ -806,13 +828,13 @@ void InterfaceEndpointClient::ResetFromAnotherSequenceUnsafe() {
}
void InterfaceEndpointClient::ForgetAsyncRequest(uint64_t request_id) {
- std::unique_ptr<MessageReceiver> responder;
+ absl::optional<PendingAsyncResponse> response;
{
base::AutoLock lock(async_responders_lock_);
auto it = async_responders_.find(request_id);
if (it == async_responders_.end())
return;
- responder = std::move(it->second);
+ response = std::move(it->second);
async_responders_.erase(it);
}
}
@@ -893,6 +915,10 @@ bool InterfaceEndpointClient::HandleValidatedMessage(Message* message) {
return false;
if (it->second) {
+ if (message->name() != it->second->request_message_name) {
+ return false;
+ }
+
it->second->response = std::move(*message);
*it->second->response_received = true;
return true;
@@ -903,18 +929,22 @@ bool InterfaceEndpointClient::HandleValidatedMessage(Message* message) {
sync_responses_.erase(it);
}
- std::unique_ptr<MessageReceiver> responder;
+ absl::optional<PendingAsyncResponse> pending_response;
{
base::AutoLock lock(async_responders_lock_);
auto it = async_responders_.find(request_id);
if (it == async_responders_.end())
return false;
- responder = std::move(it->second);
+ pending_response = std::move(it->second);
async_responders_.erase(it);
}
+ if (message->name() != pending_response->request_message_name) {
+ return false;
+ }
+
internal::MessageDispatchContext dispatch_context(message);
- return responder->Accept(message);
+ return pending_response->responder->Accept(message);
} else {
if (mojo::internal::ControlMessageHandler::IsControlMessage(message))
return control_message_handler_.Accept(message);

View File

@@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Xiaocheng Hu <xiaochengh@chromium.org>
Date: Wed, 28 Sep 2022 19:09:02 +0000
Subject: Ensure iterator validity in CustomElementRegistry::DefineInternal()
Currently, this function first resolves a promise, and then erases an
iterator from a hash map, but the promise resolving may run synchronous
JavaScript that invalidates the iterator.
This patch switches the ordering so that we always use the iterator when
it's valid.
(cherry picked from commit ed87ab54b29898a96a87e8fd497425db32539350)
(cherry picked from commit b0bfc4334369bd1d44bc6507dfefc012afb7e12d)
Fixed: 1366813
Change-Id: Iaa6631db5f3ad47049f46ddf909f18a49e5880c0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3915346
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/main@{#1050816}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3922738
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Auto-Submit: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/5304@{#203}
Cr-Original-Branched-From: 5d7b1fc9cb7103d9c82eed647cf4be38cf09738b-refs/heads/main@{#1047731}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3924290
Cr-Commit-Position: refs/branch-heads/5249@{#686}
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_registry.cc b/third_party/blink/renderer/core/html/custom/custom_element_registry.cc
index 5a63b6f0fd74d8c836c805e4d03e7be0b0205f15..6e37fba2cd627d69e602381e79f64c8ba72128b6 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_registry.cc
+++ b/third_party/blink/renderer/core/html/custom/custom_element_registry.cc
@@ -217,8 +217,11 @@ CustomElementDefinition* CustomElementRegistry::DefineInternal(
// 16: when-defined promise processing
const auto& entry = when_defined_promise_map_.find(name);
if (entry != when_defined_promise_map_.end()) {
- entry->value->Resolve();
+ ScriptPromiseResolver* resolver = entry->value;
when_defined_promise_map_.erase(entry);
+ // Resolve() may run synchronous JavaScript that invalidates iterators of
+ // |when_defined_promise_map_|, so it must be called after erasing |entry|.
+ resolver->Resolve();
}
return definition;
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/when-defined-reentry-crash.html b/third_party/blink/web_tests/external/wpt/custom-elements/when-defined-reentry-crash.html
new file mode 100644
index 0000000000000000000000000000000000000000..38614cbbd7836a955c40ea64165a22bcb44f7e63
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/when-defined-reentry-crash.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Check for crashes when a whenDefined promise resolving re-entries</title>
+<meta name="author" href="mailto:xiaochengh@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-api">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1366813">
+<script>
+class CustomElement extends HTMLElement {}
+
+Object.prototype.__defineGetter__("then", main);
+
+let depth = 0;
+function main() {
+ if (depth > 1) return;
+ ++depth;
+ customElements.whenDefined("custom-a"); // Causes re-entry of main()
+ try { customElements.define("custom-a", CustomElement) } catch (e) {}
+ customElements.whenDefined("custom-b");
+ --depth;
+}
+
+main();
+</script>
+
+Test passes if it does not crash.

View File

@@ -0,0 +1,102 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matt Wolenetz <wolenetz@chromium.org>
Date: Fri, 4 Nov 2022 22:06:47 +0000
Subject: webcodecs: Fix race in VE.isConfigSupported() promise resolution
If the context is destroyed before VideoEncoder calls `done_callback`, bad
things can happen. That's why we extract a callback runner before doing
anything asynchronous. Since we hold a ref-counted pointer to the
runner it should be safe now.
(cherry picked from commit 2acf28478008315f302fd52b571623e784be707b)
Bug: 1375059
Change-Id: I984ab27e03e50bd5ae4bf0eb13431834b14f89b7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3965544
Commit-Queue: Eugene Zemtsov <eugene@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1061737}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4005574
Reviewed-by: Matthew Wolenetz <wolenetz@chromium.org>
Cr-Commit-Position: refs/branch-heads/5249@{#911}
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
index 291c18fc9b8f4fbb869e580843403818b44f2d43..ed7b3551fc9ddb5768fec46833363806129bd505 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -68,6 +68,7 @@
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_base.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_std.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
@@ -100,16 +101,6 @@ namespace {
constexpr const char kCategory[] = "media";
constexpr int kMaxActiveEncodes = 5;
-// Use this function in cases when we can't immediately delete |ptr| because
-// there might be its methods on the call stack.
-template <typename T>
-void DeleteLater(ScriptState* state, std::unique_ptr<T> ptr) {
- DCHECK(state->ContextIsValid());
- auto* context = ExecutionContext::From(state);
- auto runner = context->GetTaskRunner(TaskType::kInternalDefault);
- runner->DeleteSoon(FROM_HERE, std::move(ptr));
-}
-
bool IsAcceleratedConfigurationSupported(
media::VideoCodecProfile profile,
const media::VideoEncoder::Options& options,
@@ -988,6 +979,7 @@ void VideoEncoder::ResetInternal() {
}
static void isConfigSupportedWithSoftwareOnly(
+ ScriptState* script_state,
ScriptPromiseResolver* resolver,
VideoEncoderSupport* support,
VideoEncoderTraits::ParsedConfig* config) {
@@ -1012,22 +1004,25 @@ static void isConfigSupportedWithSoftwareOnly(
return;
}
- auto done_callback = [](std::unique_ptr<media::VideoEncoder> sw_encoder,
+ auto done_callback = [](std::unique_ptr<media::VideoEncoder> encoder,
ScriptPromiseResolver* resolver,
+ scoped_refptr<base::SingleThreadTaskRunner> runner,
VideoEncoderSupport* support,
media::EncoderStatus status) {
support->setSupported(status.is_ok());
resolver->Resolve(support);
- DeleteLater(resolver->GetScriptState(), std::move(sw_encoder));
+ runner->DeleteSoon(FROM_HERE, std::move(encoder));
};
+ auto* context = ExecutionContext::From(script_state);
+ auto runner = context->GetTaskRunner(TaskType::kInternalDefault);
auto* software_encoder_raw = software_encoder.get();
software_encoder_raw->Initialize(
config->profile, config->options, base::DoNothing(),
- ConvertToBaseOnceCallback(
- CrossThreadBindOnce(done_callback, std::move(software_encoder),
- WrapCrossThreadPersistent(resolver),
- WrapCrossThreadPersistent(support))));
+ ConvertToBaseOnceCallback(CrossThreadBindOnce(
+ done_callback, std::move(software_encoder),
+ WrapCrossThreadPersistent(resolver), std::move(runner),
+ WrapCrossThreadPersistent(support))));
}
static void isConfigSupportedWithHardwareOnly(
@@ -1114,7 +1109,8 @@ ScriptPromise VideoEncoder::isConfigSupported(ScriptState* script_state,
promises.push_back(resolver->Promise());
auto* support = VideoEncoderSupport::Create();
support->setConfig(config_copy);
- isConfigSupportedWithSoftwareOnly(resolver, support, parsed_config);
+ isConfigSupportedWithSoftwareOnly(script_state, resolver, support,
+ parsed_config);
}
// Wait for all |promises| to resolve and check if any of them have

View File

@@ -0,0 +1,285 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dave Tapuska <dtapuska@chromium.org>
Date: Thu, 3 Nov 2022 23:16:16 +0000
Subject: Fix PauseOrFreezeOnWorkerThread with nested Worklets.
Worklets can use the same backing thread which means we can have
nested WorkerThreads paused. If a parent WorkerThread gets deallocated
make sure we don't access anything after it is deallocated once the
nested event queue is released.
BUG=1372695
(cherry picked from commit ff5696ba4bc0f8782e3de40e04685507d9f17fd2)
Change-Id: I176b8f750da5a41d19d1b3a623944d9a2ed4a441
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3953152
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1059485}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4004562
Cr-Commit-Position: refs/branch-heads/5249@{#906}
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_test.cc b/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
index 80fc6e758afbfebedfbb0303854366d2c13d6bc0..5cc0138609f1944f03500b75d40634d1a7e946fa 100644
--- a/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
+++ b/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
@@ -235,6 +235,7 @@ class ThreadedWorkletMessagingProxyForTest
private:
friend class ThreadedWorkletTest;
+ FRIEND_TEST_ALL_PREFIXES(ThreadedWorkletTest, NestedRunLoopTermination);
std::unique_ptr<WorkerThread> CreateWorkerThread() final {
return std::make_unique<ThreadedWorkletThreadForTest>(WorkletObjectProxy());
@@ -281,6 +282,16 @@ class ThreadedWorkletTest : public testing::Test {
}
Document& GetDocument() { return page_->GetDocument(); }
+ void WaitForReady(WorkerThread* worker_thread) {
+ base::WaitableEvent child_waitable;
+ PostCrossThreadTask(
+ *worker_thread->GetTaskRunner(TaskType::kInternalTest), FROM_HERE,
+ CrossThreadBindOnce(&base::WaitableEvent::Signal,
+ CrossThreadUnretained(&child_waitable)));
+
+ child_waitable.Wait();
+ }
+
private:
std::unique_ptr<DummyPageHolder> page_;
Persistent<ThreadedWorkletMessagingProxyForTest> messaging_proxy_;
@@ -404,4 +415,40 @@ TEST_F(ThreadedWorkletTest, TaskRunner) {
test::EnterRunLoop();
}
+TEST_F(ThreadedWorkletTest, NestedRunLoopTermination) {
+ MessagingProxy()->Start();
+
+ ThreadedWorkletMessagingProxyForTest* second_messaging_proxy =
+ MakeGarbageCollected<ThreadedWorkletMessagingProxyForTest>(
+ GetExecutionContext());
+
+ // Get a nested event loop where the first one is on the stack
+ // and the second is still alive.
+ second_messaging_proxy->Start();
+
+ // Wait until the workers are setup and ready to accept work before we
+ // pause them.
+ WaitForReady(GetWorkerThread());
+ WaitForReady(second_messaging_proxy->GetWorkerThread());
+
+ // Pause the second worker, then the first.
+ second_messaging_proxy->GetWorkerThread()->Pause();
+ GetWorkerThread()->Pause();
+
+ // Resume then terminate the second worker.
+ second_messaging_proxy->GetWorkerThread()->Resume();
+ second_messaging_proxy->GetWorkerThread()->Terminate();
+ second_messaging_proxy = nullptr;
+
+ // Now resume the first worker.
+ GetWorkerThread()->Resume();
+
+ // Make sure execution still works without crashing.
+ PostCrossThreadTask(
+ *GetWorkerThread()->GetTaskRunner(TaskType::kInternalTest), FROM_HERE,
+ CrossThreadBindOnce(&ThreadedWorkletThreadForTest::TestTaskRunner,
+ CrossThreadUnretained(GetWorkerThread())));
+ test::EnterRunLoop();
+}
+
} // namespace blink
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc
index 892b3e58443f1a82a6a41c6d52df7d2d701b377d..3a98c2d192e1e47d1586d1dab1fc9e9dc9daf83b 100644
--- a/third_party/blink/renderer/core/workers/worker_thread.cc
+++ b/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -30,7 +30,6 @@
#include <memory>
#include <utility>
-#include "base/auto_reset.h"
#include "base/metrics/histogram_functions.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_restrictions.h"
@@ -593,6 +592,7 @@ void WorkerThread::InitializeOnWorkerThread(
const absl::optional<WorkerBackingThreadStartupData>& thread_startup_data,
std::unique_ptr<WorkerDevToolsParams> devtools_params) {
DCHECK(IsCurrentThread());
+ backing_thread_weak_factory_.emplace(this);
worker_reporting_proxy_.WillInitializeWorkerContext();
{
TRACE_EVENT0("blink.worker", "WorkerThread::InitializeWorkerContext");
@@ -728,11 +728,13 @@ void WorkerThread::PrepareForShutdownOnWorkerThread() {
SetThreadState(ThreadState::kReadyToShutdown);
}
+ backing_thread_weak_factory_ = absl::nullopt;
if (pause_or_freeze_count_ > 0) {
DCHECK(nested_runner_);
pause_or_freeze_count_ = 0;
nested_runner_->QuitNow();
}
+ pause_handle_.reset();
{
v8::HandleScope handle_scope(GetIsolate());
@@ -883,8 +885,7 @@ void WorkerThread::PauseOrFreezeOnWorkerThread(
if (pause_or_freeze_count_ > 1)
return;
- std::unique_ptr<scheduler::WorkerScheduler::PauseHandle> pause_handle =
- GetScheduler()->Pause();
+ pause_handle_ = GetScheduler()->Pause();
{
// Since the nested message loop runner needs to be created and destroyed on
// the same thread we allocate and destroy a new message loop runner each
@@ -892,13 +893,20 @@ void WorkerThread::PauseOrFreezeOnWorkerThread(
// the worker thread such that the resume/terminate can quit this runner.
std::unique_ptr<Platform::NestedMessageLoopRunner> nested_runner =
Platform::Current()->CreateNestedMessageLoopRunner();
- base::AutoReset<Platform::NestedMessageLoopRunner*> nested_runner_autoreset(
- &nested_runner_, nested_runner.get());
+ auto weak_this = backing_thread_weak_factory_->GetWeakPtr();
+ nested_runner_ = nested_runner.get();
nested_runner->Run();
+
+ // Careful `this` may be destroyed.
+ if (!weak_this) {
+ return;
+ }
+ nested_runner_ = nullptr;
}
GlobalScope()->SetDefersLoadingForResourceFetchers(LoaderFreezeMode::kNone);
GlobalScope()->SetIsInBackForwardCache(false);
GlobalScope()->SetLifecycleState(mojom::blink::FrameLifecycleState::kRunning);
+ pause_handle_.reset();
}
void WorkerThread::ResumeOnWorkerThread() {
diff --git a/third_party/blink/renderer/core/workers/worker_thread.h b/third_party/blink/renderer/core/workers/worker_thread.h
index 89f75cbfba55c2760a018e99c4746c2e09b83c1b..b8b93f827d1892886fde662bf660d43f7bd646e3 100644
--- a/third_party/blink/renderer/core/workers/worker_thread.h
+++ b/third_party/blink/renderer/core/workers/worker_thread.h
@@ -31,6 +31,7 @@
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/single_thread_task_runner.h"
#include "base/thread_annotations.h"
@@ -78,7 +79,7 @@ struct WorkerMainScriptLoadParameters;
// abstract class. Multiple WorkerThreads may share one WorkerBackingThread for
// worklets.
//
-// WorkerThread start and termination must be initiated on the main thread and
+// WorkerThread start and termination must be initiated on the parent thread and
// an actual task is executed on the worker thread.
//
// When termination starts, (debugger) tasks on WorkerThread are handled as
@@ -101,7 +102,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
~WorkerThread() override;
// Starts the underlying thread and creates the global scope. Called on the
- // main thread.
+ // parent thread.
// Startup data for WorkerBackingThread is absl::nullopt if |this| doesn't own
// the underlying WorkerBackingThread.
// TODO(nhiroki): We could separate WorkerBackingThread initialization from
@@ -113,14 +114,14 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
std::unique_ptr<WorkerDevToolsParams>);
// Posts a task to evaluate a top-level classic script on the worker thread.
- // Called on the main thread after Start().
+ // Called on the parent thread after Start().
void EvaluateClassicScript(const KURL& script_url,
const String& source_code,
std::unique_ptr<Vector<uint8_t>> cached_meta_data,
const v8_inspector::V8StackTraceId& stack_id);
// Posts a task to fetch and run a top-level classic script on the worker
- // thread. Called on the main thread after Start().
+ // thread. Called on the parent thread after Start().
void FetchAndRunClassicScript(
const KURL& script_url,
std::unique_ptr<WorkerMainScriptLoadParameters>
@@ -131,7 +132,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
const v8_inspector::V8StackTraceId& stack_id);
// Posts a task to fetch and run a top-level module script on the worker
- // thread. Called on the main thread after Start().
+ // thread. Called on the parent thread after Start().
void FetchAndRunModuleScript(
const KURL& script_url,
std::unique_ptr<WorkerMainScriptLoadParameters>
@@ -152,7 +153,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
// Terminates the worker thread. Subclasses of WorkerThread can override this
// to do cleanup. The default behavior is to call Terminate() and
// synchronously call EnsureScriptExecutionTerminates() to ensure the thread
- // is quickly terminated. Called on the main thread.
+ // is quickly terminated. Called on the parent thread.
virtual void TerminateForTesting();
// Thread::TaskObserver.
@@ -179,7 +180,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
void DebuggerTaskStarted();
void DebuggerTaskFinished();
- // Callable on both the main thread and the worker thread.
+ // Callable on both the parent thread and the worker thread.
const base::UnguessableToken& GetDevToolsWorkerToken() const {
return devtools_worker_token_;
}
@@ -323,7 +324,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
// already shutting down. Does not terminate if a debugger task is running,
// because the debugger task is guaranteed to finish and it heavily uses V8
// API calls which would crash after forcible script termination. Called on
- // the main thread.
+ // the parent thread.
void EnsureScriptExecutionTerminates(ExitCode) LOCKS_EXCLUDED(mutex_);
// These are called in this order during worker thread startup.
@@ -408,7 +409,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
// A unique identifier among all WorkerThreads.
const int worker_thread_id_;
- // Set on the main thread.
+ // Set on the parent thread.
bool requested_to_terminate_ GUARDED_BY(mutex_) = false;
ThreadState thread_state_ GUARDED_BY(mutex_) = ThreadState::kNotStarted;
@@ -442,7 +443,7 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
TaskTypeTraits>;
TaskRunnerHashMap worker_task_runners_;
- // This lock protects shared states between the main thread and the worker
+ // This lock protects shared states between the parent thread and the worker
// thread. See thread-safety annotations (e.g., GUARDED_BY) in this header
// file.
Mutex mutex_;
@@ -451,6 +452,10 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
// only on the worker thread.
int pause_or_freeze_count_ = 0;
+ // The `PauseHandle` needs to be destroyed before the scheduler is destroyed
+ // otherwise we will hit a DCHECK.
+ std::unique_ptr<scheduler::WorkerScheduler::PauseHandle> pause_handle_;
+
// A nested message loop for handling pausing. Pointer is not owned. Used only
// on the worker thread.
Platform::NestedMessageLoopRunner* nested_runner_ = nullptr;
@@ -477,6 +482,12 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
HashSet<std::unique_ptr<InterruptData>> pending_interrupts_
GUARDED_BY(mutex_);
+ // Since the WorkerThread is allocated and deallocated on the parent thread,
+ // we need a WeakPtrFactory that is allocated and cleared on the backing
+ // thread.
+ absl::optional<base::WeakPtrFactory<WorkerThread>>
+ backing_thread_weak_factory_;
+
THREAD_CHECKER(parent_thread_checker_);
};

View File

@@ -0,0 +1,86 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Harald Alvestrand <hta@chromium.org>
Date: Mon, 10 Oct 2022 08:37:15 +0000
Subject: Use HeapMojoReceiver rather than mojo::Receiver for
PeerConnectionTracker
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
HeapMojoReceiver is recommended for garbage collected objects, avoiding
problems with conflicting lifetimes.
(cherry picked from commit e3437317c4cd8401f0f0d599b61751bbe0e1ec70)
Bug: chromium:1369882
Change-Id: Ic38e761cf4275e6d7b30a6d7e2daa5d1596e67a4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3936144
Reviewed-by: Henrik Boström <hbos@chromium.org>
Commit-Queue: Harald Alvestrand <hta@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1055630}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3934344
Commit-Queue: Henrik Boström <hbos@chromium.org>
Auto-Submit: Harald Alvestrand <hta@chromium.org>
Cr-Commit-Position: refs/branch-heads/5249@{#790}
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
index 7789929aafbb596d22c0af46e67bc4a1c9970fe9..1b068312ef9bea8f54dfbabee1a3bafc0c34801b 100644
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
@@ -648,16 +648,20 @@ PeerConnectionTracker::PeerConnectionTracker(
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
base::PassKey<PeerConnectionTracker>)
: Supplement<LocalDOMWindow>(window),
+ receiver_(this, &window),
main_thread_task_runner_(std::move(main_thread_task_runner)) {
window.GetBrowserInterfaceBroker().GetInterface(
peer_connection_tracker_host_.BindNewPipeAndPassReceiver());
}
+// Constructor used for testing. Note that receiver_ doesn't have a context
+// notifier in this case.
PeerConnectionTracker::PeerConnectionTracker(
mojo::Remote<blink::mojom::blink::PeerConnectionTrackerHost> host,
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
: Supplement(nullptr),
peer_connection_tracker_host_(std::move(host)),
+ receiver_(this, nullptr),
main_thread_task_runner_(std::move(main_thread_task_runner)) {}
PeerConnectionTracker::~PeerConnectionTracker() {}
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
index 101670d8a31154047762a060fcd13ce342dd758c..fc8ee4bc429d4abb637b121b6969880cb07f186d 100644
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h
@@ -15,6 +15,7 @@
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h"
@@ -257,6 +258,11 @@ class MODULES_EXPORT PeerConnectionTracker
virtual void TrackRtcEventLogWrite(RTCPeerConnectionHandler* pc_handler,
const WTF::Vector<uint8_t>& output);
+ void Trace(Visitor* visitor) const override {
+ visitor->Trace(receiver_);
+ Supplement<LocalDOMWindow>::Trace(visitor);
+ }
+
private:
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnSuspend);
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnThermalStateChange);
@@ -325,7 +331,9 @@ class MODULES_EXPORT PeerConnectionTracker
THREAD_CHECKER(main_thread_);
mojo::Remote<blink::mojom::blink::PeerConnectionTrackerHost>
peer_connection_tracker_host_;
- mojo::Receiver<blink::mojom::blink::PeerConnectionManager> receiver_{this};
+ HeapMojoReceiver<blink::mojom::blink::PeerConnectionManager,
+ PeerConnectionTracker>
+ receiver_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
};

View File

@@ -0,0 +1,70 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shrek Shao <shrekshao@google.com>
Date: Tue, 18 Oct 2022 01:30:12 +0000
Subject: WebGPU: use CHECK instead of DCHECK to crash out of bounds write in
SerializeDataUpdate
A comprised renderer could have a shared memory size not large enough
to fit the GPU buffer contents. Instead of DCHECK, do a CHECK here to
crash the release build. The crash is fine since it is not reachable
from normal behavior. WebGPU post-V1 will have a refactored API.
(cherry picked from commit 9bcbce75d5feaa1ba48a5d0d8036b5c77500bb67)
Fixed: 1373314
Change-Id: I8d8e1a469c2b10ff16e7363f9b6f7b63587cb007
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3946246
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Shrek Shao <shrekshao@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#1058233}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3956286
Owners-Override: Prudhvikumar Bommana <pbommana@google.com>
Reviewed-by: Prudhvikumar Bommana <pbommana@google.com>
Commit-Queue: Prudhvikumar Bommana <pbommana@google.com>
Cr-Commit-Position: refs/branch-heads/5249@{#850}
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
diff --git a/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc b/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
index 579cd3cbdfcd5990db02960413bcac86e41c69b2..a15b6f9b3b345079d8cf8251ca5f77b6e7ef647a 100644
--- a/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
+++ b/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
@@ -30,8 +30,13 @@ class ReadHandleImpl
size_t offset,
size_t size,
void* serializePointer) override {
- DCHECK_LE(offset, size_);
- DCHECK_LE(size, size_ - offset);
+ // TODO(crbug.com/1373314): A compromised renderer could have a shared
+ // memory size not large enough to fit the GPU buffer contents. Instead of
+ // DCHECK, do a CHECK here to crash the release build. The crash is fine
+ // since it is not reachable from normal behavior. WebGPU post-V1 will have
+ // a refactored API.
+ CHECK_LE(offset, size_);
+ CHECK_LE(size, size_ - offset);
// Copy the data into the shared memory allocation.
// In the case of buffer mapping, this is the mapped GPU memory which we
// copy into client-visible shared memory.
@@ -94,7 +99,10 @@ bool DawnServiceMemoryTransferService::DeserializeReadHandle(
size_t deserialize_size,
ReadHandle** read_handle) {
DCHECK(deserialize_pointer);
- DCHECK_EQ(deserialize_size, sizeof(MemoryTransferHandle));
+ // Use CHECK instead of DCHECK because the cast of the memory to
+ // MemoryTransferHandle and subsequent reads won't be safe if deserialize_size
+ // is too small.
+ CHECK_EQ(deserialize_size, sizeof(MemoryTransferHandle));
const volatile MemoryTransferHandle* handle =
reinterpret_cast<const volatile MemoryTransferHandle*>(
deserialize_pointer);
@@ -119,7 +127,10 @@ bool DawnServiceMemoryTransferService::DeserializeWriteHandle(
size_t deserialize_size,
WriteHandle** write_handle) {
DCHECK(deserialize_pointer);
- DCHECK_EQ(deserialize_size, sizeof(MemoryTransferHandle));
+ // Use CHECK instead of DCHECK because the cast of the memory to
+ // MemoryTransferHandle and subsequent reads won't be safe if deserialize_size
+ // is too small.
+ CHECK_EQ(deserialize_size, sizeof(MemoryTransferHandle));
const volatile MemoryTransferHandle* handle =
reinterpret_cast<const volatile MemoryTransferHandle*>(
deserialize_pointer);

View File

@@ -0,0 +1,46 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Stefan Zager <szager@chromium.org>
Date: Fri, 9 Sep 2022 01:56:46 +0000
Subject: Fix for reference to invalid iterator
Evidently, LocalFrameView::layout_subtree_root_list_ can be modified
during LayoutFromRootObject, leaving the loop variable in an invalid
state. I don't know the exact sequence, but the test case crashes for
me without this patch, and doesn't crash with the patch.
(cherry picked from commit 815aa5ca03ab4ecc619b2d2ad7650531bd3892a8)
Bug: 1355237
Change-Id: Ib17b1fac5b2ec060eda39be76305db18075802fa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3864877
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: Stefan Zager <szager@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1041903}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3884238
Owners-Override: Srinivas Sista <srinivassista@chromium.org>
Auto-Submit: Srinivas Sista <srinivassista@chromium.org>
Reviewed-by: Stefan Zager <szager@chromium.org>
Cr-Commit-Position: refs/branch-heads/5112@{#1566}
Cr-Branched-From: b13d3fe7b3c47a56354ef54b221008afa754412e-refs/heads/main@{#1012729}
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 8a9dabd602b54b4801406bffb26723b4105c5fdc..82963b7edb85da99f4bbf345b22e70d50ac1573c 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -821,6 +821,7 @@ void LocalFrameView::PerformLayout() {
}
for (auto& root : layout_subtree_root_list_.Ordered()) {
bool should_rebuild_fragments = false;
+ LayoutObject& root_layout_object = *root;
LayoutBlock* cb = root->ContainingNGBlock();
if (cb) {
auto it = fragment_tree_spines.find(cb);
@@ -840,7 +841,7 @@ void LocalFrameView::PerformLayout() {
// We need to ensure that we mark up all layoutObjects up to the
// LayoutView for paint invalidation. This simplifies our code as we
// just always do a full tree walk.
- if (LayoutObject* container = root->Container())
+ if (LayoutObject* container = root_layout_object.Container())
container->SetShouldCheckForPaintInvalidation();
}
layout_subtree_root_list_.Clear();

View File

@@ -0,0 +1,128 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ted Meyer <tmathmeyer@chromium.org>
Date: Wed, 8 Jun 2022 04:33:20 +0000
Subject: Add Stop method to BatchingMediaLog
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Now that ~MediaLog is posted for a later destruction due to garbage
collector ownership of CodecLogger, it's possible for the
SendQueuedMediaEvents call from ~BatchingMediaLog to reference
InspectorMediaEventHandler::inspector_context_ after it has been freed.
This fix forces BatchingMediaLog to shut down it's logging capabilities
when the destruction call is caused by the garbage collector deletion
phase
R=liberato
(cherry picked from commit 1bbfaf23cd8a1e977cb445a82a4caae107632a59)
Bug: 1333333
Change-Id: I0bdca72a71177c4c5a6a9dc692aad3de4c25f4e2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3689639
Commit-Queue: Ted (Chromium) Meyer <tmathmeyer@chromium.org>
Reviewed-by: Eugene Zemtsov <eugene@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1011247}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3694435
Auto-Submit: Ted (Chromium) Meyer <tmathmeyer@chromium.org>
Reviewed-by: Eugene Zemtsov <ezemtsov@google.com>
Commit-Queue: Eugene Zemtsov <eugene@chromium.org>
Cr-Commit-Position: refs/branch-heads/5060@{#672}
Cr-Branched-From: b83393d0f4038aeaf67f970a024d8101df7348d1-refs/heads/main@{#1002911}
diff --git a/content/renderer/media/batching_media_log.cc b/content/renderer/media/batching_media_log.cc
index 42b6fb68c294b9834f0b123ed18688482de460bc..efd56d9a0cf70cd502901d47d3639663445527e8 100644
--- a/content/renderer/media/batching_media_log.cc
+++ b/content/renderer/media/batching_media_log.cc
@@ -76,6 +76,11 @@ BatchingMediaLog::~BatchingMediaLog() {
SendQueuedMediaEvents();
}
+void BatchingMediaLog::Stop() {
+ base::AutoLock lock(lock_);
+ event_handlers_.clear();
+}
+
void BatchingMediaLog::OnWebMediaPlayerDestroyedLocked() {
base::AutoLock lock(lock_);
for (const auto& handler : event_handlers_)
diff --git a/content/renderer/media/batching_media_log.h b/content/renderer/media/batching_media_log.h
index eb757a4ca922bd5456d0e436d10cc540ee9134ae..6c2df688caee4d2fc17e973cdad12f20342e56fe 100644
--- a/content/renderer/media/batching_media_log.h
+++ b/content/renderer/media/batching_media_log.h
@@ -45,6 +45,8 @@ class CONTENT_EXPORT BatchingMediaLog : public media::MediaLog {
~BatchingMediaLog() override;
+ void Stop() override;
+
// Will reset |last_ipc_send_time_| with the value of NowTicks().
void SetTickClockForTesting(const base::TickClock* tick_clock);
diff --git a/media/base/media_log.cc b/media/base/media_log.cc
index 3728433c5eb473cc9c82b6cf33b22bbf89471eea..46887da3dc21c504b26d6ff174eb14d68298c6b1 100644
--- a/media/base/media_log.cc
+++ b/media/base/media_log.cc
@@ -49,6 +49,9 @@ std::string MediaLog::GetErrorMessageLocked() {
return "";
}
+// Default implementation.
+void MediaLog::Stop() {}
+
void MediaLog::AddMessage(MediaLogMessageLevel level, std::string message) {
std::unique_ptr<MediaLogRecord> record(
CreateRecord(MediaLogRecord::Type::kMessage));
diff --git a/media/base/media_log.h b/media/base/media_log.h
index e70a95b72f75f9bbfb114a94396c048bce2a3647..cce6a266327b43837d7a6ccaca7f2969c06fef4b 100644
--- a/media/base/media_log.h
+++ b/media/base/media_log.h
@@ -131,6 +131,10 @@ class MEDIA_EXPORT MediaLog {
// even if this occurs, in the "won't crash" sense.
virtual std::unique_ptr<MediaLog> Clone();
+ // Can be used for stopping a MediaLog during a garbage-collected destruction
+ // sequence.
+ virtual void Stop();
+
protected:
// Ensures only subclasses and factories (e.g. Clone()) can create MediaLog.
MediaLog();
diff --git a/third_party/blink/renderer/modules/webcodecs/codec_logger.h b/third_party/blink/renderer/modules/webcodecs/codec_logger.h
index 5d3f9fd53bcea8cf6220e862b095d5e109ff9857..44bbb6675e600145971339672a6eb9dc2f794daf 100644
--- a/third_party/blink/renderer/modules/webcodecs/codec_logger.h
+++ b/third_party/blink/renderer/modules/webcodecs/codec_logger.h
@@ -72,9 +72,20 @@ class MODULES_EXPORT CodecLogger final {
// This allows us to destroy |parent_media_log_| and stop logging,
// without causing problems to |media_log_| users.
media_log_ = parent_media_log_->Clone();
+
+ task_runner_ = task_runner;
}
- ~CodecLogger() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); }
+ ~CodecLogger() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ // media logs must be posted for destruction, since they can cause the
+ // garbage collector to trigger an immediate cleanup and delete the owning
+ // instance of |CodecLogger|.
+ if (parent_media_log_) {
+ parent_media_log_->Stop();
+ task_runner_->DeleteSoon(FROM_HERE, std::move(parent_media_log_));
+ }
+ }
void SendPlayerNameInformation(const ExecutionContext& context,
std::string loadedAs) {
@@ -135,6 +146,9 @@ class MODULES_EXPORT CodecLogger final {
// can be safely accessed, and whose raw pointer can be given callbacks.
std::unique_ptr<media::MediaLog> media_log_;
+ // Keep task runner around for posting the media log to upon destruction.
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
SEQUENCE_CHECKER(sequence_checker_);
};

View File

@@ -0,0 +1,305 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Wagner <benjaminwagner@google.com>
Date: Tue, 20 Sep 2022 18:38:53 +0000
Subject: Fix races in FrameQueueUnderlyingSource related to
CrossThreadPersistent
The repro in bug 1323488 unfortunately does not reliably reproduce
the races when run as a web test. I was also not able to repro the
races in a unit test.
There are actually three fixes in this CL; it was easiest to fix them
all together so that I can run the repro locally for an extended period
without it being stopped by a crash.
The underlying cause for all three races is that CrossThreadPersistent
can refer to an object whose heap has already been destroyed. When
accessed on the thread corresponding to that heap, there is no race,
but when accessed from a different thread, there is a period of time
after the heap is destroyed before the CrossThreadPersistent is
cleared.
1. The FrameQueueUnderlyingSource::transferred_source_ member's pointer
is accessed in FrameQueueUnderlyingSource::Close. This CL adds a
callback to clear the pointer in
TransferredFrameQueueUnderlyingSource::ContextDestroyed.
2. The TransferredFrameQueueUnderlyingSource constructor takes a raw
pointer to the original FrameQueueUnderlyingSource, which is
associated with a different thread. GC won't be able to update this
raw pointer since it's on the wrong stack. This CL changes the raw
pointer to a CrossThreadPersistent which is visible to GC.
3. Same as 2, but for the callstack ConnectHostCallback,
MediaStream(Audio|Video)TrackUnderlyingSource::OnSourceTransferStarted
and FrameQueueUnderlyingSource::TransferSource.
(cherry picked from commit 63ce9c40e1a67395278dfc70ecfb545a818747bb)
Bug: 1323488
Change-Id: Id63484eebefd2e003959b25bd752ac8263caab4f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3865452
Commit-Queue: Ben Wagner <benjaminwagner@google.com>
Reviewed-by: Thomas Guilbert <tguilbert@chromium.org>
Auto-Submit: Ben Wagner <benjaminwagner@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#1041434}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3908010
Commit-Queue: Srinivas Sista <srinivassista@chromium.org>
Reviewed-by: Srinivas Sista <srinivassista@chromium.org>
Cr-Commit-Position: refs/branch-heads/5249@{#521}
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
diff --git a/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.cc b/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.cc
index 2cc89e8cd32421bf80b262bac2e4a7cb685db62f..ab41fa086ad9eb8c1cd66db74ea1f05a66ac56a4 100644
--- a/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.cc
+++ b/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.cc
@@ -19,10 +19,13 @@ FrameQueueTransferringOptimizer<NativeFrameType>::
FrameQueueHost* host,
scoped_refptr<base::SequencedTaskRunner> host_runner,
wtf_size_t max_queue_size,
- ConnectHostCallback connect_host_callback)
+ ConnectHostCallback connect_host_callback,
+ CrossThreadOnceClosure transferred_source_destroyed_callback)
: host_(host),
host_runner_(std::move(host_runner)),
connect_host_callback_(std::move(connect_host_callback)),
+ transferred_source_destroyed_callback_(
+ std::move(transferred_source_destroyed_callback)),
max_queue_size_(max_queue_size) {}
template <typename NativeFrameType>
@@ -40,7 +43,8 @@ FrameQueueTransferringOptimizer<NativeFrameType>::PerformInProcessOptimization(
auto* source = MakeGarbageCollected<
TransferredFrameQueueUnderlyingSource<NativeFrameType>>(
- script_state, host, host_runner_);
+ script_state, host, host_runner_,
+ std::move(transferred_source_destroyed_callback_));
PostCrossThreadTask(
*host_runner_, FROM_HERE,
diff --git a/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.h b/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.h
index 6d33945b7c840e55ae73a1efd1f1cf33ccfaaa71..336073235ba7f6c05cf2cf19fccbfac0be9597c9 100644
--- a/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.h
+++ b/third_party/blink/renderer/modules/breakout_box/frame_queue_transferring_optimizer.h
@@ -25,13 +25,15 @@ class FrameQueueTransferringOptimizer final
using ConnectHostCallback = CrossThreadOnceFunction<void(
scoped_refptr<base::SequencedTaskRunner>,
- TransferredFrameQueueUnderlyingSource<NativeFrameType>*)>;
+ CrossThreadPersistent<
+ TransferredFrameQueueUnderlyingSource<NativeFrameType>>)>;
FrameQueueTransferringOptimizer(
FrameQueueHost*,
scoped_refptr<base::SequencedTaskRunner> host_runner,
wtf_size_t max_queue_size,
- ConnectHostCallback callback);
+ ConnectHostCallback connect_host_callback,
+ CrossThreadOnceFunction<void()> transferred_source_destroyed_callback);
~FrameQueueTransferringOptimizer() override = default;
UnderlyingSourceBase* PerformInProcessOptimization(
@@ -41,6 +43,7 @@ class FrameQueueTransferringOptimizer final
CrossThreadWeakPersistent<FrameQueueHost> host_;
scoped_refptr<base::SequencedTaskRunner> host_runner_;
ConnectHostCallback connect_host_callback_;
+ CrossThreadOnceFunction<void()> transferred_source_destroyed_callback_;
wtf_size_t max_queue_size_;
};
diff --git a/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.cc
index b93b67f131e1e58118e32d2c9b29e472a28d4664..fcd676b3035e19c6e0b28ee1c44109c6737a1c35 100644
--- a/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.cc
+++ b/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.cc
@@ -266,15 +266,22 @@ double FrameQueueUnderlyingSource<NativeFrameType>::DesiredSizeForTesting()
template <typename NativeFrameType>
void FrameQueueUnderlyingSource<NativeFrameType>::TransferSource(
- FrameQueueUnderlyingSource<NativeFrameType>* transferred_source) {
+ CrossThreadPersistent<FrameQueueUnderlyingSource<NativeFrameType>>
+ transferred_source) {
DCHECK(realm_task_runner_->RunsTasksInCurrentSequence());
MutexLocker locker(mutex_);
DCHECK(!transferred_source_);
- transferred_source_ = transferred_source;
+ transferred_source_ = std::move(transferred_source);
CloseController();
frame_queue_handle_.Invalidate();
}
+template <typename NativeFrameType>
+void FrameQueueUnderlyingSource<NativeFrameType>::ClearTransferredSource() {
+ MutexLocker locker(mutex_);
+ transferred_source_.Clear();
+}
+
template <typename NativeFrameType>
void FrameQueueUnderlyingSource<NativeFrameType>::CloseController() {
DCHECK(realm_task_runner_->RunsTasksInCurrentSequence());
diff --git a/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h
index a5d529a4231a8951e95adb6804ea45d82ccb4673..f7457b15002b244490b286f596e6e227d940ca52 100644
--- a/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h
+++ b/third_party/blink/renderer/modules/breakout_box/frame_queue_underlying_source.h
@@ -84,7 +84,13 @@ class FrameQueueUnderlyingSource
// QueueFrame(). |transferred_source| will pull frames from the same circular
// queue. Must be called on |realm_task_runner_|.
void TransferSource(
- FrameQueueUnderlyingSource<NativeFrameType>* transferred_source);
+ CrossThreadPersistent<FrameQueueUnderlyingSource<NativeFrameType>>
+ transferred_source);
+
+ // Due to a potential race condition between |transferred_source_|'s heap
+ // being destroyed and the Close() method being called, we need to explicitly
+ // clear |transferred_source_| when its context is being destroyed.
+ void ClearTransferredSource();
protected:
bool MustUseMonitor() const;
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
index bfc966452e4134e5133d559698497ce82f89aad4..da9a4bffc3a8c9ec5a1595a7cd78110bfadbfb5e 100644
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
@@ -93,14 +93,17 @@ MediaStreamAudioTrackUnderlyingSource::GetTransferringOptimizer() {
this, GetRealmRunner(), MaxQueueSize(),
CrossThreadBindOnce(
&MediaStreamAudioTrackUnderlyingSource::OnSourceTransferStarted,
+ WrapCrossThreadWeakPersistent(this)),
+ CrossThreadBindOnce(
+ &MediaStreamAudioTrackUnderlyingSource::ClearTransferredSource,
WrapCrossThreadWeakPersistent(this)));
}
void MediaStreamAudioTrackUnderlyingSource::OnSourceTransferStarted(
scoped_refptr<base::SequencedTaskRunner> transferred_runner,
- TransferredAudioDataQueueUnderlyingSource* source) {
+ CrossThreadPersistent<TransferredAudioDataQueueUnderlyingSource> source) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- TransferSource(source);
+ TransferSource(std::move(source));
RecordBreakoutBoxUsage(BreakoutBoxUsage::kReadableAudioWorker);
}
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
index 19a290ea6b83e4b56b8d96cb7632fca55bd65fd0..73c16dc5ff3855e258e1e70397def478485f1481 100644
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
@@ -56,7 +56,7 @@ class MODULES_EXPORT MediaStreamAudioTrackUnderlyingSource
void DisconnectFromTrack();
void OnSourceTransferStarted(
scoped_refptr<base::SequencedTaskRunner> transferred_runner,
- TransferredAudioDataQueueUnderlyingSource* source);
+ CrossThreadPersistent<TransferredAudioDataQueueUnderlyingSource> source);
// Only used to prevent the gargabe collector from reclaiming the media
// stream track processor that created |this|.
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc
index bcb941aca4e4d0729dc1253e01ef477fdaae1877..e748bf6eaf8f9d1acf8519c38a5a8cb53b031d0e 100644
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.cc
@@ -66,6 +66,9 @@ MediaStreamVideoTrackUnderlyingSource::GetStreamTransferOptimizer() {
this, GetRealmRunner(), MaxQueueSize(),
CrossThreadBindOnce(
&MediaStreamVideoTrackUnderlyingSource::OnSourceTransferStarted,
+ WrapCrossThreadWeakPersistent(this)),
+ CrossThreadBindOnce(
+ &MediaStreamVideoTrackUnderlyingSource::ClearTransferredSource,
WrapCrossThreadWeakPersistent(this)));
}
@@ -76,9 +79,9 @@ MediaStreamVideoTrackUnderlyingSource::GetIOTaskRunner() {
void MediaStreamVideoTrackUnderlyingSource::OnSourceTransferStarted(
scoped_refptr<base::SequencedTaskRunner> transferred_runner,
- TransferredVideoFrameQueueUnderlyingSource* source) {
+ CrossThreadPersistent<TransferredVideoFrameQueueUnderlyingSource> source) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- TransferSource(source);
+ TransferSource(std::move(source));
RecordBreakoutBoxUsage(BreakoutBoxUsage::kReadableVideoWorker);
}
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.h
index 1bbd4f6bbf20eaf168bf1319f1b35819dabe3cce..8964eb5eb83964c4bb2633092a12cb144da4e9b0 100644
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.h
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source.h
@@ -59,8 +59,9 @@ class MODULES_EXPORT MediaStreamVideoTrackUnderlyingSource
bool StartFrameDelivery() override;
void StopFrameDelivery() override;
- void OnSourceTransferStarted(scoped_refptr<base::SequencedTaskRunner>,
- TransferredVideoFrameQueueUnderlyingSource*);
+ void OnSourceTransferStarted(
+ scoped_refptr<base::SequencedTaskRunner>,
+ CrossThreadPersistent<TransferredVideoFrameQueueUnderlyingSource>);
void OnFrameFromTrack(
scoped_refptr<media::VideoFrame> media_frame,
diff --git a/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.cc
index 5c62b8f1b752c24f8b8d0048d646ea64dba0e49c..e38173482d455788861a1d831dd3422119d4d4d6 100644
--- a/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.cc
+++ b/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.cc
@@ -15,11 +15,14 @@ template <typename NativeFrameType>
TransferredFrameQueueUnderlyingSource<NativeFrameType>::
TransferredFrameQueueUnderlyingSource(
ScriptState* script_state,
- FrameQueueHost* host,
- scoped_refptr<base::SequencedTaskRunner> host_runner)
+ CrossThreadPersistent<FrameQueueHost> host,
+ scoped_refptr<base::SequencedTaskRunner> host_runner,
+ CrossThreadOnceClosure transferred_source_destroyed_callback)
: FrameQueueUnderlyingSource<NativeFrameType>(script_state, host),
host_runner_(host_runner),
- host_(host) {}
+ host_(std::move(host)),
+ transferred_source_destroyed_callback_(
+ std::move(transferred_source_destroyed_callback)) {}
template <typename NativeFrameType>
bool TransferredFrameQueueUnderlyingSource<
@@ -44,6 +47,13 @@ void TransferredFrameQueueUnderlyingSource<
CrossThreadBindOnce(&FrameQueueHost::Close, host_));
}
+template <typename NativeFrameType>
+void TransferredFrameQueueUnderlyingSource<
+ NativeFrameType>::ContextDestroyed() {
+ std::move(transferred_source_destroyed_callback_).Run();
+ FrameQueueUnderlyingSource<NativeFrameType>::ContextDestroyed();
+}
+
template <typename NativeFrameType>
void TransferredFrameQueueUnderlyingSource<NativeFrameType>::Trace(
Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h
index 5f8a36719407a404756d672530c0b9fcff9d6924..7cd3270fbb3cf5b0e2c09b16000ea5c0e4247866 100644
--- a/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h
+++ b/third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h
@@ -19,8 +19,9 @@ class TransferredFrameQueueUnderlyingSource
TransferredFrameQueueUnderlyingSource(
ScriptState*,
- FrameQueueHost*,
- scoped_refptr<base::SequencedTaskRunner> host_runner);
+ CrossThreadPersistent<FrameQueueHost>,
+ scoped_refptr<base::SequencedTaskRunner> host_runner,
+ CrossThreadOnceClosure transferred_source_destroyed_callback);
~TransferredFrameQueueUnderlyingSource() override = default;
TransferredFrameQueueUnderlyingSource(
@@ -32,11 +33,15 @@ class TransferredFrameQueueUnderlyingSource
bool StartFrameDelivery() override;
void StopFrameDelivery() override;
+ // ExecutionLifecycleObserver
+ void ContextDestroyed() override;
+
void Trace(Visitor*) const override;
private:
scoped_refptr<base::SequencedTaskRunner> host_runner_;
CrossThreadPersistent<FrameQueueHost> host_;
+ CrossThreadOnceClosure transferred_source_destroyed_callback_;
};
extern template class MODULES_EXTERN_TEMPLATE_EXPORT

View File

@@ -0,0 +1,125 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hassan Talat <hatalat@microsoft.com>
Date: Mon, 13 Jun 2022 21:27:53 +0000
Subject: dpwa: Enable Window Controls Overlay by default
This reverts commit d61c4042374672712176e43e33f39a1e66da4faa.
I2S: https://groups.google.com/a/chromium.org/g/blink-dev/c/guI1QCPJTAA
Bug: 937121
Change-Id: I3dfebec2356c7a12fd7eab32f12ef8d9e4bf6ee6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3430266
Commit-Queue: Alex Russell <slightlyoff@chromium.org>
Reviewed-by: Alex Russell <slightlyoff@chromium.org>
Reviewed-by: Avi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1013665}
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index aa4a054fad59f57af17251a3ede7cd6c9806b4cb..ea32976ab88bdae7417b2e0ce25d6778369085ae 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -1045,7 +1045,7 @@ const base::Feature kV8VmFuture{"V8VmFuture",
// Enable window controls overlays for desktop PWAs
const base::Feature kWebAppWindowControlsOverlay{
- "WebAppWindowControlsOverlay", base::FEATURE_DISABLED_BY_DEFAULT};
+ "WebAppWindowControlsOverlay", base::FEATURE_ENABLED_BY_DEFAULT};
// Enable WebAssembly baseline compilation (Liftoff).
const base::Feature kWebAssemblyBaseline{"WebAssemblyBaseline",
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 47cfcc8c758bed2fe46c6c75ba45b3cec2576ba6..ebf862fcc88579db6300b6972187f4b06f2af9e3 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -2543,7 +2543,7 @@
name: "WebAppWindowControlsOverlay",
origin_trial_feature_name: "WebAppWindowControlsOverlay",
origin_trial_os: ["win", "mac", "linux", "chromeos"],
- status: "experimental",
+ status: "stable",
},
{
name: "WebAssemblyCSP",
diff --git a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
index a2bac6e1f0fc6404a8fabbab87cd78da3e50570c..d6e4d3d5846ec3de2056af5a89a74f168a0e216d 100644
--- a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
@@ -77,6 +77,8 @@ PASS window.cached_navigator_virtualKeyboard.boundingRect.x is 0
PASS window.cached_navigator_virtualKeyboard.boundingRect.y is 0
PASS window.cached_navigator_virtualKeyboard.ongeometrychange is null
PASS window.cached_navigator_virtualKeyboard.overlaysContent is false
+PASS window.cached_navigator_windowControlsOverlay.ongeometrychange is null
+PASS window.cached_navigator_windowControlsOverlay.visible is false
PASS window.cached_navigator_xr.ondevicechange is null
PASS window.cached_performance.onresourcetimingbufferfull is null
PASS window.cached_performance_navigation.redirectCount is 0
diff --git a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
index 9b413dea03d864d6cef496279187b39cf81ba4b0..5cfdedb36e5f9bd0dbfae11d5ba5cc1172823071 100644
--- a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
@@ -77,6 +77,8 @@ PASS window.cached_navigator_virtualKeyboard.boundingRect.x is 0
PASS window.cached_navigator_virtualKeyboard.boundingRect.y is 0
PASS window.cached_navigator_virtualKeyboard.ongeometrychange is null
PASS window.cached_navigator_virtualKeyboard.overlaysContent is false
+PASS window.cached_navigator_windowControlsOverlay.ongeometrychange is null
+PASS window.cached_navigator_windowControlsOverlay.visible is false
PASS window.cached_navigator_xr.ondevicechange is null
PASS window.cached_performance.onresourcetimingbufferfull is null
PASS window.cached_performance_navigation.redirectCount is 0
diff --git a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
index 6f480ccfc7031fbdab98b50511a667aed5840af1..37bba469a00c719128762f861313e383d1ad4b86 100644
--- a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
@@ -77,6 +77,8 @@ PASS window.cached_navigator_virtualKeyboard.boundingRect.x is 0
PASS window.cached_navigator_virtualKeyboard.boundingRect.y is 0
PASS window.cached_navigator_virtualKeyboard.ongeometrychange is null
PASS window.cached_navigator_virtualKeyboard.overlaysContent is false
+PASS window.cached_navigator_windowControlsOverlay.ongeometrychange is null
+PASS window.cached_navigator_windowControlsOverlay.visible is false
PASS window.cached_navigator_xr.ondevicechange is null
PASS window.cached_performance.onresourcetimingbufferfull is null
PASS window.cached_performance_navigation.redirectCount is 0
diff --git a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
index ef72385e2cc50ae9519f2d0cf496e8cc771cf5aa..36efa30d35e4b8e5e7752bfde58f50cdef865e89 100644
--- a/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
@@ -87,6 +87,8 @@ PASS oldChildWindow.navigator.virtualKeyboard.boundingRect.y is newChildWindow.n
PASS oldChildWindow.navigator.virtualKeyboard.ongeometrychange is newChildWindow.navigator.virtualKeyboard.ongeometrychange
PASS oldChildWindow.navigator.virtualKeyboard.overlaysContent is newChildWindow.navigator.virtualKeyboard.overlaysContent
PASS oldChildWindow.navigator.webdriver is newChildWindow.navigator.webdriver
+PASS oldChildWindow.navigator.windowControlsOverlay.ongeometrychange is newChildWindow.navigator.windowControlsOverlay.ongeometrychange
+PASS oldChildWindow.navigator.windowControlsOverlay.visible is newChildWindow.navigator.windowControlsOverlay.visible
PASS oldChildWindow.navigator.xr.ondevicechange is newChildWindow.navigator.xr.ondevicechange
PASS oldChildWindow.onabort is newChildWindow.onabort
PASS oldChildWindow.onafterprint is newChildWindow.onafterprint
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
index 1f0f00e9879c0e5f24029617d146f760e6abb100..6789814dd76154ce4d2547d5e89616255585249f 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -4955,6 +4955,7 @@ interface Navigator
getter webdriver
getter webkitPersistentStorage
getter webkitTemporaryStorage
+ getter windowControlsOverlay
getter xr
method clearAppBadge
method constructor
@@ -9646,6 +9647,18 @@ interface Window : EventTarget
attribute PERSISTENT
attribute TEMPORARY
method constructor
+interface WindowControlsOverlay : EventTarget
+ attribute @@toStringTag
+ getter ongeometrychange
+ getter visible
+ method constructor
+ method getTitlebarAreaRect
+ setter ongeometrychange
+interface WindowControlsOverlayGeometryChangeEvent : Event
+ attribute @@toStringTag
+ getter titlebarAreaRect
+ getter visible
+ method constructor
interface Worker : EventTarget
attribute @@toStringTag
getter onerror

View File

@@ -0,0 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Adam Rice <ricea@chromium.org>
Date: Thu, 2 Jun 2022 07:33:07 +0000
Subject: Fix crash-on-close for Mac UDP sockets
guarded_close_np() on UDP sockets on Mac may fail with an EPROTOTYPE
error. Avoid a crash for that error as well as the ENOTCONN error we are
already checking for.
BUG=1151048
Change-Id: I11ed84b879fbeda6bd6aee8614e54d8ed791f4ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3682001
Commit-Queue: Adam Rice <ricea@chromium.org>
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1009976}
diff --git a/net/socket/udp_socket_posix.cc b/net/socket/udp_socket_posix.cc
index 63ae4274d11f53b0e2edf25ebcceb580813455d9..43e1ab15e2f1b66fb7946db6c0cbdae86a6a85a0 100644
--- a/net/socket/udp_socket_posix.cc
+++ b/net/socket/udp_socket_posix.cc
@@ -320,19 +320,20 @@ void UDPSocketPosix::Close() {
: perfetto::StaticString{"CloseSocketUDP"});
// Attempt to clear errors on the socket so that they are not returned by
- // close(). See https://crbug.com/1151048.
+ // close(). This seems to be effective at clearing some, but not all,
+ // EPROTOTYPE errors. See https://crbug.com/1151048.
int value = 0;
socklen_t value_len = sizeof(value);
HANDLE_EINTR(getsockopt(socket_, SOL_SOCKET, SO_ERROR, &value, &value_len));
if (IGNORE_EINTR(guarded_close_np(socket_, &kSocketFdGuard)) != 0) {
- // There is a bug in the Mac OS kernel that it can return an
- // ENOTCONN error. In this case we don't know whether the file
- // descriptor is still allocated or not. We cannot safely close the
- // file descriptor because it may have been reused by another
- // thread in the meantime. We may leak file handles here and cause
- // a crash indirectly later. See https://crbug.com/1151048.
- PCHECK(errno == ENOTCONN);
+ // There is a bug in the Mac OS kernel that it can return an ENOTCONN or
+ // EPROTOTYPE error. In this case we don't know whether the file descriptor
+ // is still allocated or not. We cannot safely close the file descriptor
+ // because it may have been reused by another thread in the meantime. We may
+ // leak file handles here and cause a crash indirectly later. See
+ // https://crbug.com/1151048.
+ PCHECK(errno == ENOTCONN || errno == EPROTOTYPE);
}
#else
PCHECK(IGNORE_EINTR(close(socket_)) == 0);

View File

@@ -0,0 +1,115 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jacobo=20Aragunde=20P=C3=A9rez?= <jaragunde@igalia.com>
Date: Fri, 20 May 2022 10:22:05 +0000
Subject: Refresh cached attributes before name computation traversal.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It was possible to trigger a children clear operation while running
TextFromDescendants to compute a node name from its children. This
is the sequence:
* A node changes its aria-hidden value.
* We run TextFromDescendants on that node, it queries the hidden value
for each child.
* To know the hidden value, it refreshes cached attributes in
UpdateCachedAttributeValuesIfNeeded
* To refresh the cached aria-hidden value, it needs to check the
parent's aria-hidden
* The parent also refreshes cached attributes in
UpdateCachedAttributeValuesIfNeeded
* It detects aria-hidden value has changed, that triggers
SetNeedsToUpdateChildren, which runs ClearChildren
To prevent children being cleared while we traverse them, which can
cause an invalid pointer being addressed, we run a refresh of cached
values before the traversal, knowing that operation may trigger a
children clear (and we will need to use those cached values anyway).
We also add a regression test, based on a clusterfuzz-generated one,
which is known to trigger this situation.
Bug: 1315044
Change-Id: I0a7ca27cca5d93fbdbc07d31cab6a21b1401d8dc
AX-relnotes: prevent crash in name computation.
Cq-Include-Trybots: luci.chromium.try:linux-blink-web-tests-force-accessibility-rel
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3633568
Commit-Queue: Jacobo Aragunde Pérez <jaragunde@igalia.com>
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1005708}
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index ee4bc3c0766c2d1b6f279e5a9cf12303af098f0a..44304f626679bb7b4fc5f631170462bf0d79a120 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -3277,6 +3277,12 @@ IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AriaHiddenTabindexChange) {
RunRegressionTest(FILE_PATH_LITERAL("aria-hidden-tabindex-change.html"));
}
+IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest,
+ ClearChildrenWhileComputingName) {
+ RunRegressionTest(
+ FILE_PATH_LITERAL("clear-children-while-computing-name.html"));
+}
+
IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, HiddenTable) {
RunRegressionTest(FILE_PATH_LITERAL("hidden-table.html"));
}
diff --git a/content/test/data/accessibility/regression/clear-children-while-computing-name-expected-blink.txt b/content/test/data/accessibility/regression/clear-children-while-computing-name-expected-blink.txt
new file mode 100644
index 0000000000000000000000000000000000000000..59e71c6983acae4e4cb519e423f3aa2db030c88a
--- /dev/null
+++ b/content/test/data/accessibility/regression/clear-children-while-computing-name-expected-blink.txt
@@ -0,0 +1,7 @@
+rootWebArea name='done'
+++genericContainer ignored
+++++genericContainer ignored
+++++++genericContainer ignored invisible
+++++++++heading ignored invisible
+++++++++++staticText ignored invisible name='Browser'
+++++++++genericContainer ignored invisible
diff --git a/content/test/data/accessibility/regression/clear-children-while-computing-name.html b/content/test/data/accessibility/regression/clear-children-while-computing-name.html
new file mode 100644
index 0000000000000000000000000000000000000000..415e25e70604ac74a73618075e0b97fca3b08bac
--- /dev/null
+++ b/content/test/data/accessibility/regression/clear-children-while-computing-name.html
@@ -0,0 +1,23 @@
+<!--
+@WAIT-FOR:done
+-->
+<head>
+<style>
+.c4 {}
+</style>
+</head>
+<body>
+<div id="container">
+ <h3 id="heading">Browser</h3>
+ <a id="anchor"></a>
+</div>
+<script>
+ function crash() {
+ document.getElementById('container').setAttribute('aria-hidden', 'true');
+ document.getElementById('heading').setAttribute('aria-hidden', 'false');
+ document.getElementById('anchor').setAttribute('class', 'c4');
+ heading['computedName']; // access to the property triggers name computation
+ document.title = 'done';
+ }
+ setTimeout(crash, 100);
+</script>
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index 0beba99f522a9932390306e46988832ddbc258b0..ddfeeb3f32a8a0448ecae3ee54ba8b3c3e0f68c5 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -3444,6 +3444,10 @@ String AXNodeObject::TextFromDescendants(
ax::mojom::blink::NameFrom last_used_name_from =
ax::mojom::blink::NameFrom::kUninitialized;
+ // Ensure that if this node needs to invalidate its children (e.g. due to
+ // included in tree status change), that we do it now, rather than while
+ // traversing the children.
+ UpdateCachedAttributeValuesIfNeeded();
#if defined(AX_FAIL_FAST_BUILD)
base::AutoReset<bool> auto_reset(&is_computing_text_from_descendants_, true);
#endif

View File

@@ -0,0 +1,89 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jacobo=20Aragunde=20P=C3=A9rez?= <jaragunde@igalia.com>
Date: Fri, 27 May 2022 14:42:10 +0000
Subject: Review add/clear children checks during accname traversal.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We want to make sure there are no new children added to a node while
we traverse them for accname computation. There is a check for
(!is_adding_children_) in TextFromDescendants(), but it's not really
serving that purpose: the AddChildren() operation will start and end,
resetting is_adding_children_, before execution flows back to
TextFromDescendants().
We reverse the condition, checking for the flag
is_computing_text_from_descendants_ in AddChildren(), which should
detect the situation explained above.
We replace the DCHECK for a check, because we want these to be caught
not only in debug builds.
Bug: none.
Change-Id: I88039838bd5b50257871c223633c4eb69d5c3878
Cq-Include-Trybots: luci.chromium.try:linux-blink-web-tests-force-accessibility-rel
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3657488
Commit-Queue: Jacobo Aragunde Pérez <jaragunde@igalia.com>
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1008248}
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index ddfeeb3f32a8a0448ecae3ee54ba8b3c3e0f68c5..7476ecdd4904e6b62e16da7aef2a9e15b8a84967 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -3433,9 +3433,6 @@ String AXNodeObject::TextFromDescendants(
AXObjectSet& visited,
const AXObject* aria_label_or_description_root,
bool recursive) const {
-#if defined(AX_FAIL_FAST_BUILD)
- DCHECK(!is_adding_children_);
-#endif
if (!CanHaveChildren())
return recursive ? String() : GetElement()->GetInnerTextWithoutUpdate();
@@ -3448,11 +3445,12 @@ String AXNodeObject::TextFromDescendants(
// included in tree status change), that we do it now, rather than while
// traversing the children.
UpdateCachedAttributeValuesIfNeeded();
+
+ const AXObjectVector& children = ChildrenIncludingIgnored();
#if defined(AX_FAIL_FAST_BUILD)
base::AutoReset<bool> auto_reset(&is_computing_text_from_descendants_, true);
#endif
-
- for (AXObject* child : ChildrenIncludingIgnored()) {
+ for (AXObject* child : children) {
constexpr size_t kMaxDescendantsForTextAlternativeComputation = 100;
if (visited.size() > kMaxDescendantsForTextAlternativeComputation)
break;
@@ -4123,6 +4121,10 @@ void AXNodeObject::AddChildren() {
#endif
#if defined(AX_FAIL_FAST_BUILD)
+ SANITIZER_CHECK(!is_computing_text_from_descendants_)
+ << "Should not attempt to simultaneously compute text from descendants "
+ "and add children on: "
+ << ToString(true, true);
SANITIZER_CHECK(!is_adding_children_)
<< " Reentering method on " << GetNode();
base::AutoReset<bool> reentrancy_protector(&is_adding_children_, true);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index 06fd95c7c457c20cde3a53bbafcac23dba8fb21c..de987935346051c4f9e1cfdd7c9290376c4c0e2a 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -4923,11 +4923,12 @@ void AXObject::ClearChildren() const {
// AccessibilityExposeIgnoredNodes().
// Loop through AXObject children.
+
#if defined(AX_FAIL_FAST_BUILD)
- CHECK(!is_adding_children_)
+ SANITIZER_CHECK(!is_adding_children_)
<< "Should not attempt to simultaneously add and clear children on: "
<< ToString(true, true);
- CHECK(!is_computing_text_from_descendants_)
+ SANITIZER_CHECK(!is_computing_text_from_descendants_)
<< "Should not attempt to simultaneously compute text from descendants "
"and clear children on: "
<< ToString(true, true);

View File

@@ -23,5 +23,13 @@
"src/electron/patches/angle": "src/third_party/angle",
"src/electron/patches/sqlite": "src/third_party/sqlite/src"
"src/electron/patches/sqlite": "src/third_party/sqlite/src",
"src/electron/patches/pdfium": "src/third_party/pdfium",
"src/electron/patches/ffmpeg": "src/third_party/ffmpeg",
"src/electron/patches/libaom": "src/third_party/libaom/source/libaom",
"src/electron/patches/skia": "src/third_party/skia"
}

1
patches/ffmpeg/.patches Normal file
View File

@@ -0,0 +1 @@
cherry-pick-c2c8cac2131b.patch

View File

@@ -0,0 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <michael@niedermayer.cc>
Date: Thu, 28 Jul 2022 14:42:43 +0200
Subject: avformat/mov: Check count sums in build_open_gop_key_points()
Fixes: ffmpeg.md
Fixes: Out of array access
Fixes: CVE-2022-2566
Bug: 1348283
Found-by: Andy Nguyen <theflow@google.com>
Found-by: 3pvd <3pvd@google.com>
Change-Id: I6821c87acce5a62cd9a5b829c17f56ae6418116a
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 64d7d8d0e5035087ebe24a65845b36f78e7fad92)
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/third_party/ffmpeg/+/3890391
Reviewed-by: Matthew Wolenetz <wolenetz@chromium.org>
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 124c8e907f2e0cb5777b5433ccdb17ac52f0b6eb..595babcd4bfb1298d2928b1f4c9b40b2d09971e9 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -3943,8 +3943,11 @@ static int build_open_gop_key_points(AVStream *st)
/* Build an unrolled index of the samples */
sc->sample_offsets_count = 0;
- for (uint32_t i = 0; i < sc->ctts_count; i++)
+ for (uint32_t i = 0; i < sc->ctts_count; i++) {
+ if (sc->ctts_data[i].count > INT_MAX - sc->sample_offsets_count)
+ return AVERROR(ENOMEM);
sc->sample_offsets_count += sc->ctts_data[i].count;
+ }
av_freep(&sc->sample_offsets);
sc->sample_offsets = av_calloc(sc->sample_offsets_count, sizeof(*sc->sample_offsets));
if (!sc->sample_offsets)
@@ -3963,8 +3966,11 @@ static int build_open_gop_key_points(AVStream *st)
/* Build a list of open-GOP key samples */
sc->open_key_samples_count = 0;
for (uint32_t i = 0; i < sc->sync_group_count; i++)
- if (sc->sync_group[i].index == cra_index)
+ if (sc->sync_group[i].index == cra_index) {
+ if (sc->sync_group[i].count > INT_MAX - sc->open_key_samples_count)
+ return AVERROR(ENOMEM);
sc->open_key_samples_count += sc->sync_group[i].count;
+ }
av_freep(&sc->open_key_samples);
sc->open_key_samples = av_calloc(sc->open_key_samples_count, sizeof(*sc->open_key_samples));
if (!sc->open_key_samples)
@@ -3975,6 +3981,8 @@ static int build_open_gop_key_points(AVStream *st)
if (sg->index == cra_index)
for (uint32_t j = 0; j < sg->count; j++)
sc->open_key_samples[k++] = sample_id;
+ if (sg->count > INT_MAX - sample_id)
+ return AVERROR_PATCHWELCOME;
sample_id += sg->count;
}

1
patches/libaom/.patches Normal file
View File

@@ -0,0 +1 @@
use_non_normative_scaler_for_non_optimized_ratio.patch

View File

@@ -0,0 +1,96 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jerome Jiang <jianj@google.com>
Date: Tue, 30 Aug 2022 14:45:28 -0400
Subject: Use non normative scaler for non optimized ratio
There are only optimized scalers for 1/4, 1/2 and 3/4 scaling ratio.
SSSE3 also has 2x upscaling optimization.
Use non normative scalers for all other scaling ratios.
Bug: chromium:1346938
Bug: chromium:1338114
Change-Id: I2a01717b56c53c42906440d5a3f95ca2c00dc571
(cherry picked from commit ff7b753a63a536423a91b64a066bd385c52ceacc)
diff --git a/av1/common/resize.c b/av1/common/resize.c
index a3c3c0e5160940974fbbbc84d7011fb4bd26f67e..322363fa1e136ce3b77498b9c20b63d27d339471 100644
--- a/av1/common/resize.c
+++ b/av1/common/resize.c
@@ -1366,15 +1366,20 @@ YV12_BUFFER_CONFIG *av1_realloc_and_scale_if_required(
aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
"Failed to allocate scaled buffer");
+ const bool has_optimized_scaler = av1_has_optimized_scaler(
+ unscaled->y_crop_width, unscaled->y_crop_height, scaled_width,
+ scaled_height);
+
#if CONFIG_AV1_HIGHBITDEPTH
- if (use_optimized_scaler && cm->seq_params->bit_depth == AOM_BITS_8) {
+ if (use_optimized_scaler && has_optimized_scaler &&
+ cm->seq_params->bit_depth == AOM_BITS_8) {
av1_resize_and_extend_frame(unscaled, scaled, filter, phase, num_planes);
} else {
av1_resize_and_extend_frame_nonnormative(
unscaled, scaled, (int)cm->seq_params->bit_depth, num_planes);
}
#else
- if (use_optimized_scaler) {
+ if (use_optimized_scaler && has_optimized_scaler) {
av1_resize_and_extend_frame(unscaled, scaled, filter, phase, num_planes);
} else {
av1_resize_and_extend_frame_nonnormative(
diff --git a/av1/common/resize.h b/av1/common/resize.h
index 75abe6274ee73a202bddd14962f1a4ae8083ce94..9bc23b3ffacd4121bf32dd96bae82ba5c799b1ea 100644
--- a/av1/common/resize.h
+++ b/av1/common/resize.h
@@ -105,6 +105,24 @@ static INLINE int av1_superres_scaled(const AV1_COMMON *cm) {
return !(cm->width == cm->superres_upscaled_width);
}
+// There's SIMD optimizations for 1/4, 1/2 and 3/4 downscaling.
+// SSSE3 also has optimizations for 2x upscaling.
+// Use non normative scalers for other scaling ratios.
+static INLINE bool av1_has_optimized_scaler(const int src_width,
+ const int src_height,
+ const int dst_width,
+ const int dst_height) {
+ const bool has_optimized_scaler =
+ (dst_width * 4 == src_width && dst_height * 4 == src_height) ||
+ (dst_width * 2 == src_width && dst_height * 2 == src_height) ||
+ (dst_width * 4 == src_width * 3 && dst_height * 4 == src_height * 3);
+#if HAVE_SSSE3
+ return has_optimized_scaler ||
+ (dst_width == src_width * 2 && dst_height == src_height * 2);
+#endif
+ return has_optimized_scaler;
+}
+
#define UPSCALE_NORMATIVE_TAPS 8
extern const int16_t av1_resize_filter_normative[1 << RS_SUBPEL_BITS]
[UPSCALE_NORMATIVE_TAPS];
diff --git a/av1/encoder/encoder_utils.c b/av1/encoder/encoder_utils.c
index fd8be7bf18e6a138bf20c25370c635cf3b302e10..cebea60eee37777b175f75d863f8cb94410a065a 100644
--- a/av1/encoder/encoder_utils.c
+++ b/av1/encoder/encoder_utils.c
@@ -733,15 +733,19 @@ void av1_scale_references(AV1_COMP *cpi, const InterpFilter filter,
aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
"Failed to allocate frame buffer");
}
+ const bool has_optimized_scaler = av1_has_optimized_scaler(
+ cm->width, cm->height, new_fb->buf.y_crop_width,
+ new_fb->buf.y_crop_height);
#if CONFIG_AV1_HIGHBITDEPTH
- if (use_optimized_scaler && cm->seq_params->bit_depth == AOM_BITS_8)
+ if (use_optimized_scaler && has_optimized_scaler &&
+ cm->seq_params->bit_depth == AOM_BITS_8)
av1_resize_and_extend_frame(ref, &new_fb->buf, filter, phase,
num_planes);
else
av1_resize_and_extend_frame_nonnormative(
ref, &new_fb->buf, (int)cm->seq_params->bit_depth, num_planes);
#else
- if (use_optimized_scaler)
+ if (use_optimized_scaler && has_optimized_scaler)
av1_resize_and_extend_frame(ref, &new_fb->buf, filter, phase,
num_planes);
else

View File

@@ -44,3 +44,4 @@ process_fix_hang_after_note_exit_3521.patch
feat_add_uv_loop_interrupt_on_io_change_option_to_uv_loop_configure.patch
fix_preserve_proper_method_names_as-is_in_error_stack.patch
macos_avoid_posix_spawnp_cwd_bug_3597.patch
buffer_fix_atob_input_validation.patch

View File

@@ -0,0 +1,89 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Tue, 23 Aug 2022 11:13:45 +0200
Subject: buffer: fix `atob` input validation
This patch combines:
* https://github.com/nodejs/node/pull/42539
* https://github.com/nodejs/node/pull/42662
To bring the Node.js implementation of atob into alignment with the
WHATWG spec.
diff --git a/lib/buffer.js b/lib/buffer.js
index 2d0057544395bc4aabff891fb30bfb9932a441f7..565753f76663611f0c069321b938c465b46f4ec8 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -23,8 +23,10 @@
const {
Array,
+ ArrayFrom,
ArrayIsArray,
ArrayPrototypeForEach,
+ ArrayPrototypeIndexOf,
Error,
MathFloor,
MathMin,
@@ -1227,8 +1229,25 @@ function btoa(input) {
return buf.toString('base64');
}
-const kBase64Digits =
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+// Refs: https://infra.spec.whatwg.org/#forgiving-base64-decode
+const kForgivingBase64AllowedChars = [
+ // ASCII whitespace
+ // Refs: https://infra.spec.whatwg.org/#ascii-whitespace
+ 0x09, 0x0A, 0x0C, 0x0D, 0x20,
+
+ // Uppercase letters
+ ...ArrayFrom({ length: 26 }, (_, i) => StringPrototypeCharCodeAt('A') + i),
+
+ // Lowercase letters
+ ...ArrayFrom({ length: 26 }, (_, i) => StringPrototypeCharCodeAt('a') + i),
+
+ // Decimal digits
+ ...ArrayFrom({ length: 10 }, (_, i) => StringPrototypeCharCodeAt('0') + i),
+
+ 0x2B, // +
+ 0x2F, // /
+ 0x3D, // =
+];
function atob(input) {
// The implementation here has not been performance optimized in any way and
@@ -1237,11 +1256,31 @@ function atob(input) {
if (arguments.length === 0) {
throw new ERR_MISSING_ARGS('input');
}
+
input = `${input}`;
+ let nonAsciiWhitespaceCharCount = 0;
+
for (let n = 0; n < input.length; n++) {
- if (!kBase64Digits.includes(input[n]))
+ const index = ArrayPrototypeIndexOf(
+ kForgivingBase64AllowedChars,
+ StringPrototypeCharCodeAt(input, n));
+
+ if (index > 4) {
+ // The first 5 elements of `kForgivingBase64AllowedChars` are
+ // ASCII whitespace char codes.
+ nonAsciiWhitespaceCharCount++;
+ } else if (index === -1) {
throw lazyDOMException('Invalid character', 'InvalidCharacterError');
+ }
}
+
+ // See #3 - https://infra.spec.whatwg.org/#forgiving-base64
+ if (nonAsciiWhitespaceCharCount % 4 === 1) {
+ throw lazyDOMException(
+ 'The string to be decoded is not correctly encoded.',
+ 'InvalidCharacterError');
+ }
+
return Buffer.from(input, 'base64').toString('latin1');
}

View File

@@ -6,7 +6,7 @@ Subject: fix: crash caused by GetHostNameW on Windows 7
Backported from https://github.com/libuv/libuv/pull/3285.
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 33e874ac442f88b58d2b68c8ec9764f6f664552e..2d4cc0aaa02e61bf359e80eca27527efb49fd85e 100644
index 33e874ac442f88b58d2b68c8ec9764f6f664552e..37ece5e2867ab836492a8b7faa0aa5e1b8e562f0 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -37,6 +37,7 @@
@@ -166,3 +166,17 @@ index 33e874ac442f88b58d2b68c8ec9764f6f664552e..2d4cc0aaa02e61bf359e80eca27527ef
int uv_os_gethostname(char* buffer, size_t* size) {
WCHAR buf[UV_MAXHOSTNAMESIZE];
size_t len;
@@ -1674,10 +1803,10 @@ int uv_os_gethostname(char* buffer, size_t* size) {
uv__once_init(); /* Initialize winsock */
- if (pGetHostNameW == NULL)
- return UV_ENOSYS;
+ uv_sGetHostNameW gethostnamew =
+ pGetHostNameW == NULL ? uv__gethostnamew_nt60 : pGetHostNameW;
- if (pGetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0)
+ if (gethostnamew(buf, UV_MAXHOSTNAMESIZE) != 0)
return uv_translate_sys_error(WSAGetLastError());
convert_result = uv__convert_utf16_to_utf8(buf, -1, &utf8_str);

View File

@@ -6,7 +6,7 @@ Subject: fix: suppress clang -Wdeprecated-declarations in libuv
Should be upstreamed.
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 2d4cc0aaa02e61bf359e80eca27527efb49fd85e..aaa16052e2a9c7d1dca82763c41c0890371f1471 100644
index 37ece5e2867ab836492a8b7faa0aa5e1b8e562f0..d50296728f7e0810064647125a469f3ed714f8ea 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -1950,10 +1950,17 @@ int uv_os_uname(uv_utsname_t* buffer) {

3
patches/pdfium/.patches Normal file
View File

@@ -0,0 +1,3 @@
cherry-pick-a66438897056.patch
cherry-pick-497f077a1d46.patch
cherry-pick-7f0bb5197ed1.patch

View File

@@ -0,0 +1,374 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Thu, 8 Sep 2022 23:05:34 +0000
Subject: Return retained const objects from SearchNameNodeByNameInternal()
Cherry-pick of d51720c9bb55d1163ab4fdcdc6981e753aa2354d + manual
conflict resolution.
Bug: chromium:1358075
Change-Id: Ibb20a6feaf79f7b351f22c607c306da40026d53e
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/97739
Auto-Submit: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h
index 223cd59ab7cb6cc2c08071118d1fbb3241904c6b..a2c067878847cc8ed17eb78bee416716f08a338b 100644
--- a/core/fpdfapi/parser/cpdf_array.h
+++ b/core/fpdfapi/parser/cpdf_array.h
@@ -194,4 +194,8 @@ inline RetainPtr<CPDF_Array> ToArray(RetainPtr<CPDF_Object> obj) {
return RetainPtr<CPDF_Array>(ToArray(obj.Get()));
}
+inline RetainPtr<const CPDF_Array> ToArray(RetainPtr<const CPDF_Object> obj) {
+ return RetainPtr<const CPDF_Array>(ToArray(obj.Get()));
+}
+
#endif // CORE_FPDFAPI_PARSER_CPDF_ARRAY_H_
diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h
index c7ccdc6eef50ddb93585975fb613ce442199e0ee..658ed6586959b5c2165589c9633060f86825c535 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.h
+++ b/core/fpdfapi/parser/cpdf_dictionary.h
@@ -170,4 +170,9 @@ inline RetainPtr<CPDF_Dictionary> ToDictionary(RetainPtr<CPDF_Object> obj) {
return RetainPtr<CPDF_Dictionary>(ToDictionary(obj.Get()));
}
+inline RetainPtr<const CPDF_Dictionary> ToDictionary(
+ RetainPtr<const CPDF_Object> obj) {
+ return RetainPtr<const CPDF_Dictionary>(ToDictionary(obj.Get()));
+}
+
#endif // CORE_FPDFAPI_PARSER_CPDF_DICTIONARY_H_
diff --git a/core/fpdfapi/parser/cpdf_number.h b/core/fpdfapi/parser/cpdf_number.h
index 864bbb2186f0c6208db9942121d2f80b214d46a1..0ca1130ec5a0f595054ff3e4d3d73c5e57f94e6c 100644
--- a/core/fpdfapi/parser/cpdf_number.h
+++ b/core/fpdfapi/parser/cpdf_number.h
@@ -49,4 +49,12 @@ inline const CPDF_Number* ToNumber(const CPDF_Object* obj) {
return obj ? obj->AsNumber() : nullptr;
}
+inline RetainPtr<CPDF_Number> ToNumber(RetainPtr<CPDF_Object> obj) {
+ return RetainPtr<CPDF_Number>(ToNumber(obj.Get()));
+}
+
+inline RetainPtr<const CPDF_Number> ToNumber(RetainPtr<const CPDF_Object> obj) {
+ return RetainPtr<const CPDF_Number>(ToNumber(obj.Get()));
+}
+
#endif // CORE_FPDFAPI_PARSER_CPDF_NUMBER_H_
diff --git a/core/fpdfapi/parser/cpdf_stream.h b/core/fpdfapi/parser/cpdf_stream.h
index 497db20cfcf98792bef6cb3b4bef1a4c0b1b1bff..171d93eb28e26baf1e51f4fafd4c83e39798f88b 100644
--- a/core/fpdfapi/parser/cpdf_stream.h
+++ b/core/fpdfapi/parser/cpdf_stream.h
@@ -92,4 +92,8 @@ inline RetainPtr<CPDF_Stream> ToStream(RetainPtr<CPDF_Object> obj) {
return RetainPtr<CPDF_Stream>(ToStream(obj.Get()));
}
+inline RetainPtr<const CPDF_Stream> ToStream(RetainPtr<const CPDF_Object> obj) {
+ return RetainPtr<const CPDF_Stream>(ToStream(obj.Get()));
+}
+
#endif // CORE_FPDFAPI_PARSER_CPDF_STREAM_H_
diff --git a/core/fpdfdoc/cpdf_dest.cpp b/core/fpdfdoc/cpdf_dest.cpp
index f3b11523918258e7702bda360129857165abc945..fcc09d9e580832678980987489d58ac3c7c0b9bf 100644
--- a/core/fpdfdoc/cpdf_dest.cpp
+++ b/core/fpdfdoc/cpdf_dest.cpp
@@ -41,9 +41,11 @@ CPDF_Dest CPDF_Dest::Create(CPDF_Document* pDoc, const CPDF_Object* pDest) {
if (!pDest)
return CPDF_Dest(nullptr);
- if (pDest->IsString() || pDest->IsName())
- return CPDF_Dest(CPDF_NameTree::LookupNamedDest(pDoc, pDest->GetString()));
-
+ if (pDest->IsString() || pDest->IsName()) {
+ // TODO(tsepez): make CPDF_Dest constructor take retained args.
+ return CPDF_Dest(
+ CPDF_NameTree::LookupNamedDest(pDoc, pDest->GetString()).Get());
+ }
return CPDF_Dest(pDest->AsArray());
}
diff --git a/core/fpdfdoc/cpdf_nametree.cpp b/core/fpdfdoc/cpdf_nametree.cpp
index 09d4a873fbd9e1151ddbe4f943903d796b18dbe1..2dfecbb5eeb95525c0a83023ee85b722588f3489 100644
--- a/core/fpdfdoc/cpdf_nametree.cpp
+++ b/core/fpdfdoc/cpdf_nametree.cpp
@@ -170,7 +170,7 @@ bool UpdateNodesAndLimitsUponDeletion(CPDF_Dictionary* pNode,
// will be the index of |csName| in |ppFind|. If |csName| is not found, |ppFind|
// will be the leaf array that |csName| should be added to, and |pFindIndex|
// will be the index that it should be added at.
-CPDF_Object* SearchNameNodeByNameInternal(
+RetainPtr<const CPDF_Object> SearchNameNodeByNameInternal(
const RetainPtr<CPDF_Dictionary>& pNode,
const WideString& csName,
int nLevel,
@@ -217,7 +217,7 @@ CPDF_Object* SearchNameNodeByNameInternal(
continue;
*nIndex += i;
- return pNames->GetDirectObjectAt(i * 2 + 1);
+ return pdfium::WrapRetain(pNames->GetDirectObjectAt(i * 2 + 1));
}
*nIndex += dwCount;
return nullptr;
@@ -233,7 +233,7 @@ CPDF_Object* SearchNameNodeByNameInternal(
if (!pKid)
continue;
- CPDF_Object* pFound = SearchNameNodeByNameInternal(
+ RetainPtr<const CPDF_Object> pFound = SearchNameNodeByNameInternal(
pKid, csName, nLevel + 1, nIndex, ppFind, pFindIndex);
if (pFound)
return pFound;
@@ -243,10 +243,11 @@ CPDF_Object* SearchNameNodeByNameInternal(
// Wrapper for SearchNameNodeByNameInternal() so callers do not need to know
// about the details.
-CPDF_Object* SearchNameNodeByName(const RetainPtr<CPDF_Dictionary>& pNode,
- const WideString& csName,
- RetainPtr<CPDF_Array>* ppFind,
- int* pFindIndex) {
+RetainPtr<const CPDF_Object> SearchNameNodeByName(
+ const RetainPtr<CPDF_Dictionary>& pNode,
+ const WideString& csName,
+ RetainPtr<CPDF_Array>* ppFind,
+ int* pFindIndex) {
size_t nIndex = 0;
return SearchNameNodeByNameInternal(pNode, csName, 0, &nIndex, ppFind,
pFindIndex);
@@ -344,24 +345,25 @@ size_t CountNamesInternal(CPDF_Dictionary* pNode, int nLevel) {
return nCount;
}
-CPDF_Array* GetNamedDestFromObject(CPDF_Object* obj) {
- if (!obj)
- return nullptr;
- CPDF_Array* array = obj->AsArray();
+RetainPtr<const CPDF_Array> GetNamedDestFromObject(
+ RetainPtr<const CPDF_Object> obj) {
+ RetainPtr<const CPDF_Array> array = ToArray(obj);
if (array)
return array;
- CPDF_Dictionary* dict = obj->AsDictionary();
+ RetainPtr<const CPDF_Dictionary> dict = ToDictionary(obj);
if (dict)
- return dict->GetArrayFor("D");
+ return pdfium::WrapRetain(dict->GetArrayFor("D"));
return nullptr;
}
-CPDF_Array* LookupOldStyleNamedDest(CPDF_Document* pDoc,
- const ByteString& name) {
- CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictFor("Dests");
+RetainPtr<const CPDF_Array> LookupOldStyleNamedDest(CPDF_Document* pDoc,
+ const ByteString& name) {
+ const CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictFor("Dests");
if (!pDests)
return nullptr;
- return GetNamedDestFromObject(pDests->GetDirectObjectFor(name));
+ // TODO(tsepez): return const retained objects from CPDF object getters.
+ return GetNamedDestFromObject(
+ pdfium::WrapRetain(pDests->GetDirectObjectFor(name)));
}
} // namespace
@@ -424,9 +426,10 @@ std::unique_ptr<CPDF_NameTree> CPDF_NameTree::CreateForTesting(
}
// static
-CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc,
- const ByteString& name) {
- CPDF_Array* dest_array = nullptr;
+RetainPtr<const CPDF_Array> CPDF_NameTree::LookupNamedDest(
+ CPDF_Document* pDoc,
+ const ByteString& name) {
+ RetainPtr<const CPDF_Array> dest_array;
std::unique_ptr<CPDF_NameTree> name_tree = Create(pDoc, "Dests");
if (name_tree)
dest_array = name_tree->LookupNewStyleNamedDest(name);
@@ -526,10 +529,12 @@ CPDF_Object* CPDF_NameTree::LookupValueAndName(size_t nIndex,
return result.value().value;
}
-CPDF_Object* CPDF_NameTree::LookupValue(const WideString& csName) const {
+RetainPtr<const CPDF_Object> CPDF_NameTree::LookupValue(
+ const WideString& csName) const {
return SearchNameNodeByName(m_pRoot, csName, nullptr, nullptr);
}
-CPDF_Array* CPDF_NameTree::LookupNewStyleNamedDest(const ByteString& sName) {
+RetainPtr<const CPDF_Array> CPDF_NameTree::LookupNewStyleNamedDest(
+ const ByteString& sName) {
return GetNamedDestFromObject(LookupValue(PDF_DecodeText(sName.raw_span())));
}
diff --git a/core/fpdfdoc/cpdf_nametree.h b/core/fpdfdoc/cpdf_nametree.h
index e27f5b13cd76052e1de533b94f85ae505aa56339..30371b42ac622b53b79e180789a491a917c3f263 100644
--- a/core/fpdfdoc/cpdf_nametree.h
+++ b/core/fpdfdoc/cpdf_nametree.h
@@ -38,14 +38,14 @@ class CPDF_NameTree {
static std::unique_ptr<CPDF_NameTree> CreateForTesting(
CPDF_Dictionary* pRoot);
- static CPDF_Array* LookupNamedDest(CPDF_Document* doc,
- const ByteString& name);
+ static RetainPtr<const CPDF_Array> LookupNamedDest(CPDF_Document* doc,
+ const ByteString& name);
bool AddValueAndName(RetainPtr<CPDF_Object> pObj, const WideString& name);
bool DeleteValueAndName(size_t nIndex);
CPDF_Object* LookupValueAndName(size_t nIndex, WideString* csName) const;
- CPDF_Object* LookupValue(const WideString& csName) const;
+ RetainPtr<const CPDF_Object> LookupValue(const WideString& csName) const;
size_t GetCount() const;
CPDF_Dictionary* GetRootForTesting() const { return m_pRoot.Get(); }
@@ -53,7 +53,7 @@ class CPDF_NameTree {
private:
explicit CPDF_NameTree(CPDF_Dictionary* pRoot);
- CPDF_Array* LookupNewStyleNamedDest(const ByteString& name);
+ RetainPtr<const CPDF_Array> LookupNewStyleNamedDest(const ByteString& name);
const RetainPtr<CPDF_Dictionary> m_pRoot;
};
diff --git a/core/fpdfdoc/cpdf_nametree_unittest.cpp b/core/fpdfdoc/cpdf_nametree_unittest.cpp
index 36617e74d438985b17a889043f2e5ac73836bb3a..e144033bfd66448e45267788d66e577ab366b964 100644
--- a/core/fpdfdoc/cpdf_nametree_unittest.cpp
+++ b/core/fpdfdoc/cpdf_nametree_unittest.cpp
@@ -120,7 +120,7 @@ TEST(cpdf_nametree, GetUnicodeNameWithBOM) {
EXPECT_STREQ(L"1", stored_name.c_str());
// Check that the correct value object can be obtained by looking up "1".
- const CPDF_Number* pNumber = ToNumber(name_tree->LookupValue(L"1"));
+ RetainPtr<const CPDF_Number> pNumber = ToNumber(name_tree->LookupValue(L"1"));
ASSERT_TRUE(pNumber);
EXPECT_EQ(100, pNumber->GetInteger());
}
@@ -140,7 +140,8 @@ TEST(cpdf_nametree, GetFromTreeWithLimitsArrayWith4Items) {
std::unique_ptr<CPDF_NameTree> name_tree =
CPDF_NameTree::CreateForTesting(pRootDict.Get());
- const CPDF_Number* pNumber = ToNumber(name_tree->LookupValue(L"9.txt"));
+ RetainPtr<const CPDF_Number> pNumber =
+ ToNumber(name_tree->LookupValue(L"9.txt"));
ASSERT_TRUE(pNumber);
EXPECT_EQ(999, pNumber->GetInteger());
CheckLimitsArray(pKid1, "1.txt", "9.txt");
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 161340b8a1b406987b62934d9ad6a67ec49d4bb5..b89efdd063d6c81a38536686965f7bdf8f4da244 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -1050,7 +1050,9 @@ FPDF_GetNamedDestByName(FPDF_DOCUMENT document, FPDF_BYTESTRING name) {
return nullptr;
ByteString dest_name(name);
- return FPDFDestFromCPDFArray(CPDF_NameTree::LookupNamedDest(pDoc, dest_name));
+ // TODO(tsepez): murky ownership, should caller get a reference?
+ return FPDFDestFromCPDFArray(
+ CPDF_NameTree::LookupNamedDest(pDoc, dest_name).Get());
}
#ifdef PDF_ENABLE_V8
diff --git a/fxjs/cjs_document.cpp b/fxjs/cjs_document.cpp
index a0bcf868157446cd664eab2717a1adff4e6155b5..991c3aa4a3a41cd58bf22b37626658750831691c 100644
--- a/fxjs/cjs_document.cpp
+++ b/fxjs/cjs_document.cpp
@@ -1395,12 +1395,13 @@ CJS_Result CJS_Document::gotoNamedDest(
return CJS_Result::Failure(JSMessage::kBadObjectError);
CPDF_Document* pDocument = m_pFormFillEnv->GetPDFDocument();
- CPDF_Array* dest_array = CPDF_NameTree::LookupNamedDest(
+ RetainPtr<const CPDF_Array> dest_array = CPDF_NameTree::LookupNamedDest(
pDocument, pRuntime->ToByteString(params[0]));
if (!dest_array)
return CJS_Result::Failure(JSMessage::kBadObjectError);
- CPDF_Dest dest(dest_array);
+ // TODO(tsepez): make CPDF_Dest constructor take retained argument.
+ CPDF_Dest dest(dest_array.Get());
const CPDF_Array* arrayObject = dest.GetArray();
std::vector<float> scrollPositionArray;
if (arrayObject) {
diff --git a/testing/resources/javascript/bug_1358075.in b/testing/resources/javascript/bug_1358075.in
new file mode 100644
index 0000000000000000000000000000000000000000..b503bf2d81eb3ca9adaa108c5075c04fa1c69f89
--- /dev/null
+++ b/testing/resources/javascript/bug_1358075.in
@@ -0,0 +1,39 @@
+{{header}}
+{{object 1 0}} <<
+ /Pages 1 0 R
+ /OpenAction 2 0 R
+ /Names <<
+ /Dests 3 0 R
+ >>
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Action
+ /S /JavaScript
+ /JS (
+ this.gotoNamedDest\("2"\);
+ app.alert\("completed"\);
+ )
+>>
+endobj
+{{object 3 0}} <<
+ /Kids 4 0 R
+>>
+endobj
+{{object 4 0}} [
+ (1)
+ (3)
+ <<
+ /Kids [
+ <<
+ /Limits 4 0 R
+ /Names [(2) []]
+ >>
+ ]
+ >>
+]
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/bug_1358075_expected.txt b/testing/resources/javascript/bug_1358075_expected.txt
new file mode 100644
index 0000000000000000000000000000000000000000..13d460b3b9aa905cec757ab821b980f379772565
--- /dev/null
+++ b/testing/resources/javascript/bug_1358075_expected.txt
@@ -0,0 +1 @@
+Alert: completed
diff --git a/xfa/fxfa/cxfa_ffdoc.cpp b/xfa/fxfa/cxfa_ffdoc.cpp
index 691248d2709508fc4aff096c80c535a2863bc851..5693d231122ed953c863f4a2333c5ee782bcd68e 100644
--- a/xfa/fxfa/cxfa_ffdoc.cpp
+++ b/xfa/fxfa/cxfa_ffdoc.cpp
@@ -279,7 +279,8 @@ RetainPtr<CFX_DIBitmap> CXFA_FFDoc::GetPDFNamedImage(WideStringView wsName,
if (count == 0)
return nullptr;
- CPDF_Object* pObject = name_tree->LookupValue(WideString(wsName));
+ RetainPtr<const CPDF_Object> pObject =
+ name_tree->LookupValue(WideString(wsName));
if (!pObject) {
for (size_t i = 0; i < count; ++i) {
WideString wsTemp;
@@ -291,11 +292,12 @@ RetainPtr<CFX_DIBitmap> CXFA_FFDoc::GetPDFNamedImage(WideStringView wsName,
}
}
- CPDF_Stream* pStream = ToStream(pObject);
+ RetainPtr<const CPDF_Stream> pStream = ToStream(pObject);
if (!pStream)
return nullptr;
- auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
+ // TODO(tsepez): make CPDF_StreamAcc constructor take retained argument.
+ auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream.Get());
pAcc->LoadAllDataFiltered();
auto pImageFileRead =

View File

@@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Thu, 8 Sep 2022 23:45:54 +0000
Subject: Avoid de-referencing end() in GetNextAvailContentHeight().
Add the same HasCurrentViewRecord() check as in other methods.
Bug: chromium:1355682
Change-Id: I466f386f037801daa82ead30239f34e025748748
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/96910
Reviewed-by: Lei Zhang <thestig@chromium.org>
Auto-Submit: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
(cherry picked from commit 0d76a139d7ffbbdfb0ef5f5e714597a25f9767c4)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/97738
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
index a8efdb7dfa740bd9f3e70aeadc3c8d4ccb12587f..295854f655807ce706cc76d4786ad3c57564736e 100644
--- a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
+++ b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
@@ -1551,6 +1551,8 @@ void CXFA_ViewLayoutProcessor::ProcessLastPageSet() {
}
bool CXFA_ViewLayoutProcessor::GetNextAvailContentHeight(float fChildHeight) {
+ if (!HasCurrentViewRecord())
+ return false;
CXFA_Node* pCurContentNode =
GetCurrentViewRecord()->pCurContentArea->GetFormNode();
if (!pCurContentNode)

View File

@@ -0,0 +1,127 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Thu, 8 Sep 2022 21:45:44 +0000
Subject: Enforce maximum legal object number during linearized parses.
- Watch for overflow of object numbers.
- Re-validate CPDF_Object pointer after notification in CPDF_FormField.
Bug: chromium:1358090
Change-Id: I1effd8f47277d177c804dd14b20b101e71780067
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/97130
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
(cherry picked from commit 81ab3354f79765438bad0e9d683adcfce96727fa)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/97733
Auto-Submit: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_hint_tables.cpp b/core/fpdfapi/parser/cpdf_hint_tables.cpp
index 3445e90c9f68bc2386272b4d72f72d90c10bf7ec..0f2632c6d4a5dd7e6cd18c7d2bdc370b68e5bcb9 100644
--- a/core/fpdfapi/parser/cpdf_hint_tables.cpp
+++ b/core/fpdfapi/parser/cpdf_hint_tables.cpp
@@ -13,6 +13,7 @@
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_linearized_header.h"
+#include "core/fpdfapi/parser/cpdf_parser.h"
#include "core/fpdfapi/parser/cpdf_read_validator.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
@@ -101,7 +102,7 @@ bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) {
// Item 1: The least number of objects in a page.
const uint32_t dwObjLeastNum = hStream->GetBits(32);
- if (!dwObjLeastNum)
+ if (!dwObjLeastNum || dwObjLeastNum >= CPDF_Parser::kMaxObjectNumber)
return false;
// Item 2: The location of the first page's page object.
@@ -164,7 +165,7 @@ bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) {
m_PageInfos[nFirstPageNum].set_start_obj_num(
m_pLinearized->GetFirstPageObjNum());
// The object number of remaining pages starts from 1.
- uint32_t dwStartObjNum = 1;
+ FX_SAFE_UINT32 dwStartObjNum = 1;
for (uint32_t i = 0; i < nPages; ++i) {
FX_SAFE_UINT32 safeDeltaObj = hStream->GetBits(dwDeltaObjectsBits);
safeDeltaObj += dwObjLeastNum;
@@ -173,8 +174,12 @@ bool CPDF_HintTables::ReadPageHintTable(CFX_BitStream* hStream) {
m_PageInfos[i].set_objects_count(safeDeltaObj.ValueOrDie());
if (i == nFirstPageNum)
continue;
- m_PageInfos[i].set_start_obj_num(dwStartObjNum);
+ m_PageInfos[i].set_start_obj_num(dwStartObjNum.ValueOrDie());
dwStartObjNum += m_PageInfos[i].objects_count();
+ if (!dwStartObjNum.IsValid() ||
+ dwStartObjNum.ValueOrDie() >= CPDF_Parser::kMaxObjectNumber) {
+ return false;
+ }
}
hStream->ByteAlign();
diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp
index e882098fa36058d5454475743a7e4f34186469b4..c27576e494568f66d82a7b77f81afc265ab2aea6 100644
--- a/core/fpdfdoc/cpdf_formfield.cpp
+++ b/core/fpdfdoc/cpdf_formfield.cpp
@@ -178,14 +178,15 @@ bool CPDF_FormField::ResetField() {
case kRichText:
case kFile:
default: {
- const CPDF_Object* pDV = GetDefaultValueObject();
WideString csDValue;
- if (pDV)
- csDValue = pDV->GetUnicodeText();
-
WideString csValue;
{
- // Limit the scope of |pV| because it may get invalidated below.
+ // Limit scope of |pDV| and |pV| because they may get invalidated
+ // during notification below.
+ const CPDF_Object* pDV = GetDefaultValueObject();
+ if (pDV)
+ csDValue = pDV->GetUnicodeText();
+
const CPDF_Object* pV = GetValueObject();
if (pV)
csValue = pV->GetUnicodeText();
@@ -195,21 +196,26 @@ bool CPDF_FormField::ResetField() {
if (!bHasRV && (csDValue == csValue))
return false;
- if (!NotifyBeforeValueChange(csDValue)) {
+ if (!NotifyBeforeValueChange(csDValue))
return false;
- }
- if (pDV) {
- RetainPtr<CPDF_Object> pClone = pDV->Clone();
- if (!pClone)
- return false;
-
- m_pDict->SetFor(pdfium::form_fields::kV, std::move(pClone));
- if (bHasRV) {
- m_pDict->SetFor("RV", pDV->Clone());
+
+ {
+ // Limit scope of |pDV| because it may get invalidated during
+ // notification below.
+ const CPDF_Object* pDV = GetDefaultValueObject();
+ if (pDV) {
+ RetainPtr<CPDF_Object> pClone = pDV->Clone();
+ if (!pClone)
+ return false;
+
+ m_pDict->SetFor(pdfium::form_fields::kV, std::move(pClone));
+ if (bHasRV) {
+ m_pDict->SetFor("RV", pDV->Clone());
+ }
+ } else {
+ m_pDict->RemoveFor(pdfium::form_fields::kV);
+ m_pDict->RemoveFor("RV");
}
- } else {
- m_pDict->RemoveFor(pdfium::form_fields::kV);
- m_pDict->RemoveFor("RV");
}
NotifyAfterValueChange();
break;

1
patches/skia/.patches Normal file
View File

@@ -0,0 +1 @@
cherry-pick-07a2ce61e31a.patch

View File

@@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Greg Daniel <egdaniel@google.com>
Date: Wed, 5 Oct 2022 15:28:56 -0400
Subject: Fix GrDirectContext::fClinetMappedBuffer access in abandoned
callbacks.
Bug: chromium:1364604
Change-Id: I1ca44cab1c762e7f94ac94be94991ec94a7497be
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/583963
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/587879
Auto-Submit: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/ganesh/GrDirectContext.cpp b/src/gpu/ganesh/GrDirectContext.cpp
index abec1a933ee2623aa18beb582966df30db8ec9fa..19f162083d506658394347046ada0de45908de81 100644
--- a/src/gpu/ganesh/GrDirectContext.cpp
+++ b/src/gpu/ganesh/GrDirectContext.cpp
@@ -142,9 +142,6 @@ void GrDirectContext::abandonContext() {
fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
- // Must be after GrResourceCache::abandonAll().
- fMappedBufferManager.reset();
-
if (fSmallPathAtlasMgr) {
fSmallPathAtlasMgr->reset();
}
diff --git a/src/gpu/ganesh/GrFinishCallbacks.cpp b/src/gpu/ganesh/GrFinishCallbacks.cpp
index 5519d2ca639d31f86e33ff0f617246b785fbc779..172f07d4de4554663140fdc2ad30ceab9bf449aa 100644
--- a/src/gpu/ganesh/GrFinishCallbacks.cpp
+++ b/src/gpu/ganesh/GrFinishCallbacks.cpp
@@ -35,10 +35,16 @@ void GrFinishCallbacks::check() {
void GrFinishCallbacks::callAll(bool doDelete) {
while (!fCallbacks.empty()) {
- fCallbacks.front().fCallback(fCallbacks.front().fContext);
+ // While we are processing a proc we need to make sure to remove it from
+ // the callback list before calling it. This is because the client could
+ // trigger a call (e.g. calling flushAndSubmit(/*sync=*/true)) that has
+ // us process the finished callbacks. We also must process deleting the
+ // fence before a client may abandon the context.
+ auto finishCallback = fCallbacks.front();
if (doDelete) {
- fGpu->deleteFence(fCallbacks.front().fFence);
+ fGpu->deleteFence(finishCallback.fFence);
}
fCallbacks.pop_front();
+ finishCallback.fCallback(finishCallback.fContext);
}
}

View File

@@ -1 +1,2 @@
utf-8_q_simplify_20the_20logic_20that_20converts_20the_20_1_20.patch
utf-8_q_m102-lts_20enhance_20defensive_20mode_20so_20that_20i.patch

View File

@@ -7,3 +7,10 @@ do_not_export_private_v8_symbols_on_windows.patch
fix_build_deprecated_attribute_for_older_msvc_versions.patch
fix_disable_implies_dcheck_for_node_stream_array_buffers.patch
revert_fix_cppgc_removed_deleted_cstors_in_cppheapcreateparams.patch
cherry-pick-3704cf78f471.patch
cherry-pick-2f6a2939514f.patch
cherry-pick-8b040cb69e96.patch
cherry-pick-194bcc127f21.patch
cherry-pick-ec236fef54b8.patch
cherry-pick-80ed4b917477.patch
cherry-pick-2ac0620a5bbb.patch

View File

@@ -0,0 +1,135 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tobias Tebbi <tebbi@chromium.org>
Date: Thu, 6 Oct 2022 13:43:19 +0200
Subject: Merged: [turbofan] validate more concurrent reads
Bug: chromium:1369871
(cherry picked from commit ebe5675360e4735589a92a8836303822da79a8f4)
Change-Id: I49243d2c604cb4635d0d49a572245f7469eabffa
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3952937
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.6@{#41}
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
diff --git a/src/compiler/compilation-dependencies.cc b/src/compiler/compilation-dependencies.cc
index 6f5514289b764667fb849ec70c8afe076de33dcb..62bd0f8c46d1e57812605d2425f76679183dc943 100644
--- a/src/compiler/compilation-dependencies.cc
+++ b/src/compiler/compilation-dependencies.cc
@@ -35,7 +35,8 @@ namespace compiler {
V(Protector) \
V(PrototypeProperty) \
V(StableMap) \
- V(Transition)
+ V(Transition) \
+ V(ObjectSlotValue)
CompilationDependencies::CompilationDependencies(JSHeapBroker* broker,
Zone* zone)
@@ -863,6 +864,42 @@ class ProtectorDependency final : public CompilationDependency {
const PropertyCellRef cell_;
};
+// Check that an object slot will not change during compilation.
+class ObjectSlotValueDependency final : public CompilationDependency {
+ public:
+ explicit ObjectSlotValueDependency(const HeapObjectRef& object, int offset,
+ const ObjectRef& value)
+ : CompilationDependency(kObjectSlotValue),
+ object_(object.object()),
+ offset_(offset),
+ value_(value.object()) {}
+
+ bool IsValid() const override {
+ PtrComprCageBase cage_base = GetPtrComprCageBase(*object_);
+ Object current_value =
+ offset_ == HeapObject::kMapOffset
+ ? object_->map()
+ : TaggedField<Object>::Relaxed_Load(cage_base, *object_, offset_);
+ return *value_ == current_value;
+ }
+ void Install(PendingDependencies* deps) const override {}
+
+ private:
+ size_t Hash() const override {
+ return base::hash_combine(object_.address(), offset_, value_.address());
+ }
+
+ bool Equals(const CompilationDependency* that) const override {
+ const ObjectSlotValueDependency* const zat = that->AsObjectSlotValue();
+ return object_->address() == zat->object_->address() &&
+ offset_ == zat->offset_ && value_.address() == zat->value_.address();
+ }
+
+ Handle<HeapObject> object_;
+ int offset_;
+ Handle<Object> value_;
+};
+
class ElementsKindDependency final : public CompilationDependency {
public:
ElementsKindDependency(const AllocationSiteRef& site, ElementsKind kind)
@@ -1110,6 +1147,12 @@ void CompilationDependencies::DependOnElementsKind(
}
}
+void CompilationDependencies::DependOnObjectSlotValue(
+ const HeapObjectRef& object, int offset, const ObjectRef& value) {
+ RecordDependency(
+ zone_->New<ObjectSlotValueDependency>(object, offset, value));
+}
+
void CompilationDependencies::DependOnOwnConstantElement(
const JSObjectRef& holder, uint32_t index, const ObjectRef& element) {
RecordDependency(
diff --git a/src/compiler/compilation-dependencies.h b/src/compiler/compilation-dependencies.h
index aa8ff7b82abd2b75d0f32b312f4625de29827bb5..c6a18c400fe7571af67aa45f7a4d2666e09d8de1 100644
--- a/src/compiler/compilation-dependencies.h
+++ b/src/compiler/compilation-dependencies.h
@@ -93,6 +93,10 @@ class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject {
// Record the assumption that {site}'s {ElementsKind} doesn't change.
void DependOnElementsKind(const AllocationSiteRef& site);
+ // Check that an object slot will not change during compilation.
+ void DependOnObjectSlotValue(const HeapObjectRef& object, int offset,
+ const ObjectRef& value);
+
void DependOnOwnConstantElement(const JSObjectRef& holder, uint32_t index,
const ObjectRef& element);
diff --git a/src/compiler/js-create-lowering.cc b/src/compiler/js-create-lowering.cc
index fab65507ea0566e27a6793532b5f471fd5104ea5..25a2ec03d2f4ac6834baf2de7132619ce73b8bcc 100644
--- a/src/compiler/js-create-lowering.cc
+++ b/src/compiler/js-create-lowering.cc
@@ -1677,6 +1677,10 @@ base::Optional<Node*> JSCreateLowering::TryAllocateFastLiteral(
// Now that we hold the migration lock, get the current map.
MapRef boilerplate_map = boilerplate.map();
+ // Protect against concurrent changes to the boilerplate object by checking
+ // for an identical value at the end of the compilation.
+ dependencies()->DependOnObjectSlotValue(boilerplate, HeapObject::kMapOffset,
+ boilerplate_map);
{
base::Optional<MapRef> current_boilerplate_map =
boilerplate.map_direct_read();
@@ -1841,10 +1845,18 @@ base::Optional<Node*> JSCreateLowering::TryAllocateFastLiteralElements(
boilerplate.elements(kRelaxedLoad);
if (!maybe_boilerplate_elements.has_value()) return {};
FixedArrayBaseRef boilerplate_elements = maybe_boilerplate_elements.value();
+ // Protect against concurrent changes to the boilerplate object by checking
+ // for an identical value at the end of the compilation.
+ dependencies()->DependOnObjectSlotValue(
+ boilerplate, JSObject::kElementsOffset, boilerplate_elements);
// Empty or copy-on-write elements just store a constant.
int const elements_length = boilerplate_elements.length();
MapRef elements_map = boilerplate_elements.map();
+ // Protect against concurrent changes to the boilerplate object by checking
+ // for an identical value at the end of the compilation.
+ dependencies()->DependOnObjectSlotValue(boilerplate_elements,
+ HeapObject::kMapOffset, elements_map);
if (boilerplate_elements.length() == 0 || elements_map.IsFixedCowArrayMap()) {
if (allocation == AllocationType::kOld &&
!boilerplate.IsElementsTenured(boilerplate_elements)) {

View File

@@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Thibaud Michaud <thibaudm@chromium.org>
Date: Wed, 26 Oct 2022 17:03:36 +0200
Subject: Merged: [wasm] Reload cached instance fields in catch handler
Bug: chromium:1377816
(cherry picked from commit f517e518af26b7eac23c9e328b463eb1e8ee3499)
Change-Id: I993bcff0389a1ba134e89e8ac5299d742ddd150c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3999134
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.6@{#47}
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
diff --git a/src/wasm/graph-builder-interface.cc b/src/wasm/graph-builder-interface.cc
index f2d776435dd8cff94eea9533a06f6023813a233b..24452564d8159fbaed1acec98c30832b1383c1d8 100644
--- a/src/wasm/graph-builder-interface.cc
+++ b/src/wasm/graph-builder-interface.cc
@@ -87,6 +87,7 @@ class WasmGraphBuildingInterface {
struct TryInfo : public ZoneObject {
SsaEnv* catch_env;
TFNode* exception = nullptr;
+ bool first_catch = true;
bool might_throw() const { return exception != nullptr; }
@@ -879,6 +880,10 @@ class WasmGraphBuildingInterface {
TFNode* exception = block->try_info->exception;
SetEnv(block->try_info->catch_env);
+ if (block->try_info->first_catch) {
+ LoadContextIntoSsa(ssa_env_);
+ block->try_info->first_catch = false;
+ }
TFNode* if_catch = nullptr;
TFNode* if_no_catch = nullptr;
@@ -956,6 +961,9 @@ class WasmGraphBuildingInterface {
}
SetEnv(block->try_info->catch_env);
+ if (block->try_info->first_catch) {
+ LoadContextIntoSsa(ssa_env_);
+ }
}
void AtomicOp(FullDecoder* decoder, WasmOpcode opcode,

View File

@@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tobias Tebbi <tebbi@chromium.org>
Date: Thu, 1 Sep 2022 15:35:33 +0200
Subject: Merged: [compiler] fix typing of [[DateValue]]
Bug: chromium:1356308
(cherry picked from commit ae329407989f1e4689baba7a7827863057d688a9)
Change-Id: I1e132e96325296d180488774ef183daa36dc22c7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3915224
Reviewed-by: Darius Mercadier <dmercadier@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.6@{#25}
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
diff --git a/src/compiler/type-cache.h b/src/compiler/type-cache.h
index 6442b6f6b0ee39bf1a820168e9dd924e81bc0cb3..a34d094edaa4cb7dd7ac692e4a11d7c890744d7c 100644
--- a/src/compiler/type-cache.h
+++ b/src/compiler/type-cache.h
@@ -131,9 +131,10 @@ class V8_EXPORT_PRIVATE TypeCache final {
Type const kStringLengthType = CreateRange(0.0, String::kMaxLength);
// A time value always contains a tagged number in the range
- // [-kMaxTimeInMs, kMaxTimeInMs].
- Type const kTimeValueType =
- CreateRange(-DateCache::kMaxTimeInMs, DateCache::kMaxTimeInMs);
+ // [-kMaxTimeInMs, kMaxTimeInMs] or -0.
+ Type const kTimeValueType = Type::Union(
+ CreateRange(-DateCache::kMaxTimeInMs, DateCache::kMaxTimeInMs),
+ Type::MinusZero(), zone());
// The JSDate::day property always contains a tagged number in the range
// [1, 31] or NaN.

View File

@@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dominik=20Inf=C3=BChr?= <dinfuehr@chromium.org>
Date: Thu, 8 Sep 2022 16:27:54 +0200
Subject: Merged: [heap] Fix aborting compaction with map space compaction
Revision: 3ec02e314cfca04e7457a60363af98b9c9957b16
BUG=chromium:1359294,v8:12578
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
R=mlippautz@chromium.org
Change-Id: I04093833a1bfef4269eb578fa5a002872015199e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3882977
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.4@{#43}
Cr-Branched-From: b1413ed7c71ababe05d590de4b5c4ed97b68693e-refs/heads/10.4.132@{#1}
Cr-Branched-From: 9d0a09368569234a1d1094975e2e92591922cd08-refs/heads/main@{#80972}
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index ef0b67ca2b62745e3d9102a8c73b5841d782e21b..1fef50f691e9dfd44b30cf27e6cdf389f5d89d45 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -1943,7 +1943,7 @@ class EvacuateRecordOnlyVisitor final : public HeapObjectVisitor {
// Instead of calling object.IterateBodyFast(cage_base(), &visitor) here
// we can shortcut and use the precomputed size value passed to the visitor.
DCHECK_EQ(object.SizeFromMap(map), size);
- object.IterateBodyFast(map, size, &visitor);
+ object.IterateFast(map, size, &visitor);
return true;
}

View File

@@ -0,0 +1,111 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maya Lekova <mslekova@chromium.org>
Date: Wed, 2 Nov 2022 11:02:24 +0100
Subject: Merged: [compiler] Fix mutable heap number object reference leak
(cherry picked from commit 64112122374c00a86771b4612d20ca5d88ad5bfb)
Bug: chromium:1380063
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Change-Id: Ifa1737af7fbc7e14d69a5080cbe0aabf7ef466fa
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4009978
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.6@{#51}
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc
index 191f50e9e10406f4320d539aeb78f3bec59e8482..ed68b117f21530b66e957654516c6b7208446780 100644
--- a/src/compiler/effect-control-linearizer.cc
+++ b/src/compiler/effect-control-linearizer.cc
@@ -5384,6 +5384,8 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
auto if_double = __ MakeDeferredLabel();
auto done = __ MakeLabel(MachineRepresentation::kTagged);
+ auto loaded_field = __ MakeLabel(MachineRepresentation::kTagged);
+ auto done_double = __ MakeLabel(MachineRepresentation::kFloat64);
// Check if field is a mutable double field.
__ GotoIfNot(__ IntPtrEqual(__ WordAnd(index, one), zero), &if_double);
@@ -5400,8 +5402,8 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
Node* offset =
__ IntAdd(__ WordShl(index, __ IntPtrConstant(kTaggedSizeLog2 - 1)),
__ IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag));
- Node* result = __ Load(MachineType::AnyTagged(), object, offset);
- __ Goto(&done, result);
+ Node* field = __ Load(MachineType::AnyTagged(), object, offset);
+ __ Goto(&loaded_field, field);
}
// The field is located in the properties backing store of {object}.
@@ -5415,8 +5417,8 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
__ IntPtrConstant(kTaggedSizeLog2 - 1)),
__ IntPtrConstant((FixedArray::kHeaderSize - kTaggedSize) -
kHeapObjectTag));
- Node* result = __ Load(MachineType::AnyTagged(), properties, offset);
- __ Goto(&done, result);
+ Node* field = __ Load(MachineType::AnyTagged(), properties, offset);
+ __ Goto(&loaded_field, field);
}
}
@@ -5424,9 +5426,6 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
// architectures, or a mutable HeapNumber.
__ Bind(&if_double);
{
- auto loaded_field = __ MakeLabel(MachineRepresentation::kTagged);
- auto done_double = __ MakeLabel(MachineRepresentation::kFloat64);
-
index = __ WordSar(index, one);
// Check if field is in-object or out-of-object.
@@ -5454,27 +5453,27 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
Node* field = __ Load(MachineType::AnyTagged(), properties, offset);
__ Goto(&loaded_field, field);
}
+ }
- __ Bind(&loaded_field);
- {
- Node* field = loaded_field.PhiAt(0);
- // We may have transitioned in-place away from double, so check that
- // this is a HeapNumber -- otherwise the load is fine and we don't need
- // to copy anything anyway.
- __ GotoIf(ObjectIsSmi(field), &done, field);
- Node* field_map = __ LoadField(AccessBuilder::ForMap(), field);
- __ GotoIfNot(__ TaggedEqual(field_map, __ HeapNumberMapConstant()), &done,
- field);
-
- Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), field);
- __ Goto(&done_double, value);
- }
+ __ Bind(&loaded_field);
+ {
+ Node* field = loaded_field.PhiAt(0);
+ // We may have transitioned in-place away from double, so check that
+ // this is a HeapNumber -- otherwise the load is fine and we don't need
+ // to copy anything anyway.
+ __ GotoIf(ObjectIsSmi(field), &done, field);
+ Node* field_map = __ LoadField(AccessBuilder::ForMap(), field);
+ __ GotoIfNot(__ TaggedEqual(field_map, __ HeapNumberMapConstant()), &done,
+ field);
- __ Bind(&done_double);
- {
- Node* result = AllocateHeapNumberWithValue(done_double.PhiAt(0));
- __ Goto(&done, result);
- }
+ Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), field);
+ __ Goto(&done_double, value);
+ }
+
+ __ Bind(&done_double);
+ {
+ Node* result = AllocateHeapNumberWithValue(done_double.PhiAt(0));
+ __ Goto(&done, result);
}
__ Bind(&done);

View File

@@ -0,0 +1,47 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jakob Kummerow <jkummerow@chromium.org>
Date: Fri, 23 Sep 2022 13:13:37 +0200
Subject: Fix a register reuse corner case
Fixed: chromium:1366399
(cherry picked from commit 6c214db445827707d65be08d177c9a4257a03a7b)
Change-Id: I72cf30cbd31a21acb44b524a194acfb89d8fecbc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3925795
Reviewed-by: Matthias Liedtke <mliedtke@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.6@{#29}
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc
index 34b51e37c650274ec89a1930c4a9d9443f9838a2..508a91ecb8aa068b942fe445e186267832378cef 100644
--- a/src/wasm/baseline/liftoff-compiler.cc
+++ b/src/wasm/baseline/liftoff-compiler.cc
@@ -1417,9 +1417,11 @@ class LiftoffCompiler {
__ MergeFullStackWith(c->label_state, *__ cache_state());
__ emit_jump(c->label.get());
}
- // Merge the else state into the end state.
+ // Merge the else state into the end state. Set this state as the current
+ // state first so helper functions know which registers are in use.
__ bind(c->else_state->label.get());
- __ MergeFullStackWith(c->label_state, c->else_state->state);
+ __ cache_state()->Steal(c->else_state->state);
+ __ MergeFullStackWith(c->label_state, *__ cache_state());
__ cache_state()->Steal(c->label_state);
} else if (c->reachable()) {
// No merge yet at the end of the if, but we need to create a merge for
@@ -1431,9 +1433,11 @@ class LiftoffCompiler {
c->stack_depth + c->num_exceptions);
__ MergeFullStackWith(c->label_state, *__ cache_state());
__ emit_jump(c->label.get());
- // Merge the else state into the end state.
+ // Merge the else state into the end state. Set this state as the current
+ // state first so helper functions know which registers are in use.
__ bind(c->else_state->label.get());
- __ MergeFullStackWith(c->label_state, c->else_state->state);
+ __ cache_state()->Steal(c->else_state->state);
+ __ MergeFullStackWith(c->label_state, *__ cache_state());
__ cache_state()->Steal(c->label_state);
} else {
// No merge needed, just continue with the else state.

View File

@@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tobias Tebbi <tebbi@chromium.org>
Date: Wed, 26 Oct 2022 11:19:59 +0200
Subject: Merged: [turbofan] do not optimize any stores for field type None
Fixed: chromium:1378239
(cherry picked from commit db83e72034c0d431ff2f73e3c4ae3130c0f3e4e1)
Change-Id: I061d5dfe6e4ee24e6d0e7df56e15fbe37752d51e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3982254
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.6@{#45}
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc
index 53cab92b8e72bbfcead07b94f68f0872b9379b53..6ad6a68092efc36591204f9aacde97a49b13812d 100644
--- a/src/compiler/access-info.cc
+++ b/src/compiler/access-info.cc
@@ -454,9 +454,15 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo(
map, descriptor, details_representation));
} else if (details_representation.IsHeapObject()) {
if (descriptors_field_type->IsNone()) {
- // Store is not safe if the field type was cleared.
- if (access_mode == AccessMode::kStore) {
- return Invalid();
+ switch (access_mode) {
+ case AccessMode::kStore:
+ case AccessMode::kStoreInLiteral:
+ case AccessMode::kDefine:
+ // Store is not safe if the field type was cleared.
+ return Invalid();
+ case AccessMode::kLoad:
+ case AccessMode::kHas:
+ break;
}
// The field type was cleared by the GC, so we don't know anything

View File

@@ -2,13 +2,14 @@ const fs = require('fs');
const path = require('path');
const utils = require('./lib/utils');
const branding = require('../shell/app/BRANDING.json');
if (process.platform !== 'darwin') {
console.log('Not checking symlinks on non-darwin platform');
process.exit(0);
}
const appPath = path.resolve(__dirname, '..', '..', 'out', utils.getOutDir(), 'Electron.app');
const appPath = path.resolve(__dirname, '..', '..', 'out', utils.getOutDir(), `${branding.product_name}.app`);
const visited = new Set();
const traverse = (p) => {
if (visited.has(p)) return;

17
script/create-api-json.js Normal file
View File

@@ -0,0 +1,17 @@
const { parseDocs } = require('@electron/docs-parser');
const fs = require('fs');
const path = require('path');
const { getElectronVersion } = require('./lib/get-version');
parseDocs({
baseDirectory: path.resolve(__dirname, '..'),
packageMode: 'single',
useReadme: false,
moduleVersion: getElectronVersion()
}).then((api) => {
return fs.promises.writeFile(path.resolve(__dirname, '..', 'electron-api.json'), JSON.stringify(api, null, 2));
}).catch((err) => {
console.error(err);
process.exit(1);
});

View File

@@ -3,8 +3,7 @@ const path = require('path');
const semver = require('semver');
const outputPath = process.argv[2];
const currentVersion = fs.readFileSync(path.resolve(__dirname, '../ELECTRON_VERSION'), 'utf8').trim();
const currentVersion = process.argv[3];
const parsed = semver.parse(currentVersion);
@@ -20,9 +19,11 @@ const {
} = parsed;
fs.writeFileSync(outputPath, JSON.stringify({
full_version: currentVersion,
major,
minor,
patch,
prerelease,
prerelease_number: prerelease ? parsed.prerelease[parsed.prerelease.length - 1] : '0',
has_prerelease: prerelease === '' ? 0 : 1
}, null, 2));

View File

@@ -1,4 +1,4 @@
const asar = require('asar');
const asar = require('@electron/asar');
const crypto = require('crypto');
const fs = require('fs');

View File

@@ -1,4 +1,4 @@
const asar = require('asar');
const asar = require('@electron/asar');
const assert = require('assert');
const fs = require('fs-extra');
const os = require('os');

22
script/lib/get-version.js Normal file
View File

@@ -0,0 +1,22 @@
const { spawnSync } = require('child_process');
const path = require('path');
module.exports.getElectronVersion = () => {
// Find the nearest tag to the current HEAD
// This is equivilant to our old logic of "use a value in package.json" for the following reasons
//
// 1. Whenever we updated the package.json we ALSO pushed a tag with the same version
// 2. Whenever we _reverted_ a bump all we actually did was push a commit that deleted the tag and changed the version number back
//
// The only difference in the "git describe" technique is that technically a commit can "change" it's version
// number if a tag is created / removed retroactively. i.e. the first time a commit is pushed it will be 1.2.3
// and after the tag is made rebuilding the same commit will result in it being 1.2.4
const output = spawnSync('git', ['describe', '--tags', '--abbrev=0'], {
cwd: path.resolve(__dirname, '..', '..')
});
if (output.status !== 0) {
console.error(output.stderr);
throw new Error('Failed to get current electron version');
}
return output.stdout.toString().trim().replace(/^v/g, '');
};

View File

@@ -15,7 +15,9 @@ except ImportError:
from urllib2 import urlopen
import zipfile
from lib.config import is_verbose_mode
# from lib.config import is_verbose_mode
def is_verbose_mode():
return False
ELECTRON_DIR = os.path.abspath(
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
@@ -149,11 +151,17 @@ def get_electron_branding():
with open(branding_file_path) as f:
return json.load(f)
cached_electron_version = None
def get_electron_version():
SOURCE_ROOT = os.path.abspath(os.path.join(__file__, '..', '..', '..'))
version_file = os.path.join(SOURCE_ROOT, 'ELECTRON_VERSION')
with open(version_file) as f:
return 'v' + f.read().strip()
global cached_electron_version
if cached_electron_version is None:
cached_electron_version = str.strip(execute([
'node',
'-p',
'require("./script/lib/get-version").getElectronVersion()'
], cwd=ELECTRON_DIR).decode())
return cached_electron_version
def store_artifact(prefix, key_prefix, files):
# Azure Storage

3
script/print-version.py Normal file
View File

@@ -0,0 +1,3 @@
from lib.util import get_electron_version
print(get_electron_version())

View File

@@ -6,6 +6,7 @@ const got = require('got');
const semver = require('semver');
const { getCurrentBranch, ELECTRON_DIR } = require('../lib/utils');
const { getElectronVersion } = require('../lib/get-version');
const rootPackageJson = require('../../package.json');
const { Octokit } = require('@octokit/rest');
@@ -34,7 +35,6 @@ const files = [
const jsonFields = [
'name',
'version',
'repository',
'description',
'license',
@@ -44,6 +44,9 @@ const jsonFields = [
let npmTag = '';
const currentElectronVersion = getElectronVersion();
const isNightlyElectronVersion = currentElectronVersion.includes('nightly');
new Promise((resolve, reject) => {
temp.mkdir('electron-npm', (err, dirPath) => {
if (err) {
@@ -68,6 +71,7 @@ new Promise((resolve, reject) => {
jsonFields.forEach((fieldName) => {
packageJson[fieldName] = rootPackageJson[fieldName];
});
packageJson.version = currentElectronVersion;
fs.writeFileSync(
path.join(tempDir, 'package.json'),
JSON.stringify(packageJson, null, 2)
@@ -75,27 +79,27 @@ new Promise((resolve, reject) => {
return octokit.repos.listReleases({
owner: 'electron',
repo: rootPackageJson.version.indexOf('nightly') > 0 ? 'nightlies' : 'electron'
repo: isNightlyElectronVersion ? 'nightlies' : 'electron'
});
})
.then((releases) => {
// download electron.d.ts from release
const release = releases.data.find(
(release) => release.tag_name === `v${rootPackageJson.version}`
(release) => release.tag_name === `v${currentElectronVersion}`
);
if (!release) {
throw new Error(`cannot find release with tag v${rootPackageJson.version}`);
throw new Error(`cannot find release with tag v${currentElectronVersion}`);
}
return release;
})
.then(async (release) => {
const tsdAsset = release.assets.find((asset) => asset.name === 'electron.d.ts');
if (!tsdAsset) {
throw new Error(`cannot find electron.d.ts from v${rootPackageJson.version} release assets`);
throw new Error(`cannot find electron.d.ts from v${currentElectronVersion} release assets`);
}
const typingsContent = await getAssetContents(
rootPackageJson.version.indexOf('nightly') > 0 ? 'nightlies' : 'electron',
isNightlyElectronVersion ? 'nightlies' : 'electron',
tsdAsset.id
);
@@ -106,11 +110,11 @@ new Promise((resolve, reject) => {
.then(async (release) => {
const checksumsAsset = release.assets.find((asset) => asset.name === 'SHASUMS256.txt');
if (!checksumsAsset) {
throw new Error(`cannot find SHASUMS256.txt from v${rootPackageJson.version} release assets`);
throw new Error(`cannot find SHASUMS256.txt from v${currentElectronVersion} release assets`);
}
const checksumsContent = await getAssetContents(
rootPackageJson.version.indexOf('nightly') > 0 ? 'nightlies' : 'electron',
isNightlyElectronVersion ? 'nightlies' : 'electron',
checksumsAsset.id
);
@@ -127,7 +131,7 @@ new Promise((resolve, reject) => {
.then(async (release) => {
const currentBranch = await getCurrentBranch();
if (release.tag_name.indexOf('nightly') > 0) {
if (isNightlyElectronVersion) {
// TODO(main-migration): Simplify once main branch is renamed.
if (currentBranch === 'master' || currentBranch === 'main') {
// Nightlies get published to their own module, so they should be tagged as latest
@@ -164,7 +168,7 @@ new Promise((resolve, reject) => {
.then(() => childProcess.execSync('npm pack', { cwd: tempDir }))
.then(() => {
// test that the package can install electron prebuilt from github release
const tarballPath = path.join(tempDir, `${rootPackageJson.name}-${rootPackageJson.version}.tgz`);
const tarballPath = path.join(tempDir, `${rootPackageJson.name}-${currentElectronVersion}.tgz`);
return new Promise((resolve, reject) => {
const result = childProcess.spawnSync('npm', ['install', tarballPath, '--force', '--silent'], {
env: Object.assign({}, process.env, { electron_config_cache: tempDir }),
@@ -190,7 +194,7 @@ new Promise((resolve, reject) => {
});
})
.then((tarballPath) => {
const existingVersionJSON = childProcess.execSync(`npm view electron@${rootPackageJson.version} --json`).toString('utf-8');
const existingVersionJSON = childProcess.execSync(`npx npm@7 view ${rootPackageJson.name}@${currentElectronVersion} --json`).toString('utf-8');
// It's possible this is a re-run and we already have published the package, if not we just publish like normal
if (!existingVersionJSON) {
childProcess.execSync(`npm publish ${tarballPath} --tag ${npmTag} --otp=${process.env.ELECTRON_NPM_OTP}`);
@@ -198,22 +202,21 @@ new Promise((resolve, reject) => {
})
.then(() => {
const currentTags = JSON.parse(childProcess.execSync('npm show electron dist-tags --json').toString());
const localVersion = rootPackageJson.version;
const parsedLocalVersion = semver.parse(localVersion);
const parsedLocalVersion = semver.parse(currentElectronVersion);
if (rootPackageJson.name === 'electron') {
// We should only customly add dist tags for non-nightly releases where the package name is still
// "electron"
if (parsedLocalVersion.prerelease.length === 0 &&
semver.gt(localVersion, currentTags.latest)) {
childProcess.execSync(`npm dist-tag add electron@${localVersion} latest --otp=${process.env.ELECTRON_NPM_OTP}`);
semver.gt(currentElectronVersion, currentTags.latest)) {
childProcess.execSync(`npm dist-tag add electron@${currentElectronVersion} latest --otp=${process.env.ELECTRON_NPM_OTP}`);
}
if (parsedLocalVersion.prerelease[0] === 'beta' &&
semver.gt(localVersion, currentTags.beta)) {
childProcess.execSync(`npm dist-tag add electron@${localVersion} beta --otp=${process.env.ELECTRON_NPM_OTP}`);
semver.gt(currentElectronVersion, currentTags.beta)) {
childProcess.execSync(`npm dist-tag add electron@${currentElectronVersion} beta --otp=${process.env.ELECTRON_NPM_OTP}`);
}
if (parsedLocalVersion.prerelease[0] === 'alpha' &&
semver.gt(localVersion, currentTags.alpha)) {
childProcess.execSync(`npm dist-tag add electron@${localVersion} alpha --otp=${process.env.ELECTRON_NPM_OTP}`);
semver.gt(currentElectronVersion, currentTags.alpha)) {
childProcess.execSync(`npm dist-tag add electron@${currentElectronVersion} alpha --otp=${process.env.ELECTRON_NPM_OTP}`);
}
}
})

View File

@@ -18,26 +18,6 @@ require('colors');
const pass = '✓'.green;
const fail = '✗'.red;
function getLastBumpCommit (tag) {
const data = execSync(`git log -n1 --grep "Bump ${tag}" --format='format:{"hash": "%H", "message": "%s"}'`).toString();
return JSON.parse(data);
}
async function revertBumpCommit (tag) {
const branch = await getCurrentBranch();
const commitToRevert = getLastBumpCommit(tag).hash;
await GitProcess.exec(['pull', '--rebase']);
await GitProcess.exec(['revert', commitToRevert], ELECTRON_DIR);
const pushDetails = await GitProcess.exec(['push', 'origin', `HEAD:${branch}`, '--follow-tags'], ELECTRON_DIR);
if (pushDetails.exitCode === 0) {
console.log(`${pass} successfully reverted release commit.`);
} else {
const error = GitProcess.parseError(pushDetails.stderr);
console.error(`${fail} could not push release commit: `, error);
process.exit(1);
}
}
async function deleteDraft (releaseId, targetRepo) {
try {
const result = await octokit.repos.getRelease({
@@ -80,9 +60,6 @@ async function cleanReleaseArtifacts () {
const releaseId = args.releaseID.length > 0 ? args.releaseID : null;
const isNightly = args.tag.includes('nightly');
// try to revert commit regardless of tag and draft deletion status
await revertBumpCommit(args.tag);
if (releaseId) {
if (isNightly) {
await deleteDraft(releaseId, 'nightlies');

View File

@@ -12,8 +12,6 @@ const args = require('minimist')(process.argv.slice(2), {
const fs = require('fs');
const { execSync } = require('child_process');
const got = require('got');
const pkg = require('../../package.json');
const pkgVersion = `v${pkg.version}`;
const path = require('path');
const temp = require('temp').track();
const { URL } = require('url');
@@ -25,8 +23,11 @@ const pass = '✓'.green;
const fail = '✗'.red;
const { ELECTRON_DIR } = require('../lib/utils');
const { getElectronVersion } = require('../lib/get-version');
const getUrlHash = require('./get-url-hash');
const pkgVersion = `v${getElectronVersion()}`;
const octokit = new Octokit({
auth: process.env.ELECTRON_GITHUB_TOKEN
});

View File

@@ -23,7 +23,7 @@ from lib.util import get_electron_branding, execute, get_electron_version, \
SRC_DIR, ELECTRON_DIR, TS_NODE
ELECTRON_VERSION = get_electron_version()
ELECTRON_VERSION = 'v' + get_electron_version()
PROJECT_NAME = get_electron_branding()['project_name']
PRODUCT_NAME = get_electron_branding()['product_name']

View File

@@ -1,17 +1,10 @@
#!/usr/bin/env node
const { GitProcess } = require('dugite');
const { promises: fs } = require('fs');
const semver = require('semver');
const path = require('path');
const minimist = require('minimist');
const { ELECTRON_DIR } = require('../lib/utils');
const { getElectronVersion } = require('../lib/get-version');
const versionUtils = require('./version-utils');
const supported = path.resolve(ELECTRON_DIR, 'docs', 'tutorial', 'support.md');
const writeFile = fs.writeFile;
const readFile = fs.readFile;
function parseCommandLine () {
let help;
@@ -37,7 +30,7 @@ function parseCommandLine () {
// run the script
async function main () {
const opts = parseCommandLine();
const currentVersion = await versionUtils.getElectronVersion();
const currentVersion = getElectronVersion();
const version = await nextVersion(opts.bump, currentVersion);
const parsed = semver.parse(version);
@@ -54,20 +47,6 @@ async function main () {
return 0;
}
if (shouldUpdateSupported(opts.bump, currentVersion, version)) {
await updateSupported(version, supported);
}
// update all version-related files
await Promise.all([
updateVersion(version),
updatePackageJSON(version),
updateWinRC(components)
]);
// commit all updated version-related files
await commitVersionBump(version);
console.log(`Bumped to version: ${version}`);
}
@@ -118,10 +97,6 @@ async function nextVersion (bumpType, version) {
return version;
}
function shouldUpdateSupported (bump, current, version) {
return isMajorStable(bump, current) || isMajorNightly(version, current);
}
function isMajorStable (bump, currentVersion) {
if (versionUtils.isBeta(currentVersion) && (bump === 'stable')) return true;
return false;
@@ -134,59 +109,6 @@ function isMajorNightly (version, currentVersion) {
return false;
}
// update VERSION file with latest release info
async function updateVersion (version) {
const versionPath = path.resolve(ELECTRON_DIR, 'ELECTRON_VERSION');
await writeFile(versionPath, version, 'utf8');
}
// update package metadata files with new version
async function updatePackageJSON (version) {
const filePath = path.resolve(ELECTRON_DIR, 'package.json');
const file = require(filePath);
file.version = version;
await writeFile(filePath, JSON.stringify(file, null, 2));
}
// push bump commit to release branch
async function commitVersionBump (version) {
const gitArgs = ['commit', '-a', '-m', `Bump v${version}`, '-n'];
await GitProcess.exec(gitArgs, ELECTRON_DIR);
}
// updates electron.rc file with new semver values
async function updateWinRC (components) {
const filePath = path.resolve(ELECTRON_DIR, 'shell', 'browser', 'resources', 'win', 'electron.rc');
const data = await readFile(filePath, 'utf8');
const arr = data.split('\n');
arr.forEach((line, idx) => {
if (line.includes('FILEVERSION')) {
arr[idx] = ` FILEVERSION ${versionUtils.makeVersion(components, ',', versionUtils.preType.PARTIAL)}`;
arr[idx + 1] = ` PRODUCTVERSION ${versionUtils.makeVersion(components, ',', versionUtils.preType.PARTIAL)}`;
} else if (line.includes('FileVersion')) {
arr[idx] = ` VALUE "FileVersion", "${versionUtils.makeVersion(components, '.')}"`;
arr[idx + 5] = ` VALUE "ProductVersion", "${versionUtils.makeVersion(components, '.')}"`;
}
});
await writeFile(filePath, arr.join('\n'));
}
// updates support.md file with new semver values (stable only)
async function updateSupported (version, filePath) {
const v = parseInt(version);
const newVersions = [`* ${v}.x.y`, `* ${v - 1}.x.y`, `* ${v - 2}.x.y`, `* ${v - 3}.x.y`];
const contents = await readFile(filePath, 'utf8');
const previousVersions = contents.split('\n').filter((elem) => {
return (/[^\n]*\.x\.y[^\n]*/).test(elem);
}, []);
const newContents = previousVersions.reduce((contents, current, i) => {
return contents.replace(current, newVersions[i]);
}, contents);
await writeFile(filePath, newContents, 'utf8');
}
if (process.mainModule === module) {
main().catch((error) => {
console.error(error);
@@ -194,4 +116,4 @@ if (process.mainModule === module) {
});
}
module.exports = { nextVersion, shouldUpdateSupported, updateSupported };
module.exports = { nextVersion };

View File

@@ -68,12 +68,6 @@ async function nextBeta (v) {
return tags.length === 0 ? `${next}-beta.1` : semver.inc(tags.pop(), 'prerelease');
}
async function getElectronVersion () {
const versionPath = path.resolve(ELECTRON_DIR, 'ELECTRON_VERSION');
const version = await readFile(versionPath, 'utf8');
return version.trim();
}
async function nextNightly (v) {
let next = semver.valid(semver.coerce(v));
const pre = `nightly.${getCurrentDate()}`;
@@ -114,7 +108,6 @@ module.exports = {
nextAlpha,
nextBeta,
makeVersion,
getElectronVersion,
nextNightly,
preType
};

View File

@@ -88,8 +88,11 @@ class DataPipeReader {
if (result == MOJO_RESULT_OK) { // success
remaining_size_ -= length;
head_ += length;
if (remaining_size_ == 0)
if (remaining_size_ == 0) {
OnSuccess();
} else {
handle_watcher_.ArmOrNotify();
}
} else if (result == MOJO_RESULT_SHOULD_WAIT) { // IO pending
handle_watcher_.ArmOrNotify();
} else { // error

View File

@@ -4,6 +4,7 @@
#include "shell/browser/api/electron_api_desktop_capturer.h"
#include <map>
#include <memory>
#include <utility>
#include <vector>
@@ -24,12 +25,125 @@
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
#if defined(USE_OZONE)
#include "ui/ozone/buildflags.h"
#if BUILDFLAG(OZONE_PLATFORM_X11)
#define USE_OZONE_PLATFORM_X11
#endif
#endif
#if BUILDFLAG(IS_WIN)
#include "third_party/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h"
#include "third_party/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h"
#include "ui/display/win/display_info.h"
#elif BUILDFLAG(IS_LINUX)
#if defined(USE_OZONE_PLATFORM_X11)
#include "base/logging.h"
#include "ui/base/x/x11_display_util.h"
#include "ui/base/x/x11_util.h"
#include "ui/display/util/edid_parser.h" // nogncheck
#include "ui/gfx/x/randr.h"
#include "ui/gfx/x/x11_atom_cache.h"
#include "ui/gfx/x/xproto_util.h"
#endif // defined(USE_OZONE_PLATFORM_X11)
#endif // BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_LINUX)
// Private function in ui/base/x/x11_display_util.cc
std::map<x11::RandR::Output, int> GetMonitors(int version,
x11::RandR* randr,
x11::Window window) {
std::map<x11::RandR::Output, int> output_to_monitor;
if (version >= 105) {
if (auto reply = randr->GetMonitors({window}).Sync()) {
for (size_t monitor = 0; monitor < reply->monitors.size(); monitor++) {
for (x11::RandR::Output output : reply->monitors[monitor].outputs)
output_to_monitor[output] = monitor;
}
}
}
return output_to_monitor;
}
// Get the EDID data from the |output| and stores to |edid|.
// Private function in ui/base/x/x11_display_util.cc
std::vector<uint8_t> GetEDIDProperty(x11::RandR* randr,
x11::RandR::Output output) {
constexpr const char kRandrEdidProperty[] = "EDID";
auto future = randr->GetOutputProperty(x11::RandR::GetOutputPropertyRequest{
.output = output,
.property = x11::GetAtom(kRandrEdidProperty),
.long_length = 128});
auto response = future.Sync();
std::vector<uint8_t> edid;
if (response && response->format == 8 && response->type != x11::Atom::None)
edid = std::move(response->data);
return edid;
}
// Find the mapping from monitor name atom to the display identifier
// that the screen API uses. Based on the logic in BuildDisplaysFromXRandRInfo
// in ui/base/x/x11_display_util.cc
std::map<int32_t, uint32_t> MonitorAtomIdToDisplayId() {
auto* connection = x11::Connection::Get();
auto& randr = connection->randr();
auto x_root_window = ui::GetX11RootWindow();
int version = ui::GetXrandrVersion();
std::map<int32_t, uint32_t> monitor_atom_to_display;
auto resources = randr.GetScreenResourcesCurrent({x_root_window}).Sync();
if (!resources) {
LOG(ERROR) << "XRandR returned no displays; don't know how to map ids";
return monitor_atom_to_display;
}
std::map<x11::RandR::Output, int> output_to_monitor =
GetMonitors(version, &randr, x_root_window);
auto monitors_reply = randr.GetMonitors({x_root_window}).Sync();
for (size_t i = 0; i < resources->outputs.size(); i++) {
x11::RandR::Output output_id = resources->outputs[i];
auto output_info =
randr.GetOutputInfo({output_id, resources->config_timestamp}).Sync();
if (!output_info)
continue;
if (output_info->connection != x11::RandR::RandRConnection::Connected)
continue;
if (output_info->crtc == static_cast<x11::RandR::Crtc>(0))
continue;
auto crtc =
randr.GetCrtcInfo({output_info->crtc, resources->config_timestamp})
.Sync();
if (!crtc)
continue;
display::EdidParser edid_parser(
GetEDIDProperty(&randr, static_cast<x11::RandR::Output>(output_id)));
auto output_32 = static_cast<uint32_t>(output_id);
int64_t display_id =
output_32 > 0xff ? 0 : edid_parser.GetIndexBasedDisplayId(output_32);
// It isn't ideal, but if we can't parse the EDID data, fall back on the
// display number.
if (!display_id)
display_id = i;
// Find the mapping between output identifier and the monitor name atom
// Note this isn't the atom string, but the numeric atom identifier,
// since this is what the WebRTC system uses as the display identifier
auto output_monitor_iter = output_to_monitor.find(output_id);
if (output_monitor_iter != output_to_monitor.end()) {
x11::Atom atom =
monitors_reply->monitors[output_monitor_iter->second].name;
monitor_atom_to_display[static_cast<int32_t>(atom)] = display_id;
}
}
return monitor_atom_to_display;
}
#endif
namespace gin {
template <>
@@ -181,10 +295,22 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
for (auto& source : screen_sources) {
source.display_id = base::NumberToString(source.media_list_source.id.id);
}
#elif BUILDFLAG(IS_LINUX)
#if defined(USE_OZONE_PLATFORM_X11)
// On Linux, with X11, the source id is the numeric value of the
// display name atom and the display id is either the EDID or the
// loop index when that display was found (see
// BuildDisplaysFromXRandRInfo in ui/base/x/x11_display_util.cc)
std::map<int32_t, uint32_t> monitor_atom_to_display_id =
MonitorAtomIdToDisplayId();
for (auto& source : screen_sources) {
auto display_id_iter =
monitor_atom_to_display_id.find(source.media_list_source.id.id);
if (display_id_iter != monitor_atom_to_display_id.end())
source.display_id = base::NumberToString(display_id_iter->second);
}
#endif // defined(USE_OZONE_PLATFORM_X11)
#endif // BUILDFLAG(IS_WIN)
// TODO(ajmacd): Add Linux support. The IDs across APIs differ but Chrome
// only supports capturing the entire desktop on Linux. Revisit this if
// individual screen support is added.
std::move(screen_sources.begin(), screen_sources.end(),
std::back_inserter(captured_sources_));
}

View File

@@ -175,4 +175,4 @@ bool Converter<ui::NativeTheme::ThemeSource>::FromV8(
} // namespace gin
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_common_native_theme, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_native_theme, Initialize)

View File

@@ -304,4 +304,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_common_notification, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_notification, Initialize)

View File

@@ -185,4 +185,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_common_screen, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_screen, Initialize)

View File

@@ -144,6 +144,10 @@
#include "shell/browser/osr/osr_web_contents_view.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "shell/browser/native_window_views.h"
#endif
#if !BUILDFLAG(IS_MAC)
#include "ui/aura/window.h"
#else
@@ -174,9 +178,8 @@
#if BUILDFLAG(IS_WIN)
#include "printing/backend/win_helper.h"
#include "shell/browser/native_window_views.h"
#endif
#endif
#endif // BUILDFLAG(ENABLE_PRINTING)
#if BUILDFLAG(ENABLE_PICTURE_IN_PICTURE)
#include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h"
@@ -1325,7 +1328,7 @@ void WebContents::EnterFullscreenModeForTab(
auto callback =
base::BindRepeating(&WebContents::OnEnterFullscreenModeForTab,
base::Unretained(this), requesting_frame, options);
permission_helper->RequestFullscreenPermission(callback);
permission_helper->RequestFullscreenPermission(requesting_frame, callback);
}
void WebContents::OnEnterFullscreenModeForTab(
@@ -1394,11 +1397,6 @@ bool WebContents::HandleContextMenu(content::RenderFrameHost& render_frame_host,
return true;
}
bool WebContents::OnGoToEntryOffset(int offset) {
GoToOffset(offset);
return false;
}
void WebContents::FindReply(content::WebContents* web_contents,
int request_id,
int number_of_matches,
@@ -2430,14 +2428,6 @@ void WebContents::OpenDevTools(gin::Arguments* args) {
!owner_window()) {
state = "detach";
}
bool activate = true;
if (args && args->Length() == 1) {
gin_helper::Dictionary options;
if (args->GetNext(&options)) {
options.Get("mode", &state);
options.Get("activate", &activate);
}
}
#if BUILDFLAG(IS_WIN)
auto* win = static_cast<NativeWindowViews*>(owner_window());
@@ -2447,6 +2437,15 @@ void WebContents::OpenDevTools(gin::Arguments* args) {
state = "detach";
#endif
bool activate = true;
if (args && args->Length() == 1) {
gin_helper::Dictionary options;
if (args->GetNext(&options)) {
options.Get("mode", &state);
options.Get("activate", &activate);
}
}
DCHECK(inspectable_web_contents_);
inspectable_web_contents_->SetDockState(state);
inspectable_web_contents_->ShowDevTools(activate);

View File

@@ -552,7 +552,6 @@ class WebContents : public ExclusiveAccessContext,
content::RenderWidgetHost* render_widget_host) override;
bool HandleContextMenu(content::RenderFrameHost& render_frame_host,
const content::ContextMenuParams& params) override;
bool OnGoToEntryOffset(int offset) override;
void FindReply(content::WebContents* web_contents,
int request_id,
int number_of_matches,

View File

@@ -291,6 +291,12 @@ GURL WebFrameMain::URL() const {
return render_frame_->GetLastCommittedURL();
}
std::string WebFrameMain::Origin() const {
if (!CheckRenderFrame())
return std::string();
return render_frame_->GetLastCommittedOrigin().Serialize();
}
blink::mojom::PageVisibilityState WebFrameMain::VisibilityState() const {
if (!CheckRenderFrame())
return blink::mojom::PageVisibilityState::kHidden;
@@ -380,6 +386,7 @@ v8::Local<v8::ObjectTemplate> WebFrameMain::FillObjectTemplate(
.SetProperty("processId", &WebFrameMain::ProcessID)
.SetProperty("routingId", &WebFrameMain::RoutingID)
.SetProperty("url", &WebFrameMain::URL)
.SetProperty("origin", &WebFrameMain::Origin)
.SetProperty("visibilityState", &WebFrameMain::VisibilityState)
.SetProperty("top", &WebFrameMain::Top)
.SetProperty("parent", &WebFrameMain::Parent)

Some files were not shown because too many files have changed in this diff Show More