Compare commits

..

101 Commits

Author SHA1 Message Date
Keeley Hammond
50f600b350 chore: cherry-pick d652130c4bc2 from chromium (#37171)
* chore: cherry-pick d652130c4bc2 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>
2023-02-08 15:26:58 +01:00
Samuel Attard
99b0c77cd7 build: empty commit 2023-02-08 01:52:25 -08:00
Keeley Hammond
bd191e1862 chore: cherry-pick e545559df538 from chromium (#37172)
* chore: cherry-pick e545559df538 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-02-07 22:43:44 -08:00
trop[bot]
79115938c6 ci: run WOA tests on AppVeyor (20-x-y) (#37076)
* ci: run WOA tests on AppVeyor

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

* ci: ensure correct ninja is used

Co-Authored-By: John Kleinschmidt <jkleinsc@electronjs.org>
(cherry picked from commit cfa67a099c)

* 3696127: win: Fix touch mode detection DCHECK in canary

https://chromium-review.googlesource.com/c/chromium/src/+/3696127

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-02-01 19:46:10 -05:00
Keeley Hammond
03193df4d3 chore: cherry-pick ca2b108a0f1f from chromium (#37058)
* chore: [20-x-y] cherry-pick ca2b108a0f1f from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-01-30 21:41:32 -08:00
trop[bot]
80d0d340c7 docs: add missing window-placement permission value to setPermissionRequestHandler() (#36904)
docs: add missing window-placement permission value to setPermissionRequestHandler() (#36777)

Co-authored-by: Milan Burda <miburda@microsoft.com>

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>
2023-01-17 16:24:40 -05:00
Pedro Pontes
2bf86bcf65 chore: [20-x-y] cherry-pick c79148742421 from v8 (#36581)
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-01-17 16:00:27 -05:00
Keeley Hammond
2946432147 ci: bake appveyor images automatically, run sync on depshash change (#36485)
* ci: bake appveyor images automatically, run sync on depshash change

* build: fixup appveyor image for release

* build: make sure symstore is in the PATH when baking an image

* build: update to use fixed baked image

* cleanup sdk install

* chore: instiall VSC++ tools on bake

* fix: pin Node to 16

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-01-12 14:27:49 -05:00
Pedro Pontes
9b552bfe98 chore: cherry-pick 43637378b14e from chromium (#36886)
* chore: cherry-pick 43637378b14e from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-01-12 13:14:45 +01:00
Pedro Pontes
aa2f4c094f chore: cherry-pick 0f481c9ddf2a from v8 (#36883)
* chore: cherry-pick 0f481c9ddf2a from v8

* 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>
2023-01-12 13:02:43 +01:00
Pedro Pontes
f680f21036 chore: cherry-pick 28b9c1c04e78 from v8 (#36880)
* chore: cherry-pick 28b9c1c04e78 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-01-11 17:30:38 -05:00
Pedro Pontes
4717ae4321 chore: cherry-pick 42e15c2055c4 from chromium (#36577)
* chore: [20-x-y] cherry-pick 42e15c2055c4 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-12-21 15:14:30 -08:00
Pedro Pontes
8c1af31b74 chore: cherry-pick 77208afba04d from chromium (#36682)
* chore: [20-x-y] cherry-pick 77208afba04d 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-12-21 13:36:29 -08:00
Pedro Pontes
4c27ab0a48 chore: cherry-pick 0d4862e31aca and c4e7fe2f2e1b from chromium (#36587)
* chore: [20-x-y] cherry-pick c4e7fe2f2e1b 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-12-20 12:09:42 -08:00
Pedro Pontes
b645d63b9b chore: cherry-pick 819d876e1bb8 from chromium (#36688) 2022-12-20 10:08:00 -08:00
Pedro Pontes
ebe47b445f chore: cherry-pick 176c526846cb from chromium (#36583)
chore: [20-x-y] cherry-pick 176c526846cb from chromium

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-12-19 13:28:13 -08:00
Pedro Pontes
4e881baaea chore: cherry-pick 65d46507a0c9 from chromium (#36585)
* chore: [20-x-y] cherry-pick 65d46507a0c9 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-12-19 13:27:49 -08:00
Pedro Pontes
c3d3f9a03b chore: cherry-pick 9b3d0e2f1aab from chromium (#36686)
* chore: cherry-pick 9b3d0e2f1aab from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-12-19 13:26:03 -08:00
Pedro Pontes
85565c0edd chore: cherry-pick eed5a4de2c40 from chromium (#36680)
* chore: [20-x-y] cherry-pick eed5a4de2c40 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-12-19 13:25:25 -08:00
Pedro Pontes
7644257bcd chore: cherry-pick fcf671adc2f3 from libaom (#36684) 2022-12-19 11:06:13 -08:00
Pedro Pontes
ec951270bd chore: cherry-pick d1d654d73222 from chromium (#36678) 2022-12-19 10:56:01 -08:00
Pedro Pontes
48159db088 chore: cherry-pick 136ef25acbf7 from webrtc (#36676) 2022-12-19 10:55:26 -08:00
Pedro Pontes
d1475648cb chore: cherry-pick 65ad70274d4b from chromium (#36579)
* chore: [20-x-y] cherry-pick 65ad70274d4b 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: Jeremy Rose <jeremya@chromium.org>
2022-12-14 16:09:25 -05:00
Pedro Pontes
1ce4472ae6 chore: cherry-pick f46db6aac3e9 from chromium (#36590)
* chore: cherry-pick f46db6aac3e9 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: Jeremy Rose <jeremya@chromium.org>
2022-12-14 13:04:52 -05:00
ad0p
d323392955 chore: cherry-pick 27fa951ae4a3 from v8 (#36552)
* chore: cherry-pick 27fa951ae4a3 from v8

* chore: cherry-pick 27fa951ae4a3 from v8

Co-authored-by: Adam Prasil <adamprasil@microsoft.com>
2022-12-13 14:32:44 -05:00
Pedro Pontes
5cfaf82036 chore: cherry-pick 2ef09109c0ec from chromium (#36592)
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2022-12-13 10:46:49 -08:00
Samuel Attard
56dedcc291 chore: cherry-pick 09ae62b from node (#36626)
Co-authored-by: VerteDinde <vertedinde@electronjs.org>
2022-12-13 10:40:00 -08:00
Pedro Pontes
02506a4cb1 chore: cherry-pick f98adc846aad from chromium (#36594)
* chore: cherry-pick f98adc846aad from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-12-09 03:26:25 -08:00
Milan Burda
8cbac3a861 build: fix building with enable_plugins = false (#36494)
build: fix building with enable_plugins = false (#36193)

Co-authored-by: Milan Burda <miburda@microsoft.com>
2022-11-30 16:15:45 -05:00
trop[bot]
9fa958cb5f build(deps): bump minimatch from 3.0.4 to 3.0.8 (#36470)
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.0.8.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.0.8)

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-29 12:05:35 -05:00
ad0p
cb26b3689b chore: cherry-pick 6b4af5d82083 from chromium (#36444)
Co-authored-by: Adam Prasil <adamprasil@microsoft.com>
2022-11-28 10:30:21 -08:00
trop[bot]
5456137421 chore: fix dangling promise in npm install (#36400)
* Fix dangling promise introduced in #33979

Co-authored-by: hyrious <hyrious@outlook.com>

* fix reject in callback

Co-authored-by: hyrious <hyrious@outlook.com>

* simplify code

Co-authored-by: Black-Hole <158blackhole@gmail.com>

Co-authored-by: hyrious <hyrious@outlook.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: hyrious <hyrious@outlook.com>
2022-11-21 14:54:34 +01:00
trop[bot]
9945746f1f chore: compile addons with --gnu++17 (#36382)
* chore: compile addons with --gnu++17

Co-authored-by: deepak1556 <hop2deep@gmail.com>

* chore: update patch

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-11-17 14:19:39 -05:00
Keeley Hammond
ec6df2b000 ci: use AppVeyor workflows (#36377)
* ci: use AppVeyor workflows (#35377)

* ci: use AppVeyor workflows

* fixup for skipping test on pr jobs

* chore: remove builtins-pgo (does not exist in 20)

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-11-17 10:44:27 -05:00
trop[bot]
e35ad40498 build: remove out cache (#36358)
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 20:05:09 -08:00
trop[bot]
c281f15bf6 build: make src cache smaller (#36353)
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 13:16:16 -05:00
Pedro Pontes
e86b4a6f99 chore: cherry-pick 81cb17c24788 from chromium (#36311)
* chore: cherry-pick 81cb17c24788 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-14 16:05:43 -05:00
Samuel Attard
f62120aa1b build: provide moduleVersion to docs-parser directly (#36339)
build: provide moduleVersion to docs-parser directly (#36329)
2022-11-14 21:53:23 +01:00
Pedro Pontes
b0bd900aa3 chore: cherry-pick 177e8bcd3584 from v8 (#36303)
* chore: cherry-pick 177e8bcd3584 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-14 00:16:46 -08:00
Pedro Pontes
a4f43aaa4d chore: cherry-pick 1894458e04a2 from chromium (#36302)
* chore: [20-x-y] cherry-pick 1894458e04a2 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-14 00:16:04 -08:00
Pedro Pontes
63b3434132 chore: cherry-pick 80ed4b917477 from v8 (#36300)
* chore: [20-x-y] cherry-pick 80ed4b917477 from v8

* 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 20:09:19 -05:00
Pedro Pontes
c881c3f21b chore: cherry-pick a1cbf05b4163 from chromium (#36298)
* chore: [20-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 20:03:14 -05:00
Pedro Pontes
5014520e2d chore: cherry-pick ac4785387fff from chromium (#36304)
* chore: cherry-pick ac4785387fff from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-10 12:16:06 -05:00
Pedro Pontes
8bde173814 chore: cherry-pick 2ac0620a5bbb from v8 (#36296)
* chore: [20-x-y] cherry-pick 2ac0620a5bbb from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-10 16:44:37 +01:00
Pedro Pontes
7841595cc6 revert: cherry-pick eef098d1c7d5 from webrtc (#36263)
Revert "chore: cherry-pick eef098d1c7d5 from webrtc (#36217)"

This reverts commit 92a338a273.
2022-11-09 15:20:42 -05:00
trop[bot]
870bf8c1f8 fix: app.dock.setIcon() crash before app ready (#36292)
fix: dock.setIcon() crash before app ready

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-11-09 15:02:02 -05:00
Pedro Pontes
e8b8ee1454 chore: cherry-pick d5ffb4dd4112 from chromium (#36214)
* chore: cherry-pick d5ffb4dd4112 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-03 12:26:44 -04:00
Pedro Pontes
b9d0a5aee3 chore: cherry-pick ec236fef54b8 from v8 (#36226)
* chore: [20-x-y] cherry-pick ec236fef54b8 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-03 11:40:13 -04:00
Pedro Pontes
bc3d0bf0c2 chore: cherry-pick 933cc81c6bad from chromium (#36223)
* 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>
2022-11-03 09:52:59 -04:00
Pedro Pontes
a0f608b8b6 chore: cherry-pick 06c87f9f42ff from chromium (#36208)
chore: [20-x-y] cherry-pick 06c87f9f42ff from chromium

Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2022-11-02 11:53:02 -04:00
Pedro Pontes
92a338a273 chore: cherry-pick eef098d1c7d5 from webrtc (#36217)
* chore: cherry-pick eef098d1c7d5 from webrtc

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-02 11:50:29 -04:00
Pedro Pontes
f8ab27474f chore: cherry-pick b8636b57b8f2 from angle (#36210)
chore: [20-x-y] cherry-pick b8636b57b8f2 from angle
2022-11-02 10:32:39 -04:00
Pedro Pontes
d844933377 chore: cherry-pick 194bcc127f21 from v8 (#36206)
* chore: [20-x-y] cherry-pick 194bcc127f21 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-02 10:05:48 -04:00
Pedro Pontes
30046ca08d chore: cherry-pick 67c9cbc784d6 from chromium (#36220) 2022-11-02 09:15:49 -04:00
George Xu
98ab127aa1 build: use python3 for appveyor commands (#36231) 2022-11-01 16:59:01 -07:00
trop[bot]
1008774610 docs: Fixed outdated documentation (uploading to App Store) (#36211)
* Updated docs on uploading

- replaced mention of Application Loader with Apple Transporter, its replacement
- replaced mention of iTunes Connect with App Store Connect
- updated link for creating a record

Co-authored-by: Georgescu Gabriel <29951139+gabi200@users.noreply.github.com>

* Update mac-app-store-submission-guide.md

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Georgescu Gabriel <29951139+gabi200@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2022-11-01 16:40:25 -07:00
trop[bot]
782e5adc99 build: fix building with enable_plugins = false (#36005)
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>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2022-11-01 11:17:30 -04:00
trop[bot]
806d0840ff fix: resolve loadURL properly for in-page navigations (#36149)
Co-authored-by: Jeremy Rose <jeremya@chromium.org>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-11-01 11:12:22 -04:00
Keeley Hammond
bdf6126133 build: determine electron version from tags not files (#36136)
* 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:37:45 -07:00
trop[bot]
378110b748 build: prefix version in uploader script (#36176)
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:48:21 -07:00
trop[bot]
117b264db5 test: fixup HID test for ARM CI (#36171)
(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:18:12 -04:00
trop[bot]
109009f3e7 refactor: handle uncaught promise error (#36157)
Co-authored-by: daief <1437931235@qq.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: daief <1437931235@qq.com>
2022-10-27 14:26:51 -04:00
trop[bot]
b2ca7f9c05 test: fix flake in will-navigate test (#36167)
Co-authored-by: Jeremy Rose <jeremya@chromium.org>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-10-27 14:03:46 -04:00
trop[bot]
5382df7ea2 docs: document that when invoke rejects, it gives a different Error (#36146)
Co-authored-by: Jeremy Rose <jeremya@chromium.org>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-10-26 17:28:30 -07:00
Pedro Pontes
aedfdadf1b chore: cherry-pick 65f0ef609c00 from chromium (#36079)
* chore: [20-x-y] cherry-pick 65f0ef609c00 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-10-26 17:29:30 -04:00
Pedro Pontes
7a70765ba1 chore: cherry-pick 07a2ce61e31a from skia (#36080)
* chore: cherry-pick 07a2ce61e31a from skia

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-10-26 17:17:26 -04:00
George Xu
a7ae2511d2 refactor: migrate from asar to @electron/asar (#36070) (#36083)
* refactor: migrate from asar to @electron/asar (#36070)

* refactor: migrate from asar to @electron/asar

* fix: update asar require calls

* kick ci

* kick ci

Co-authored-by: Samuel Attard <sam@electronjs.org>
2022-10-24 14:49:00 -07:00
trop[bot]
cf9f5ca5b8 test: disable flaky linux arm/arm64 crash test case (#36099)
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 15:06:55 -04:00
Pedro Pontes
2e85e7fd69 chore: cherry-pick d7feae867b83 from sqlite (#36085)
* chore: cherry-pick d7feae867b83 from sqlite

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-10-24 15:05:56 -04:00
Pedro Pontes
3028dcd785 chore: cherry-pick cb9dff93f3d4 from chromium (#36078)
* chore: [20-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:05:20 -04:00
Sudowoodo Release Bot
d010bcca86 Bump v20.3.3 2022-10-19 08:31:28 -07:00
trop[bot]
1ba8128c8c docs: update VS Code debugger types to remove "pwa-" prefix (#36052)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2022-10-17 14:18:39 -04:00
trop[bot]
25e504a7ed fix: override app's desktop name and v8 flags in default-app (#36048)
Co-authored-by: Piroro-hs <Piroro-hs@users.noreply.github.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Piroro-hs <Piroro-hs@users.noreply.github.com>
2022-10-17 14:12:49 +02:00
trop[bot]
589199f335 test: re-enable power monitor tests on arm64 (#36023)
test: re-enable powermonitor on arm64

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-15 01:24:14 -07:00
Sudowoodo Release Bot
c0371ab218 Bump v20.3.2 2022-10-12 08:32:04 -07:00
trop[bot]
50f2f10b94 fix: on-screen-keyboard hides on input blurred in webview (#35981)
* fix: on-screen-keyboard hides on input blurred in webview

Co-authored-by: Kyrylo Hrechykhin <khrechykhin@microsoft.com>

* chore: update patches

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Kyrylo Hrechykhin <khrechykhin@microsoft.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-10-12 10:36:53 -04:00
trop[bot]
2ee36539ba fix: drag and drop should copy on macOS (#35978)
fix: drag and drop should copy on macOS (#35963)

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-10-12 10:08:42 -04:00
trop[bot]
0d05ce8d12 docs: remove references to Widevine (#35991)
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-12 09:59:37 -04:00
Jeremy Rose
9e064fec80 chore: cherry-pick fefd6198da31 from chromium (#35883)
* chore: [20-x-y] cherry-pick fefd6198da31 from chromium

* chore: update patches

* Update cherry-pick-fefd6198da31.patch

* 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: Shelley Vohr <shelley.vohr@gmail.com>
2022-10-12 09:53:39 -04:00
trop[bot]
619a88cf56 fix: expose the built-in electron module via the ESM loader (#35956)
* fix: expose the built-in electron module via the ESM loader

Co-authored-by: Samuel Attard <sattard@salesforce.com>

* Update .patches

* chore: update patches

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@salesforce.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-10-11 16:06:42 -07:00
Milan Burda
080bc57145 fix: pass rfh instances through to the permission helper (#35985)
fix: pass rfh instances through to the permission helper (#35419)

Co-authored-by: Samuel Attard <sam@electronjs.org>
2022-10-11 16:05:41 -07:00
Raymond Zhao
a03ec151e1 chore: cherry-pick 30a32e6 from chromium (#35370) (#35968) 2022-10-11 15:45:51 +09:00
ad0p
0858a08097 chore: cherry-pick 05a0d99c9715 from chromium (#35929)
* chore: cherry-pick 05a0d99c9715 from chromium

* chore: cherry-pick 05a0d99c9715 from chromium

Co-authored-by: Adam Prasil <adamprasil@microsoft.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-10-10 16:49:07 +02:00
Samuel Attard
53b6270320 chore: cherry-pick c83640db21b5 from chromium (#35926)
* chore: cherry-pick c83640db21b5 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-10-06 04:27:10 -07:00
Samuel Attard
4c44e86fd1 build: fix filesystem permissions from bad trop commits
Ref: a7848809fc
Ref: c0c83d2719
2022-10-05 12:09:08 -07:00
Sudowoodo Release Bot
543a29c926 Bump v20.3.1 2022-10-05 08:32:16 -07:00
trop[bot]
c0c83d2719 docs: update supported Mac versions (#35912)
Co-authored-by: VerteDinde <vertedinde@electronjs.org>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: VerteDinde <vertedinde@electronjs.org>
2022-10-05 11:05:49 +02:00
trop[bot]
a7848809fc fix: TryCatch scope in node_bindings (#35897)
fix: TryCatch scope in node_bindings

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-10-04 11:04:41 -04:00
Jeremy Rose
d8ca287700 chore: cherry-pick 8b040cb69e96 from v8 (#35889)
* chore: [20-x-y] cherry-pick 8b040cb69e96 from v8

* 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-04 15:47:07 +02:00
Jeremy Rose
b0c881f608 chore: cherry-pick 1eb1e18ad41d from chromium (#35880)
* chore: [20-x-y] cherry-pick 1eb1e18ad41d from chromium

* chore: resolve patch conflicts

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
2022-10-03 23:49:47 -07:00
Jeremy Rose
6620ba4e15 chore: cherry-pick 2f6a2939514f from v8 (#35892)
* chore: [20-x-y] cherry-pick 2f6a2939514f from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-10-03 23:37:28 -07:00
trop[bot]
1babaec6da fix: set display_id in desktop capturer on Linux (#35834)
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-10-03 13:05:11 -07:00
Sudowoodo Release Bot
cbe1debbe2 Bump v20.3.0 2022-09-28 08:31:21 -07:00
trop[bot]
3c73ea5259 fix: Handle an electron.d.ts file in a custom build (#35823)
fix: Handle an electron.d.ts file in a custom build (#33979)

* Handle an electron.d.ts file in a custom build

* Fix linter issues

Co-authored-by: Felix Rieseberg <felixr@stripe.com>

Co-authored-by: Felix Rieseberg <felix@felixrieseberg.com>
Co-authored-by: Felix Rieseberg <felixr@stripe.com>
2022-09-26 17:41:28 -04:00
trop[bot]
02622b02a6 build: remove unused GitHub app config file (#35813)
chore: remove unused GitHub action config file

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2022-09-26 11:29:27 -04:00
trop[bot]
700906c1f1 fix: set macOS crypto keychain name earlier (#35796)
* fix: set macOS crypto keychain name earlier

* spec: ensure arm64 mac tests are cleaned up

Co-authored-by: Samuel Attard <sattard@salesforce.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2022-09-26 01:50:45 -07:00
trop[bot]
d19a0ac51b docs: add forge-overview.md (#35758)
docs: add forge-overview.md (#35473)

* docs: move forge-specific docs to electronforge.io

* docs: add reference to forge icon tutorial

* docs: add references to forge-overview.md

* docs: add recommended

* docs: update forge-overview

* docs: apply code review comments

Co-authored-by: Charles Kerr <charles@charleskerr.com>

Co-authored-by: George Xu <33054982+georgexu99@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2022-09-23 12:43:58 -07:00
trop[bot]
25521f6286 fix: allow docking DevTools with WCO (#35764)
fix: allow for docking devtools with WCO

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-09-23 11:48:08 -07:00
trop[bot]
f89b51fe0a docs: update the link for Introduction to Node.js (#35769)
Updated the link for Introduction to NodeJs

Co-authored-by: Aman Gupta <techbugaman@gmail.com>
2022-09-23 11:44:08 -07:00
trop[bot]
2a42cd2f65 docs: changed event.data to data under the message.port in docs (#35781)
* docs: changed event.data to data under the message.port in docs

* docs: corrected BrowserWindow wrong usage and change window.messagePort to window.electronMessagePort

Co-authored-by: cyrilchukwuebuka <muofunanya3@gmail.com>
2022-09-23 11:35:24 -07:00
trop[bot]
9e419bc4e9 feat: allow custom v8 snapshots to be used in the main process and the default snapshot in the renderer process (#35694)
feat: allow custom v8 snapshots to be used in the main process and the default snapshot in the renderer process (#35266)

* Updates to allow for using a custom v8 snapshot file name

* Allow using a custom v8 snapshot file name

* Fix up patch due to merge

* Use fuse to set up custom v8 snapshot file in browser process

* Refactor to use delegate instead of command line parameter

* Refactoring

* Update due to merge

* PR comments

* Rename patch

* Rename patch

chore: update patches

Co-authored-by: Ryan Manuel <ryanm@cypress.io>
2022-09-22 09:41:25 -07:00
144 changed files with 10795 additions and 1159 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-test-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"
@@ -235,6 +236,11 @@ step-depot-tools-get: &step-depot-tools-get
name: Get depot tools
command: |
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
cd depot_tools
git fetch --depth 1 origin b7d8efd8bee494f4cfacacc19cf50fc4d4be3900
git checkout b7d8efd8bee494f4cfacacc19cf50fc4d4be3900
touch .disable_auto_update
cd ..
if [ "`uname`" == "Darwin" ]; then
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
sed -i '' '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
@@ -454,7 +460,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
@@ -812,7 +818,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
@@ -872,12 +878,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
@@ -892,14 +898,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
@@ -917,13 +915,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
@@ -953,13 +944,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:
@@ -969,7 +963,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:
@@ -1293,9 +1287,6 @@ commands:
build:
type: boolean
default: true
use-out-cache:
type: boolean
default: true
restore-src-cache:
type: boolean
default: true
@@ -1418,10 +1409,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
@@ -1464,22 +1451,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
@@ -1633,7 +1604,6 @@ jobs:
persist: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-x64-testing-asan:
executor:
@@ -1650,7 +1620,6 @@ jobs:
- electron-build:
persist: true
checkout: true
use-out-cache: false
build-nonproprietary-ffmpeg: false
linux-x64-testing-no-run-as-node:
@@ -1667,7 +1636,6 @@ jobs:
- electron-build:
persist: false
checkout: true
use-out-cache: false
linux-x64-testing-gn-check:
executor:
@@ -1718,7 +1686,6 @@ jobs:
persist: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-arm-publish:
executor:
@@ -1761,7 +1728,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

@@ -1,178 +0,0 @@
name: Electron WOA Testing
on:
push:
branches: '**'
workflow_dispatch:
inputs:
appveyor_job_id:
description: 'Job Id of Appveyor WOA job to test'
type: text
required: true
jobs:
electron-woa-init:
if: ${{ github.event_name == 'push' && github.repository == 'electron/electron' }}
runs-on: ubuntu-latest
steps:
- name: Dummy step for push event
run: |
echo "This job is a needed initialization step for Electron WOA testing. Another test result will appear once the electron-woa-testing build is done."
electron-woa-testing:
if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'electron/electron' }}
runs-on: [self-hosted, woa]
permissions:
checks: write
pull-requests: write
steps:
- uses: LouisBrunner/checks-action@v1.1.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
name: electron-woa-testing
status: in_progress
details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
output: |
{"summary":"Test In Progress","text_description":"See job details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
- name: Clean Workspace
run: |
Remove-Item * -Recurse -Force
shell: powershell
- name: Checkout
uses: actions/checkout@v3
with:
path: src\electron
fetch-depth: 0
- name: Yarn install
run: |
cd src\electron
node script/yarn.js install --frozen-lockfile
- name: Download and extract dist.zip for test
run: |
$localArtifactPath = "$pwd\dist.zip"
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/dist.zip"
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\Default -y $localArtifactPath
shell: powershell
- name: Download and extract native test executables for test
run: |
$localArtifactPath = "src\out\Default\shell_browser_ui_unittests.exe"
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/shell_browser_ui_unittests.exe"
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
shell: powershell
- name: Download and extract ffmpeg.zip for test
run: |
$localArtifactPath = "$pwd\ffmpeg.zip"
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/ffmpeg.zip"
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\ffmpeg $localArtifactPath
shell: powershell
- name: Download node headers for test
run: |
$localArtifactPath = "src\node_headers.zip"
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/node_headers.zip"
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
cd src
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y node_headers.zip
shell: powershell
- name: Download electron.lib for test
run: |
$localArtifactPath = "src\out\Default\electron.lib"
$serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/electron.lib"
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
shell: powershell
# Uncomment the following block if pdb files are needed to debug issues
# - name: Download pdb files for detailed stacktraces
# if: ${{ github.event_name == 'workflow_dispatch' }}
# run: |
# try {
# $localArtifactPath = "src\pdb.zip"
# $serverArtifactPath = "https://ci.appveyor.com/api/buildjobs/${{ inputs.appveyor_job_id }}/artifacts/pdb.zip"
# Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer ${{ secrets.APPVEYOR_TOKEN }}" }
# cd src
# & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y pdb.zip
# } catch {
# Write-Host "There was an exception encountered while downloading pdb files:" $_.Exception.Message
# } finally {
# $global:LASTEXITCODE = 0
# }
# shell: powershell
- name: Setup node headers
run: |
New-Item src\out\Default\gen\node_headers\Release -Type directory
Copy-Item -path src\out\Default\electron.lib -destination src\out\Default\gen\node_headers\Release\node.lib
shell: powershell
- name: Run Electron Main process tests
run: |
cd src
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
set npm_config_arch=arm64
cd electron
node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion
env:
ELECTRON_ENABLE_STACK_DUMPING: true
ELECTRON_OUT_DIR: Default
IGNORE_YARN_INSTALL_ERROR: 1
ELECTRON_TEST_RESULTS_DIR: junit
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
MOCHA_REPORTER: mocha-multi-reporters
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
- name: Run Electron Remote based tests
if: ${{ success() || failure() }}
run: |
cd src
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
set npm_config_arch=arm64
cd electron
node script/yarn test --runners=remote --enable-logging --disable-features=CalculateNativeWinOcclusion
env:
ELECTRON_OUT_DIR: Default
IGNORE_YARN_INSTALL_ERROR: 1
ELECTRON_TEST_RESULTS_DIR: junit
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
MOCHA_REPORTER: mocha-multi-reporters
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
- name: Verify ffmpeg
run: |
cd src
echo "Verifying non proprietary ffmpeg"
python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
shell: cmd
- name: Kill processes left running from last test run
if: ${{ always() }}
run: |
Get-Process | Where Name -Like "electron*" | Stop-Process
Get-Process | Where Name -Like "msedge*" | Stop-Process
shell: powershell
- name: Delete user app data directories
if: ${{ always() }}
run: |
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore
shell: powershell
- uses: LouisBrunner/checks-action@v1.1.1
if: ${{ success() }}
with:
token: ${{ secrets.GITHUB_TOKEN }}
name: electron-woa-testing
conclusion: "${{ job.status }}"
details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
output: |
{"summary":"${{ job.status }}","text_description":"See job details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
- uses: LouisBrunner/checks-action@v1.1.1
if: ${{ success() }}
with:
token: ${{ secrets.GITHUB_TOKEN }}
name: electron-woa-testing
conclusion: "${{ job.status }}"
details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
output: |
{"summary":"Job Succeeded","text_description":"See job details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}
- uses: LouisBrunner/checks-action@v1.1.1
if: ${{ ! success() }}
with:
token: ${{ secrets.GITHUB_TOKEN }}
name: electron-woa-testing
conclusion: "${{ job.status }}"
details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
output: |
{"summary":"Job Failed","text_description":"See job details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}

View File

@@ -0,0 +1,62 @@
name: Update AppVeyor Image
# Run chron daily Mon-Fri
on:
schedule:
- cron: '0 8 * * 1-5' # runs 8:00 every business day (see https://crontab.guru)
permissions:
contents: write
pull-requests: write
jobs:
bake-appveyor-image:
name: Bake AppVeyor Image
permissions:
contents: write
pull-requests: write # to create a new PR with updated Appveyor images
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Yarn install
run: |
node script/yarn.js install --frozen-lockfile
- name: Set Repo for Commit
run: git config --global --add safe.directory $GITHUB_WORKSPACE
- name: Check AppVeyor Image
env:
APPVEYOR_TOKEN: ${{ secrets.APPVEYOR_TOKEN }}
run: |
node ./script/prepare-appveyor
if [ -f ./image_version.txt ]; then
echo "APPVEYOR_IMAGE_VERSION="$(cat image_version.txt)"" >> $GITHUB_ENV
rm image_version.txt
fi
- name: (Optionally) Update Appveyor Image
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
uses: mikefarah/yq@v4.27.2
with:
cmd: yq '.image = "${{ env.APPVEYOR_IMAGE_VERSION }}"' "appveyor.yml" > "appveyor2.yml"
- name: (Optionally) Generate Commit Diff
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
run: |
diff -w -B appveyor.yml appveyor2.yml > appveyor.diff || true
patch -f appveyor.yml < appveyor.diff
rm appveyor2.yml appveyor.diff
- name: (Optionally) Commit and Pull Request
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
uses: peter-evans/create-pull-request@v4
with:
token: ${{ secrets.ACTIONS_GITHUB_TOKEN }}
commit-message: 'build: update appveyor image to latest version'
committer: GitHub <noreply@github.com>
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
signoff: false
branch: bump-appveyor-image
delete-branch: true
title: 'build: update appveyor image to latest version'
body: |
This PR updates appveyor.yml to the latest baked image, ${{ env.APPVEYOR_IMAGE_VERSION }}.

View File

@@ -107,6 +107,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,
@@ -302,12 +310,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") {
@@ -319,6 +324,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"
@@ -403,9 +441,6 @@ source_set("electron_lib") {
"//media/mojo/mojom",
"//net:extras",
"//net:net_resources",
"//ppapi/host",
"//ppapi/proxy",
"//ppapi/shared_impl",
"//printing/buildflags",
"//services/device/public/cpp/geolocation",
"//services/device/public/cpp/hid",
@@ -616,8 +651,15 @@ source_set("electron_lib") {
}
if (enable_plugins) {
deps += [ "chromium_src:plugins" ]
deps += [
"chromium_src:plugins",
"//ppapi/host",
"//ppapi/proxy",
"//ppapi/shared_impl",
]
sources += [
"shell/renderer/electron_renderer_pepper_host_factory.cc",
"shell/renderer/electron_renderer_pepper_host_factory.h",
"shell/renderer/pepper_helper.cc",
"shell/renderer/pepper_helper.h",
]
@@ -750,7 +792,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" ]
@@ -1184,6 +1225,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",
@@ -1217,8 +1259,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",
]
@@ -1400,15 +1441,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 @@
20.2.0

View File

@@ -38,7 +38,7 @@ For more installation options and troubleshooting tips, see
Each Electron release provides binaries for macOS, Windows, and Linux.
* macOS (El Capitan and up): Electron provides 64-bit Intel and ARM binaries for macOS. Apple Silicon support was added in Electron 11.
* macOS (High Sierra and up): Electron provides 64-bit Intel and ARM binaries for macOS. Apple Silicon support was added in Electron 11.
* Windows (Windows 7 and up): Electron provides `ia32` (`x86`), `x64` (`amd64`), and `arm64` binaries for Windows. Windows on ARM support was added in Electron 5.0.8.
* Linux: The prebuilt binaries of Electron are built on Ubuntu 20.04. They have also been verified to work on:
* Ubuntu 14.04 and newer

52
appveyor-bake.yml Normal file
View File

@@ -0,0 +1,52 @@
# The config is used to bake appveyor images, not for running CI jobs.
# The config expects the following environment variables to be set:
# - "APPVEYOR_BAKE_IMAGE" e.g. 'electron-99.0.4767.0'. Name of the image to be baked.
# Typically named after the Chromium version on which the image is built.
# This can be set dynamically in the prepare-appveyor script.
version: 1.0.{build}
build_cloud: electronhq-16-core
image: Windows_Default_Appveyor
environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default
ELECTRON_ENABLE_STACK_DUMPING: 1
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
GOMA_FALLBACK_ON_AUTH_FAILURE: true
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
PYTHONIOENCODING: UTF-8
build_script:
- ps: Resize-Partition -DriveLetter C -Size (256GB) # ensure initial partition size
- ps: Get-Partition -DriveLetter C
- git config --global core.longpaths true
- cd ..
- mkdir src
- ps: git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- update_depot_tools.bat
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
- src\electron\script\setup-win-for-dev.bat
- >-
gclient config
--name "src\electron"
--unmanaged
%GCLIENT_EXTRA_ARGS%
"https://github.com/electron/electron"
- ps: cd src\electron
- ps: node script\generate-deps-hash.js
- ps: $depshash = Get-Content .\.depshash -Raw
- ps: Copy-Item -path .\.depshash -destination ..\.depshash
- ps: cd ..\..
- gclient sync --with_branch_heads --with_tags --nohooks
- ps: regsvr32 /s "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\DIA SDK\bin\amd64\msdia140.dll"
on_image_bake:
- ps: >-
echo "Baking image: $env:APPVEYOR_BAKE_IMAGE at dir $PWD"
- ps: Remove-Item -Recurse -Force $pwd\depot_tools
- ps: Remove-Item -Recurse -Force $pwd\src\electron
# Uncomment these lines to enable RDP
#on_finish:
# - ps: >-
# $env:APPVEYOR_RDP_PASSWORD = "electron"
# $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))

286
appveyor-woa.yml Normal file
View File

@@ -0,0 +1,286 @@
# NOTE IF CHANGING THIS FILE, ALSO APPLY THE CHANGE TO appveyor.yml
# IF APPLICABLE!!!!
#
#
# The config expects the following environment variables to be set:
# - "GN_CONFIG" Build type. One of {'testing', 'release'}.
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
# https://gn.googlesource.com/gn/+/master/docs/reference.md#target_cpu
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordingly
# if you pass a custom value for 'target_cpu'.
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
# - "NPM_CONFIG_ARCH" E.g. 'x86'. Is used to build native Node.js modules.
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "TARGET_ARCH" value.
# - "TARGET_ARCH" Choose from {'ia32', 'x64', 'arm', 'arm64', 'mips64el'}.
# Is used in some publishing scripts, but does NOT affect the Electron binary.
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "NPM_CONFIG_ARCH" value.
# - "UPLOAD_TO_STORAGE" Set it to '1' upload a release to the Azure bucket.
# Otherwise the release will be uploaded to the GitHub Releases.
# (The value is only checked if "ELECTRON_RELEASE" is defined.)
#
# The publishing scripts expect access tokens to be defined as env vars,
# but those are not covered here.
#
# AppVeyor docs on variables:
# https://www.appveyor.com/docs/environment-variables/
# https://www.appveyor.com/docs/build-configuration/#secure-variables
# https://www.appveyor.com/docs/build-configuration/#custom-environment-variables
version: 1.0.{build}
build_cloud: electronhq-16-core
image: e-106.0.5249.199
environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default
ELECTRON_ENABLE_STACK_DUMPING: 1
ELECTRON_ALSO_LOG_TO_STDERR: 1
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
GOMA_FALLBACK_ON_AUTH_FAILURE: true
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
PYTHONIOENCODING: UTF-8
matrix:
- job_name: Build Arm on X64 Windows
- job_name: Test On Windows On Arm Hardware
job_depends_on: Build Arm on X64 Windows
APPVEYOR_BUILD_WORKER_IMAGE: base-woa
APPVEYOR_BUILD_WORKER_CLOUD: electronhq-woa
clone_folder: C:\projects\src\electron
skip_branch_with_pr: true
# the first failed job cancels other jobs and fails entire build
matrix:
fast_finish: true
for:
- matrix:
only:
- job_name: Build Arm on X64 Windows
build_script:
- ps: |
node script/yarn.js install --frozen-lockfile
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
if ($LASTEXITCODE -eq 0) {
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
}
$global:LASTEXITCODE = 0
- cd ..
- ps: Write-Host "Building $env:GN_CONFIG build"
- git config --global core.longpaths true
- ps: >-
if (Test-Path -Path "$pwd\depot_tools") {
Remove-Item -Recurse -Force $pwd\depot_tools
}
- ps: >-
if (Test-Path -Path "$pwd\build-tools") {
Remove-Item -Recurse -Force $pwd\build-tools
}
- ps: |
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
cd depot_tools
git fetch --depth 1 origin b7d8efd8bee494f4cfacacc19cf50fc4d4be3900
git checkout b7d8efd8bee494f4cfacacc19cf50fc4d4be3900
New-Item -Name .disable_auto_update -ItemType File
bootstrap\win_tools.bat
cd ..
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (Test-Path -Path "$pwd\src\electron") {
Remove-Item -Recurse -Force $pwd\src\electron
}
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
}
- git clone https://github.com/electron/build-tools.git
- cd build-tools
- npm install
- mkdir third_party
- ps: >-
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
- cd ..\..
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
if ($goma_login -eq 'Login as Fermi Planck') {
Write-warning "Goma authentication is correct";
} else {
Write-warning "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token.";
$host.SetShouldExit(1)
}
}
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
- ps: >-
if ($env:GN_CONFIG -ne 'release') {
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
}
- gclient config --name "src\electron" --unmanaged %GCLIENT_EXTRA_ARGS% "https://github.com/electron/electron"
# Patches are applied in the image bake. Check depshash to see if patches have changed.
- ps: $env:RUN_GCLIENT_SYNC="false"
- ps: $depshash_baked = Get-Content .\src\.depshash -Raw
- ps: cd src\electron
- ps: node script\generate-deps-hash.js
- ps: $depshash = Get-Content .\.depshash -Raw
- ps: cd ..\..
- ps: >-
if ($depshash_baked -ne $depshash) {
$env:RUN_GCLIENT_SYNC="true"
}
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags ) else ( gclient runhooks )
- cd src
- ps: $env:PATH="$pwd\third_party\ninja;$env:PATH"
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
- gn check out/Default //electron:electron_lib
- gn check out/Default //electron:electron_app
- gn check out/Default //electron/shell/common/api:mojo
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
- ninja -C out/Default electron:electron_dist_zip
- ninja -C out/Default shell_browser_ui_unittests
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/default_mksnapshot_args
# Remove unused args from mksnapshot_args
- ps: >-
Get-Content out/Default/default_mksnapshot_args | Where-Object { -not $_.Contains('--turbo-profiling-input') -And -not $_.Contains('builtins-pgo') } | Set-Content out/Default/mksnapshot_args
- ninja -C out/Default electron:electron_mksnapshot_zip
- cd out\Default
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
- cd ..\..
- ninja -C out/Default electron:hunspell_dictionaries_zip
- ninja -C out/Default electron:electron_chromedriver_zip
- ninja -C out/Default third_party/electron_node:headers
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
- ps: >-
Get-CimInstance -Namespace root\cimv2 -Class Win32_product | Select vendor, description, @{l='install_location';e='InstallLocation'}, @{l='install_date';e='InstallDate'}, @{l='install_date_2';e='InstallDate2'}, caption, version, name, @{l='sku_number';e='SKUNumber'} | ConvertTo-Json | Out-File -Encoding utf8 -FilePath .\installed_software.json
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
- 7z a node_headers.zip out\Default\gen\node_headers
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
# Needed for msdia140.dll on 64-bit windows
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
ninja -C out/Default electron:electron_symbols
}
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
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
}
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
deploy_script:
- cd electron
- ps: >-
if (Test-Path Env:\ELECTRON_RELEASE) {
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
Write-Output "Uploading Electron release distribution to azure"
& python3 script\release\uploaders\upload.py --verbose --upload_to_storage
} else {
Write-Output "Uploading Electron release distribution to github releases"
& python3 script\release\uploaders\upload.py --verbose
}
}
on_finish:
# Uncomment this lines to enable RDP
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
- cd C:\projects\src
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
- if exist out\Default\shell_browser_ui_unittests.exe (appveyor-retry appveyor PushArtifact out\Default\shell_browser_ui_unittests.exe)
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
- ps: >-
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
appveyor-retry appveyor PushArtifact pdb.zip
}
- matrix:
only:
- job_name: Test On Windows On Arm Hardware
environment:
IGNORE_YARN_INSTALL_ERROR: 1
ELECTRON_TEST_RESULTS_DIR: junit
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
MOCHA_REPORTER: mocha-multi-reporters
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
build_script:
- ps: |
node script/yarn.js install --frozen-lockfile
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
if ($LASTEXITCODE -eq 0) {
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
}
$global:LASTEXITCODE = 0
- cd ..
- mkdir out\Default
- cd ..
- ps: |
# Download build artifacts
$apiUrl = 'https://ci.appveyor.com/api'
$build_info = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/builds/$env:APPVEYOR_BUILD_ID"
$artifacts_to_download = @('dist.zip','ffmpeg.zip','node_headers.zip','pdb.zip','electron.lib')
foreach ($job in $build_info.build.jobs) {
if ($job.name -eq "Build Arm on X64 Windows") {
$jobId = $job.jobId
foreach($artifact_name in $artifacts_to_download) {
if ($artifact_name -eq 'shell_browser_ui_unittests.exe' -Or $artifact_name -eq 'electron.lib') {
$outfile = "src\out\Default\$artifact_name"
} else {
$outfile = $artifact_name
}
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifact_name" -OutFile $outfile
}
}
}
- ps: |
$out_default_zips = @('dist.zip','pdb.zip')
foreach($zip_name in $out_default_zips) {
7z x -y -osrc\out\Default $zip_name
}
- ps: 7z x -y -osrc\out\ffmpeg ffmpeg.zip
- ps: 7z x -y -osrc node_headers.zip
test_script:
# Workaround for https://github.com/appveyor/ci/issues/2420
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
- ps: |
cd src
New-Item .\out\Default\gen\node_headers\Release -Type directory
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
- set npm_config_nodedir=%cd%\out\Default\gen\node_headers
- set npm_config_arch=arm64
- cd electron
# Explicitly set npm_config_arch because the .env doesn't persist
- ps: >-
if ($env:TARGET_ARCH -eq 'ia32') {
$env:npm_config_arch = "ia32"
}
- echo Running main test suite & node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion
- cd ..
- echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
on_finish:
# Uncomment these lines to enable RDP
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
- if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )

View File

@@ -1,9 +1,13 @@
# NOTE IF CHANGING THIS FILE, ALSO APPLY THE CHANGE TO appveyor-woa.yml
# IF APPLICABLE!!!!
#
#
# The config expects the following environment variables to be set:
# - "GN_CONFIG" Build type. One of {'testing', 'release'}.
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
# https://gn.googlesource.com/gn/+/master/docs/reference.md#target_cpu
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordningly
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordingly
# if you pass a custom value for 'target_cpu'.
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
# - "NPM_CONFIG_ARCH" E.g. 'x86'. Is used to build native Node.js modules.
@@ -12,7 +16,7 @@
# Is used in some publishing scripts, but does NOT affect the Electron binary.
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "NPM_CONFIG_ARCH" value.
# - "UPLOAD_TO_STORAGE" Set it to '1' upload a release to the Azure bucket.
# Otherwise the release will be uploaded to the Github Releases.
# Otherwise the release will be uploaded to the GitHub Releases.
# (The value is only checked if "ELECTRON_RELEASE" is defined.)
#
# The publishing scripts expect access tokens to be defined as env vars,
@@ -24,224 +28,258 @@
# https://www.appveyor.com/docs/build-configuration/#custom-environment-variables
version: 1.0.{build}
build_cloud: electron-16-core
image: vs2019bt-16.16.11
build_cloud: electronhq-16-core
image: e-104.0.5112.124-fix
environment:
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default
ELECTRON_ENABLE_STACK_DUMPING: 1
ELECTRON_ALSO_LOG_TO_STDERR: 1
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
GOMA_FALLBACK_ON_AUTH_FAILURE: true
build_script:
- ps: >-
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
} else {
node script/yarn.js install --frozen-lockfile
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
PYTHONIOENCODING: UTF-8
$result = node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
Write-Output $result
if ($result.ExitCode -eq 0) {
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
}
}
- echo "Building $env:GN_CONFIG build"
- git config --global core.longpaths true
- cd ..
- mkdir src
- update_depot_tools.bat
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
}
- git clone https://github.com/electron/build-tools.git
- cd build-tools
- npm install
- mkdir third_party
- ps: >-
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
- cd ..
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
if ($goma_login -eq 'Login as Fermi Planck') {
Write-warning "Goma authentication is correct";
} else {
Write-warning "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token.";
$host.SetShouldExit(1)
}
}
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
- ps: >-
if ($env:GN_CONFIG -ne 'release') {
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
}
- >-
gclient config
--name "src\electron"
--unmanaged
%GCLIENT_EXTRA_ARGS%
"https://github.com/electron/electron"
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
$env:RUN_GCLIENT_SYNC="true"
} else {
cd src\electron
node script\generate-deps-hash.js
$depshash = Get-Content .\.depshash -Raw
$zipfile = "Z:\$depshash.7z"
cd ..\..
if (Test-Path -Path $zipfile) {
# file exists, unzip and then gclient sync
7z x -y $zipfile -mmt=30 -aoa
if (-not (Test-Path -Path "src\buildtools")) {
# the zip file must be corrupt - resync
$env:RUN_GCLIENT_SYNC="true"
if ($env:TARGET_ARCH -ne 'ia32') {
# only save on x64/woa to avoid contention saving
$env:SAVE_GCLIENT_SRC="true"
matrix:
- job_name: Build
- job_name: Test
job_depends_on: Build
clone_folder: C:\projects\src\electron
skip_branch_with_pr: true
# the first failed job cancels other jobs and fails entire build
matrix:
fast_finish: true
for:
- matrix:
only:
- job_name: Build
build_script:
- ps: |
node script/yarn.js install --frozen-lockfile
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
if ($LASTEXITCODE -eq 0) {
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
}
$global:LASTEXITCODE = 0
- cd ..
- ps: Write-Host "Building $env:GN_CONFIG build"
- git config --global core.longpaths true
- ps: >-
if (Test-Path -Path "$pwd\depot_tools") {
Remove-Item -Recurse -Force $pwd\depot_tools
}
- ps: >-
if (Test-Path -Path "$pwd\build-tools") {
Remove-Item -Recurse -Force $pwd\build-tools
}
- ps: |
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
cd depot_tools
git fetch --depth 1 origin b7d8efd8bee494f4cfacacc19cf50fc4d4be3900
git checkout b7d8efd8bee494f4cfacacc19cf50fc4d4be3900
New-Item -Name .disable_auto_update -ItemType File
bootstrap\win_tools.bat
cd ..
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (Test-Path -Path "$pwd\src\electron") {
Remove-Item -Recurse -Force $pwd\src\electron
}
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
}
- git clone https://github.com/electron/build-tools.git
- cd build-tools
- npm install
- mkdir third_party
- ps: >-
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
- cd ..\..
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
if ($goma_login -eq 'Login as Fermi Planck') {
Write-warning "Goma authentication is correct";
} else {
Write-warning "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token.";
$host.SetShouldExit(1)
}
}
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
- ps: >-
if ($env:GN_CONFIG -ne 'release') {
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
}
- gclient config --name "src\electron" --unmanaged %GCLIENT_EXTRA_ARGS% "https://github.com/electron/electron"
# Patches are applied in the image bake. Check depshash to see if patches have changed.
- ps: $env:RUN_GCLIENT_SYNC="false"
- ps: $depshash_baked = Get-Content .\src\.depshash -Raw
- ps: cd src\electron
- ps: node script\generate-deps-hash.js
- ps: $depshash = Get-Content .\.depshash -Raw
- ps: cd ..\..
- ps: >-
if ($depshash_baked -ne $depshash) {
$env:RUN_GCLIENT_SYNC="true"
}
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags ) else ( gclient runhooks )
- cd src
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
- gn check out/Default //electron:electron_lib
- gn check out/Default //electron:electron_app
- gn check out/Default //electron/shell/common/api:mojo
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
- ninja -C out/Default electron:electron_dist_zip
- ninja -C out/Default shell_browser_ui_unittests
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/default_mksnapshot_args
# Remove unused args from mksnapshot_args
- ps: >-
Get-Content out/Default/default_mksnapshot_args | Where-Object { -not $_.Contains('--turbo-profiling-input') -And -not $_.Contains('builtins-pgo') } | Set-Content out/Default/mksnapshot_args
- ninja -C out/Default electron:electron_mksnapshot_zip
- cd out\Default
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
- cd ..\..
- ninja -C out/Default electron:hunspell_dictionaries_zip
- ninja -C out/Default electron:electron_chromedriver_zip
- ninja -C out/Default third_party/electron_node:headers
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
- ps: >-
Get-CimInstance -Namespace root\cimv2 -Class Win32_product | Select vendor, description, @{l='install_location';e='InstallLocation'}, @{l='install_date';e='InstallDate'}, @{l='install_date_2';e='InstallDate2'}, caption, version, name, @{l='sku_number';e='SKUNumber'} | ConvertTo-Json | Out-File -Encoding utf8 -FilePath .\installed_software.json
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
- 7z a node_headers.zip out\Default\gen\node_headers
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
# Needed for msdia140.dll on 64-bit windows
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
ninja -C out/Default electron:electron_symbols
}
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
python3 electron\script\zip-symbols.py
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
} else {
# update angle
cd src\third_party\angle
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
git fetch
cd ..\..\..
# It's useful to have pdb files when debugging testing builds that are
# built on CI.
7z a pdb.zip out\Default\*.pdb
}
} else {
# file does not exist, gclient sync, then zip
$env:RUN_GCLIENT_SYNC="true"
if ($env:TARGET_ARCH -ne 'ia32') {
# only save on x64/woa to avoid contention saving
$env:SAVE_GCLIENT_SRC="true"
}
}
}
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync )
- ps: >-
if ($env:SAVE_GCLIENT_SRC -eq 'true') {
# archive current source for future use
# only run on x64/woa to avoid contention saving
$(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30)
if ($LASTEXITCODE -ne 0) {
Write-warning "Could not save source to shared drive; continuing anyway"
}
# build time generation of file gen/angle/angle_commit.h depends on
# third_party/angle/.git
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
$(7z a $zipfile src\third_party\angle\.git)
if ($LASTEXITCODE -ne 0) {
Write-warning "Failed to add third_party\angle\.git; continuing anyway"
}
# build time generation of file dawn/common/Version_autogen.h depends on third_party/dawn/.git/HEAD
# https://dawn-review.googlesource.com/c/dawn/+/83901
$(7z a $zipfile src\third_party\dawn\.git)
if ($LASTEXITCODE -ne 0) {
Write-warning "Failed to add third_party\dawn\.git; continuing anyway"
}
}
- cd src
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
- gn check out/Default //electron:electron_lib
- gn check out/Default //electron:electron_app
- gn check out/Default //electron/shell/common/api:mojo
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
- ninja -C out/Default electron:electron_dist_zip
- ninja -C out/Default shell_browser_ui_unittests
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
- ninja -C out/Default electron:electron_mksnapshot_zip
- cd out\Default
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
- cd ..\..
- ninja -C out/Default electron:hunspell_dictionaries_zip
- ninja -C out/Default electron:electron_chromedriver_zip
- ninja -C out/Default third_party/electron_node:headers
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
- 7z a node_headers.zip out\Default\gen\node_headers
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
# Needed for msdia140.dll on 64-bit windows
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
ninja -C out/Default electron:electron_symbols
}
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
python 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
test_script:
# Workaround for https://github.com/appveyor/ci/issues/2420
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
- ps: >-
if ((-Not (Test-Path Env:\TEST_WOA)) -And (-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
$env:RUN_TESTS="true"
}
- ps: >-
if ($env:RUN_TESTS -eq 'true') {
New-Item .\out\Default\gen\node_headers\Release -Type directory
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
} else {
echo "Skipping tests for $env:GN_CONFIG build"
}
- cd electron
# CalculateNativeWinOcclusion is disabled due to https://bugs.chromium.org/p/chromium/issues/detail?id=1139022
- if "%RUN_TESTS%"=="true" ( echo Running main test suite & node script/yarn test -- --trace-uncaught --runners=main --enable-logging=file --log-file=%cd%\electron.log --disable-features=CalculateNativeWinOcclusion )
- 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 )
- 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% )
- echo "Done verifying mksnapshot"
- if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )
- echo "Done verifying chromedriver"
deploy_script:
- cd electron
- ps: >-
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
} else {
Write-Output "Uploading Electron release distribution to github releases"
& python 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
}
on_finish:
# Uncomment this lines to enable RDP
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
- cd ..
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
- if exist out\Default\shell_browser_ui_unittests.exe (appveyor-retry appveyor PushArtifact out\Default\shell_browser_ui_unittests.exe)
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
- ps: >-
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
appveyor-retry appveyor PushArtifact pdb.zip
}
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
- if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )
deploy_script:
- cd electron
- ps: >-
if (Test-Path Env:\ELECTRON_RELEASE) {
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
Write-Output "Uploading Electron release distribution to azure"
& python3 script\release\uploaders\upload.py --verbose --upload_to_storage
} else {
Write-Output "Uploading Electron release distribution to github releases"
& python3 script\release\uploaders\upload.py --verbose
}
}
on_finish:
# Uncomment this lines to enable RDP
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
- cd C:\projects\src
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
- if exist out\Default\shell_browser_ui_unittests.exe (appveyor-retry appveyor PushArtifact out\Default\shell_browser_ui_unittests.exe)
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
- ps: >-
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
appveyor-retry appveyor PushArtifact pdb.zip
}
- matrix:
only:
- job_name: Test
init:
- ps: |
if ($env:RUN_TESTS -ne 'true') {
Write-warning "Skipping tests for $env:APPVEYOR_PROJECT_NAME"; Exit-AppveyorBuild
}
build_script:
- ps: |
node script/yarn.js install --frozen-lockfile
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
if ($LASTEXITCODE -eq 0) {
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
}
$global:LASTEXITCODE = 0
- cd ..
- mkdir out\Default
- cd ..
- ps: |
# Download build artifacts
$apiUrl = 'https://ci.appveyor.com/api'
$build_info = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/builds/$env:APPVEYOR_BUILD_ID"
$artifacts_to_download = @('dist.zip','shell_browser_ui_unittests.exe','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib')
foreach ($job in $build_info.build.jobs) {
if ($job.name -eq "Build") {
$jobId = $job.jobId
foreach($artifact_name in $artifacts_to_download) {
if ($artifact_name -eq 'shell_browser_ui_unittests.exe' -Or $artifact_name -eq 'electron.lib') {
$outfile = "src\out\Default\$artifact_name"
} else {
$outfile = $artifact_name
}
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifact_name" -OutFile $outfile
}
}
}
- ps: |
$out_default_zips = @('dist.zip','chromedriver.zip','mksnapshot.zip')
foreach($zip_name in $out_default_zips) {
7z x -y -osrc\out\Default $zip_name
}
- ps: 7z x -y -osrc\out\ffmpeg ffmpeg.zip
- ps: 7z x -y -osrc node_headers.zip
test_script:
# Workaround for https://github.com/appveyor/ci/issues/2420
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
- ps: |
cd src
New-Item .\out\Default\gen\node_headers\Release -Type directory
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
- cd electron
# Explicitly set npm_config_arch because the .env doesn't persist
- ps: >-
if ($env:TARGET_ARCH -eq 'ia32') {
$env:npm_config_arch = "ia32"
}
- echo Running main test suite & node script/yarn test -- --trace-uncaught --runners=main --enable-logging=file --log-file=%cd%\electron.log
- echo Running native test suite & node script/yarn test -- --trace-uncaught --runners=native --enable-logging=file --log-file=%cd%\electron.log
- cd ..
- echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
- echo "About to verify mksnapshot"
- echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd%
- echo "Done verifying mksnapshot"
- echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd%
- echo "Done verifying chromedriver"
on_finish:
# Uncomment these lines to enable RDP
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
- if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )

View File

@@ -7,5 +7,6 @@
"node_options": "1",
"node_cli_inspect": "1",
"embedded_asar_integrity_validation": "0",
"only_load_app_from_asar": "0"
"only_load_app_from_asar": "0",
"load_browser_process_specific_v8_snapshot": "0"
}

View File

@@ -5,8 +5,6 @@ import sys
import os
import optparse
import json
import re
import subprocess
sys.path.append("%s/../../build" % os.path.dirname(os.path.realpath(__file__)))
@@ -36,56 +34,10 @@ def calculate_hash(root):
return CalculateHash('.', None)
def windows_installed_software():
powershell_command = [
"Get-CimInstance",
"-Namespace",
"root\cimv2",
"-Class",
"Win32_product",
"|",
"Select",
"vendor,",
"description,",
"@{l='install_location';e='InstallLocation'},",
"@{l='install_date';e='InstallDate'},",
"@{l='install_date_2';e='InstallDate2'},",
"caption,",
"version,",
"name,",
"@{l='sku_number';e='SKUNumber'}",
"|",
"ConvertTo-Json",
]
proc = subprocess.Popen(
["powershell.exe", "-Command", "-"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
stdout, _ = proc.communicate(" ".join(powershell_command).encode("utf-8"))
if proc.returncode != 0:
raise RuntimeError("Failed to get list of installed software")
# On AppVeyor there's other output related to PSReadline,
# so grab only the JSON output and ignore everything else
json_match = re.match(
r".*(\[.*{.*}.*\]).*", stdout.decode("utf-8"), re.DOTALL
)
if not json_match:
raise RuntimeError(
"Couldn't find JSON output for list of installed software"
)
# Filter out missing keys
return list(
map(
lambda info: {k: info[k] for k in info if info[k]},
json.loads(json_match.group(1)),
)
)
# file_path = os.path.join(os.getcwd(), 'installed_software.json')
# return json.loads(open('installed_software.json').read().decode('utf-8'))
f = open('installed_software.json', encoding='utf-8-sig')
return json.load(f)
def windows_profile():

View File

@@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 20,2,0,0
PRODUCTVERSION 20,2,0,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", "20.2.0"
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", "20.2.0"
VALUE "ProductVersion", "$major.$minor.$patch"
VALUE "SquirrelAwareVersion", "1"
END
END

View File

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

View File

@@ -6,6 +6,7 @@ import("//build/config/ozone.gni")
import("//build/config/ui.gni")
import("//components/spellcheck/spellcheck_build_features.gni")
import("//electron/buildflags/buildflags.gni")
import("//ppapi/buildflags/buildflags.gni")
import("//printing/buildflags/buildflags.gni")
import("//third_party/widevine/cdm/widevine.gni")
@@ -370,15 +371,20 @@ source_set("plugins") {
deps += [
"//components/strings",
"//media:media_buildflags",
"//ppapi/buildflags",
"//ppapi/host",
"//ppapi/proxy",
"//ppapi/proxy:ipc",
"//ppapi/shared_impl",
"//services/device/public/mojom",
"//skia",
"//storage/browser",
]
if (enable_plugins) {
deps += [
"//ppapi/buildflags",
"//ppapi/host",
"//ppapi/proxy",
"//ppapi/proxy:ipc",
"//ppapi/shared_impl",
]
}
}
# This source set is just so we don't have to depend on all of //chrome/browser

View File

@@ -83,7 +83,7 @@ function loadApplicationPackage (packagePath: string) {
});
try {
// Override app name and version.
// Override app's package.json data.
packagePath = path.resolve(packagePath);
const packageJsonPath = path.join(packagePath, 'package.json');
let appPath;
@@ -104,6 +104,16 @@ function loadApplicationPackage (packagePath: string) {
} else if (packageJson.name) {
app.name = packageJson.name;
}
if (packageJson.desktopName) {
app.setDesktopName(packageJson.desktopName);
} else {
app.setDesktopName(`${app.name}.desktop`);
}
// Set v8 flags, deliberately lazy load so that apps that do not use this
// feature do not pay the price
if (packageJson.v8Flags) {
require('v8').setFlagsFromString(packageJson.v8Flags);
}
appPath = packagePath;
}

View File

@@ -83,7 +83,6 @@ These individual tutorials expand on topics discussed in the guide above.
* Electron Releases & Developer Feedback
* [Versioning Policy](tutorial/electron-versioning.md)
* [Release Timelines](tutorial/electron-timelines.md)
* [Testing Widevine CDM](tutorial/testing-widevine-cdm.md)
---

View File

@@ -96,14 +96,6 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
throw an exception.
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
> special Electron objects will throw an exception.
>
> Since the main process does not have support for DOM objects such as
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
> Electron's IPC to the main process, as the main process would have no way to decode
> them. Attempting to send such objects over IPC will result in an error.
The main process should listen for `channel` with
[`ipcMain.handle()`](./ipc-main.md#ipcmainhandlechannel-listener).
@@ -126,6 +118,21 @@ If you need to transfer a [`MessagePort`][] to the main process, use [`ipcRender
If you do not need a response to the message, consider using [`ipcRenderer.send`](#ipcrenderersendchannel-args).
> **Note**
> Sending non-standard JavaScript types such as DOM objects or
> special Electron objects will throw an exception.
>
> Since the main process does not have support for DOM objects such as
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
> Electron's IPC to the main process, as the main process would have no way to decode
> them. Attempting to send such objects over IPC will result in an error.
> **Note**
> If the handler in the main process throws an error,
> the promise returned by `invoke` will reject.
> However, the `Error` object in the renderer process
> will not be the same as the one thrown in the main process.
### `ipcRenderer.sendSync(channel, ...args)`
* `channel` string

View File

@@ -635,9 +635,10 @@ 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.
* `window-placement` - Request access to enumerate screens using the [`getScreenDetails`](https://developer.chrome.com/en/articles/multi-screen-window-placement/) API.
* `unknown` - An unrecognized permission request
* `callback` Function
* `permissionGranted` boolean - Allow or deny the permission.

View File

@@ -11,8 +11,8 @@ can either use specialized tooling or manual approaches.
## With tooling
There are a couple tools out there that exist to package and distribute your Electron app.
We recommend using [Electron Forge](https://www.electronforge.io). You can check out
its documentation directly, or refer to the [Packaging and Distribution](./tutorial-5-packaging.md)
We recommend using [Electron Forge](./forge-overview.md). You can check out
its [documentation](https://www.electronforge.io) directly, or refer to the [Packaging and Distribution](./tutorial-5-packaging.md)
part of the Electron tutorial.
## Manual packaging

View File

@@ -26,10 +26,8 @@ beginners, using a command line tool is likely to be helpful*.
## electron-forge
A "complete tool for building modern Electron applications". Electron Forge
unifies the existing (and well maintained) build tools for Electron development
into a cohesive package so that anyone can jump right in to Electron
development.
Electron Forge is a tool for packaging and publishing Electron applications. It unifies Electron's tooling ecosystem
into a single extensible interface so that anyone can jump right into making Electron apps.
Forge comes with [a ready-to-use template](https://electronforge.io/templates) using Webpack as a bundler. It includes an example typescript configuration and provides two configuration files to enable easy customization. It uses the same core modules used by the
greater Electron community (like [`electron-packager`](https://github.com/electron/electron-packager))

View File

@@ -54,85 +54,11 @@ and notarized requires a few additions to your configuration. [Forge](https://el
collection of the official Electron tools, using [`electron-packager`],
[`electron-osx-sign`], and [`electron-notarize`] under the hood.
Let's take a look at an example `package.json` configuration with all required fields. Not all of them are
required: the tools will be clever enough to automatically find a suitable `identity`, for instance,
but we recommend that you are explicit.
```json title="package.json" {7}
{
"name": "my-app",
"version": "0.0.1",
"config": {
"forge": {
"packagerConfig": {
"osxSign": {
"identity": "Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)",
"hardened-runtime": true,
"entitlements": "entitlements.plist",
"entitlements-inherit": "entitlements.plist",
"signature-flags": "library"
},
"osxNotarize": {
"appleId": "felix@felix.fun",
"appleIdPassword": "my-apple-id-password"
}
}
}
}
}
```
The `entitlements.plist` file referenced here needs the following macOS-specific entitlements
to assure the Apple security mechanisms that your app is doing these things
without meaning any harm:
```xml title="entitlements.plist"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.debugger</key>
<true/>
</dict>
</plist>
```
Note that up until Electron 12, the `com.apple.security.cs.allow-unsigned-executable-memory` entitlement was required
as well. However, it should not be used anymore if it can be avoided.
To see all of this in action, check out Electron Fiddle's source code,
[especially its `electron-forge` configuration
file](https://github.com/electron/fiddle/blob/master/forge.config.js).
If you plan to access the microphone or camera within your app using Electron's APIs, you'll also
need to add the following entitlements:
```xml title="entitlements.plist"
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
```
If these are not present in your app's entitlements when you invoke, for example:
```js title="main.js"
const { systemPreferences } = require('electron')
const microphone = systemPreferences.askForMediaAccess('microphone')
```
Your app may crash. See the Resource Access section in [Hardened Runtime](https://developer.apple.com/documentation/security/hardened_runtime) for more information and entitlements you may need.
### Using Electron Builder
Electron Builder comes with a custom solution for signing your application. You
can find [its documentation here](https://www.electron.build/code-signing).
Detailed instructions on how to configure your application can be found in the [Electron Forge Code Signing Tutorial](https://www.electronforge.io/guides/code-signing/code-signing-macos).
### Using Electron Packager
If you're not using an integrated build pipeline like Forge or Builder, you
If you're not using an integrated build pipeline like Forge, you
are likely using [`electron-packager`], which includes [`electron-osx-sign`] and
[`electron-notarize`].
@@ -204,36 +130,7 @@ commit it to your source code.
### Using Electron Forge
Once you have a code signing certificate file (`.pfx`), you can sign
[Squirrel.Windows][maker-squirrel] and [MSI][maker-msi] installers in Electron Forge
with the `certificateFile` and `certificatePassword` fields in their respective
configuration objects.
For example, if you keep your Forge config in your `package.json` file and are
creating a Squirrel.Windows installer:
```json {9-15} title='package.json'
{
"name": "my-app",
"version": "0.0.1",
//...
"config": {
"forge": {
"packagerConfig": {},
"makers": [
{
"name": "@electron-forge/maker-squirrel",
"config": {
"certificateFile": "./cert.pfx",
"certificatePassword": "this-is-a-secret"
}
}
]
}
}
//...
}
```
Electron Forge is the recommended way to sign your `Squirrel.Windows` and `WiX MSI` installers. Detailed instructions on how to configure your application can be found in the [Electron Forge Code Signing Tutorial](https://www.electronforge.io/guides/code-signing/code-signing-macos).
### Using electron-winstaller (Squirrel.Windows)

View File

@@ -11,7 +11,7 @@ you can deliver it to your users.
## Packaging
To distribute your app with Electron, you need to package all your resources and assets
into an executable and rebrand it. To do this, you can either use specialized tooling
into an executable and rebrand it. To do this, you can either use specialized tooling like Electron Forge
or do it manually. See the [Application Packaging][application-packaging] tutorial
for more information.

View File

@@ -0,0 +1,36 @@
# Distributing Apps With Electron Forge
Electron Forge is a tool for packaging and publishing Electron applications.
It unifies Electron's build tooling ecosystem into
a single extensible interface so that anyone can jump right into making Electron apps.
## Getting started
The [Electron Forge docs] contain detailed information on taking your application
from source code to your end users' machines.
This includes:
* Packaging your application [(package)]
* Generating executables and installers for each OS [(make)], and,
* Publishing these files to online platforms to download [(publish)].
For beginners, we recommend following through Electron's [tutorial] to develop, build,
package and publish your first Electron app. If you have already developed an app on your machine
and want to start on packaging and distribution, start from [step 5] of the tutorial.
## Getting help
* If you need help with developing your app, our [community Discord server][discord] is a great place
to get advice from other Electron app developers.
* If you suspect you're running into a bug with Forge, please check the [GitHub issue tracker]
to see if any existing issues match your problem. If not, feel free to fill out our bug report
template and submit a new issue.
[Electron Forge Docs]: https://www.electronforge.io/
[step 5]: ./tutorial-5-packaging.md
[(package)]: https://www.electronforge.io/cli#package
[(make)]: https://www.electronforge.io/cli#make
[(publish)]: https://www.electronforge.io/cli#publish
[GitHub issue tracker]: https://github.com/electron-userland/electron-forge/issues
[discord]: https://discord.gg/APGC3k5yaH
[tutorial]: https://www.electronjs.org/docs/latest/tutorial/tutorial-prerequisites

View File

@@ -54,6 +54,13 @@ For more information on how to use asar integrity validation please read the [As
The onlyLoadAppFromAsar fuse changes the search system that Electron uses to locate your app code. By default Electron will search in the following order `app.asar` -> `app` -> `default_app.asar`. When this fuse is enabled the search order becomes a single entry `app.asar` thus ensuring that when combined with the `embeddedAsarIntegrityValidation` fuse it is impossible to load non-validated code.
### `loadBrowserProcessSpecificV8Snapshot`
**Default:** Disabled
**@electron/fuses:** `FuseV1Options.LoadBrowserProcessSpecificV8Snapshot`
The loadBrowserProcessSpecificV8Snapshot fuse changes which V8 snapshot file is used for the browser process. By default Electron's processes will all use the same V8 snapshot file. When this fuse is enabled the browser process uses the file called `browser_v8_context_snapshot.bin` for its V8 snapshot. The other processes will use the V8 snapshot file that they normally do.
## How do I flip the fuses?
### The easy way

View File

@@ -232,7 +232,7 @@ how to meet the Mac App Store requirements.
### Upload
The Application Loader should be used to upload the signed app to iTunes
[Apple Transporter][apple-transporter] should be used to upload the signed app to App Store
Connect for processing, making sure you have [created a record][create-record]
before uploading.
@@ -345,7 +345,8 @@ Electron uses following cryptographic algorithms:
[app-sandboxing]: https://developer.apple.com/app-sandboxing/
[app-notarization]: https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution
[submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html
[create-record]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/CreatingiTunesConnectRecord.html
[create-record]: https://help.apple.com/app-store-connect/#/dev2cd126805
[apple-transporter]: https://help.apple.com/itc/transporteruserguide/en.lproj/static.html
[submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html
[export-compliance]: https://help.apple.com/app-store-connect/#/devc3f64248f
[user-selected]: https://developer.apple.com/library/mac/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW6

View File

@@ -101,7 +101,7 @@ app.whenReady().then(async () => {
}
})
const secondaryWindow = BrowserWindow({
const secondaryWindow = new BrowserWindow({
show: false,
webPreferences: {
contextIsolation: false,
@@ -144,7 +144,7 @@ to use `contextIsolation` and set up specific contextBridge calls for each of yo
expected messages, but for the simplicity of this example we don't. You can find an
example of context isolation further down this page at [Communicating directly between the main process and the main world of a context-isolated page](#communicating-directly-between-the-main-process-and-the-main-world-of-a-context-isolated-page)
That means window.messagePort is globally available and you can call
That means window.electronMessagePort is globally available and you can call
`postMessage` on it from anywhere in your app to send a message to the other
renderer.
@@ -272,7 +272,7 @@ const makeStreamingRequest = (element, callback) => {
}
makeStreamingRequest(42, (data) => {
console.log('got response data:', event.data)
console.log('got response data:', data)
})
// We will see "got response data: 42" 10 times.
```

View File

@@ -1,95 +0,0 @@
# Testing Widevine CDM
In Electron you can use the Widevine CDM library shipped with Chrome browser.
Widevine Content Decryption Modules (CDMs) are how streaming services protect
content using HTML5 video to web browsers without relying on an NPAPI plugin
like Flash or Silverlight. Widevine support is an alternative solution for
streaming services that currently rely on Silverlight for playback of
DRM-protected video content. It will allow websites to show DRM-protected video
content in Firefox without the use of NPAPI plugins. The Widevine CDM runs in an
open-source CDM sandbox providing better user security than NPAPI plugins.
#### Note on VMP
As of [`Electron v1.8.0 (Chrome v59)`](https://electronjs.org/releases#1.8.1),
the below steps are may only be some of the necessary steps to enable Widevine;
any app on or after that version intending to use the Widevine CDM may need to
be signed using a license obtained from [Widevine](https://www.widevine.com/)
itself.
Per [Widevine](https://www.widevine.com/):
> Chrome 59 (and later) includes support for Verified Media Path (VMP). VMP
> provides a method to verify the authenticity of a device platform. For browser
> deployments, this will provide an additional signal to determine if a
> browser-based implementation is reliable and secure.
>
> The proxy integration guide has been updated with information about VMP and
> how to issue licenses.
>
> Widevine recommends our browser-based integrations (vendors and browser-based
> applications) add support for VMP.
To enable video playback with this new restriction,
[castLabs](https://castlabs.com/open-source/downstream/) has created a
[fork](https://github.com/castlabs/electron-releases) that has implemented the
necessary changes to enable Widevine to be played in an Electron application if
one has obtained the necessary licenses from widevine.
## Getting the library
Open `chrome://components/` in Chrome browser, find `Widevine Content Decryption Module`
and make sure it is up to date, then you can find the library files from the
application directory.
### On Windows
The library file `widevinecdm.dll` will be under
`Program Files(x86)/Google/Chrome/Application/CHROME_VERSION/WidevineCdm/_platform_specific/win_(x86|x64)/`
directory.
### On macOS
The library file `libwidevinecdm.dylib` will be under
`/Applications/Google Chrome.app/Contents/Versions/CHROME_VERSION/Google Chrome Framework.framework/Versions/A/Libraries/WidevineCdm/_platform_specific/mac_(x86|x64)/`
directory.
**Note:** Make sure that chrome version used by Electron is greater than or
equal to the `min_chrome_version` value of Chrome's widevine cdm component.
The value can be found in `manifest.json` under `WidevineCdm` directory.
## Using the library
After getting the library files, you should pass the path to the file
with `--widevine-cdm-path` command line switch, and the library's version
with `--widevine-cdm-version` switch. The command line switches have to be
passed before the `ready` event of `app` module gets emitted.
Example code:
```javascript
const { app, BrowserWindow } = require('electron')
// You have to pass the directory that contains widevine library here, it is
// * `libwidevinecdm.dylib` on macOS,
// * `widevinecdm.dll` on Windows.
app.commandLine.appendSwitch('widevine-cdm-path', '/path/to/widevine_library')
// The version of plugin can be got from `chrome://components` page in Chrome.
app.commandLine.appendSwitch('widevine-cdm-version', '1.4.8.866')
let win = null
app.whenReady().then(() => {
win = new BrowserWindow()
win.show()
})
```
## Verifying Widevine CDM support
To verify whether widevine works, you can use following ways:
* Open https://shaka-player-demo.appspot.com/ and load a manifest that uses
`Widevine`.
* Open http://www.dash-player.com/demo/drm-test-area/, check whether the page
says `bitdash uses Widevine in your browser`, then play the video.

View File

@@ -123,7 +123,7 @@ the list of versions in the [electron/releases] repository.
[homebrew]: https://brew.sh/
[mdn-guide]: https://developer.mozilla.org/en-US/docs/Learn/
[node]: https://nodejs.org/
[node-guide]: https://nodejs.dev/learn
[node-guide]: https://nodejs.dev/en/learn/
[node-download]: https://nodejs.org/en/download/
[nvm]: https://github.com/nvm-sh/nvm
[process-model]: ./process-model.md

View File

@@ -369,12 +369,12 @@ run. Create a launch.json configuration in a new `.vscode` folder in your projec
"name": "Renderer",
"port": 9222,
"request": "attach",
"type": "pwa-chrome",
"type": "chrome",
"webRoot": "${workspaceFolder}"
},
{
"name": "Main",
"type": "pwa-node",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
@@ -398,11 +398,11 @@ What we have done in the `launch.json` file is to create 3 configurations:
- `Main` is used to start the main process and also expose port 9222 for remote debugging
(`--remote-debugging-port=9222`). This is the port that we will use to attach the debugger
for the `Renderer`. Because the main process is a Node.js process, the type is set to
`pwa-node` (`pwa-` is the prefix that tells VS Code to use the latest JavaScript debugger).
`node`.
- `Renderer` is used to debug the renderer process. Because the main process is the one
that creates the process, we have to "attach" to it (`"request": "attach"`) instead of
creating a new one.
The renderer process is a web one, so the debugger we have to use is `pwa-chrome`.
The renderer process is a web one, so the debugger we have to use is `chrome`.
- `Main + renderer` is a [compound task] that executes the previous ones simultaneously.
:::caution

View File

@@ -111,6 +111,12 @@ Electron Forge can be configured to create distributables in different OS-specif
:::
:::tip Creating and Adding Application Icons
Setting custom application icons requires a few additions to your config. Check out [Forge's icon tutorial] for more information.
:::
:::note Packaging without Electron Forge
If you want to manually package your code, or if you're just interested understanding the
@@ -214,6 +220,7 @@ information.
[electron forge]: https://www.electronforge.io
[electron forge cli documentation]: https://www.electronforge.io/cli#commands
[makers]: https://www.electronforge.io/config/makers
[Forge's icon tutorial]: https://www.electronforge.io/guides/create-and-add-icons
<!-- Tutorial links -->

View File

@@ -672,8 +672,6 @@ filenames = {
"shell/renderer/electron_render_frame_observer.h",
"shell/renderer/electron_renderer_client.cc",
"shell/renderer/electron_renderer_client.h",
"shell/renderer/electron_renderer_pepper_host_factory.cc",
"shell/renderer/electron_renderer_pepper_host_factory.h",
"shell/renderer/electron_sandboxed_renderer_client.cc",
"shell/renderer/electron_sandboxed_renderer_client.h",
"shell/renderer/guest_view_container.cc",

View File

@@ -475,12 +475,14 @@ WebContents.prototype.loadURL = function (url, options) {
const removeListeners = () => {
this.removeListener('did-finish-load', finishListener);
this.removeListener('did-fail-load', failListener);
this.removeListener('did-navigate-in-page', finishListener);
this.removeListener('did-start-navigation', navigationListener);
this.removeListener('did-stop-loading', stopLoadingListener);
this.removeListener('destroyed', stopLoadingListener);
};
this.on('did-finish-load', finishListener);
this.on('did-fail-load', failListener);
this.on('did-navigate-in-page', finishListener);
this.on('did-start-navigation', navigationListener);
this.on('did-stop-loading', stopLoadingListener);
this.on('destroyed', stopLoadingListener);

View File

@@ -186,7 +186,10 @@ export class SrcAttribute extends WebViewAttribute {
opts.userAgent = useragent;
}
(this.webViewImpl.webviewNode as Electron.WebviewTag).loadURL(this.getValue(), opts);
(this.webViewImpl.webviewNode as Electron.WebviewTag).loadURL(this.getValue(), opts)
.catch(err => {
console.error('Unexpected error while loading URL', err);
});
}
}

View File

@@ -70,8 +70,22 @@ function isInstalled () {
// unzips and makes path.txt point at the correct executable
function extractFile (zipPath) {
return extract(zipPath, { dir: path.join(__dirname, 'dist') })
.then(() => fs.promises.writeFile(path.join(__dirname, 'path.txt'), platformPath));
const distPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || path.join(__dirname, 'dist');
return extract(zipPath, { dir: path.join(__dirname, 'dist') }).then(() => {
// If the zip contains an "electron.d.ts" file,
// move that up
const srcTypeDefPath = path.join(distPath, 'electron.d.ts');
const targetTypeDefPath = path.join(__dirname, 'electron.d.ts');
const hasTypeDefinitions = fs.existsSync(srcTypeDefPath);
if (hasTypeDefinitions) {
fs.renameSync(srcTypeDefPath, targetTypeDefPath);
}
// Write a "path.txt" file.
return fs.promises.writeFile(path.join(__dirname, 'path.txt'), platformPath);
});
}
function getPlatformPath () {

View File

@@ -1,12 +1,13 @@
{
"name": "electron",
"version": "20.2.0",
"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",
@@ -146,4 +146,4 @@
"resolutions": {
"nan": "nodejs/nan#16fa32231e2ccd89d2804b3f765319128b20c4ac"
}
}
}

1
patches/angle/.patches Normal file
View File

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

View File

@@ -0,0 +1,46 @@
From b8636b57b8f231994ecb3fb14f181c593c83a3fb Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Mon, 29 Aug 2022 16:25:46 -0400
Subject: [PATCH] [M106] 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 168104e..2f498d3 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -603,6 +603,11 @@
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 9f475e6..6ef5f72 100644
--- a/src/libANGLE/renderer/vulkan/QueryVk.cpp
+++ b/src/libANGLE/renderer/vulkan/QueryVk.cpp
@@ -303,6 +303,13 @@
{
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

@@ -124,3 +124,41 @@ feat_add_set_can_resize_mutator.patch
cherry-pick-2083e894852c.patch
cherry-pick-51daffbf5cd8.patch
dpwa_enable_window_controls_overlay_by_default.patch
create_browser_v8_snapshot_file_name_fuse.patch
cherry-pick-fefd6198da31.patch
cherry-pick-1eb1e18ad41d.patch
cherry-pick-05a0d99c9715.patch
cherry-pick-c83640db21b5.patch
fix_on-screen-keyboard_hides_on_input_blur_in_webview.patch
cherry-pick-65f0ef609c00.patch
cherry-pick-cb9dff93f3d4.patch
build_fix_building_with_enable_plugins_false.patch
build_allow_electron_to_use_exec_script.patch
cherry-pick-d5ffb4dd4112.patch
cherry-pick-65d46507a0c9.patch
cherry-pick-933cc81c6bad.patch
cherry-pick-06c87f9f42ff.patch
cherry-pick-67c9cbc784d6.patch
cherry-pick-a1cbf05b4163.patch
cherry-pick-ac4785387fff.patch
cherry-pick-81cb17c24788.patch
cherry-pick-9b3d0e2f1aab.patch
cherry-pick-1894458e04a2.patch
cherry-pick-6b4af5d82083.patch
cherry-pick-176c526846cb.patch
cherry-pick-65ad70274d4b.patch
cherry-pick-f46db6aac3e9.patch
cherry-pick-2ef09109c0ec.patch
cherry-pick-f98adc846aad.patch
cherry-pick-eed5a4de2c40.patch
cherry-pick-d1d654d73222.patch
cherry-pick-42e15c2055c4.patch
cherry-pick-77208afba04d.patch
mojo_disable_sync_call_interrupts_in_the_browser.patch
mojo_validate_that_a_message_is_allowed_to_use_the_sync_flag.patch
cherry-pick-819d876e1bb8.patch
cherry-pick-43637378b14e.patch
win_fix_touch_mode_detection_dcheck_in_canary.patch
cherry-pick-ca2b108a0f1f.patch
cherry-pick-d652130c4bc2.patch
cherry-pick-e545559df538.patch

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 7d538f812d72e0937e7a031e1c53651c352149c5..1cad40a9825f3c6df67dbcc12d2f9650aad809b2 100644
--- a/.gn
+++ b/.gn
@@ -169,4 +169,6 @@ exec_script_whitelist =
"//tools/grit/grit_rule.gni",
"//tools/gritsettings/BUILD.gn",
+
+ "//electron/BUILD.gn"
]

View File

@@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Milan Burda <miburda@microsoft.com>
Date: Sun, 30 Oct 2022 22:32:39 +0100
Subject: build: fix building with enable_plugins = false
This issue is fixed in latest Chromium
diff --git a/tools/ipc_fuzzer/message_lib/BUILD.gn b/tools/ipc_fuzzer/message_lib/BUILD.gn
index 00618d9f81cabd5084218431658fd91d22fb4208..26be64a51fc5767e0ee97681a0b3f2dfd74159fe 100644
--- a/tools/ipc_fuzzer/message_lib/BUILD.gn
+++ b/tools/ipc_fuzzer/message_lib/BUILD.gn
@@ -3,6 +3,7 @@
# found in the LICENSE file.
import("//components/nacl/features.gni")
+import("//ppapi/buildflags/buildflags.gni")
import("//remoting/remoting_enable.gni")
static_library("ipc_message_lib") {
@@ -22,7 +23,6 @@ static_library("ipc_message_lib") {
"//ipc",
"//media/cast:net",
"//media/gpu/ipc/common",
- "//ppapi/proxy:ipc",
"//skia",
"//third_party/blink/public:blink",
"//third_party/blink/public:blink_headers",
@@ -49,4 +49,7 @@ static_library("ipc_message_lib") {
if (enable_remoting) {
public_deps += [ "//remoting/host" ]
}
+ if (enable_plugins) {
+ public_deps += [ "//ppapi/proxy:ipc" ]
+ }
}

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 fe775337fbc22817d7489df143821eea2d9425ec..13a241273090e54fabdba9d82510e36d2386c4a4 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
@@ -2460,10 +2460,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 f51b8878eb0abe23889a07277efeaf7cdf961cc8..ddcef20b47357e58acae08b4183db6187b046f80 100644
--- a/third_party/blink/renderer/core/css/style_engine.cc
+++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -2808,6 +2808,7 @@ void StyleEngine::RecalcStyle(StyleRecalcChange change,
const StyleRecalcContext& style_recalc_context) {
DCHECK(GetDocument().documentElement());
ScriptForbiddenScope forbid_script;
+ SkipStyleRecalcScope skip_scope(*this);
CheckPseudoHasCacheScope check_pseudo_has_cache_scope(&GetDocument());
Element& root_element = style_recalc_root_.RootElement();
Element* parent = FlatTreeTraversal::ParentElement(root_element);
@@ -3400,4 +3401,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 a6c325b69e5bc43c657519f4c0730f6e2efd4f71..f7ccc6c2b7b306d76bba60cf46da91a5b291c29e 100644
--- a/third_party/blink/renderer/core/css/style_engine.h
+++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -178,6 +178,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;
@@ -342,6 +356,10 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
bool MarkReattachAllowed() const;
+ // 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>>&);
@@ -743,6 +761,9 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
Element& changed_element,
bool for_pseudo_change);
+ // Initialization value for SkipStyleRecalcScope.
+ bool AllowSkipStyleRecalcForScope() const;
+
Member<Document> document_;
// Tracks the number of currently loading top-level stylesheets. Sheets loaded
@@ -812,6 +833,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 8e5c4aab2e37ed0acda0ef56273d007fbaa58780..2df360c33c54e12af341b77771fcda95e562fa92 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3532,6 +3532,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,192 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robert Sesek <rsesek@chromium.org>
Date: Fri, 18 Nov 2022 19:31:38 +0000
Subject: Fix a data race leading to use-after-free in mojo::ChannelMac
ShutDown
(cherry picked from commit bd8a1e43aa93d5bb7674cb5a431e7375f7e2f192)
Bug: 1378564
Change-Id: I67041b1e2ef08dd0ee1ccbf6d534249c539b74db
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4027242
Commit-Queue: Robert Sesek <rsesek@chromium.org>
Reviewed-by: Ken Rockot <rockot@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#1071700}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4035114
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Robert Sesek <rsesek@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5359@{#881}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/mojo/core/channel_mac.cc b/mojo/core/channel_mac.cc
index 686dea5c783af06e41c290b03db251ca584d9a72..a24d5ab4ea9ae63f652acc2f903e577d45b1f0ee 100644
--- a/mojo/core/channel_mac.cc
+++ b/mojo/core/channel_mac.cc
@@ -25,6 +25,7 @@
#include "base/mac/scoped_mach_vm.h"
#include "base/message_loop/message_pump_for_io.h"
#include "base/task/current_thread.h"
+#include "base/thread_annotations.h"
#include "base/trace_event/typed_macros.h"
extern "C" {
@@ -167,7 +168,10 @@ class ChannelMac : public Channel,
vm_allocate(mach_task_self(), &address, size,
VM_MAKE_TAG(VM_MEMORY_MACH_MSG) | VM_FLAGS_ANYWHERE);
MACH_CHECK(kr == KERN_SUCCESS, kr) << "vm_allocate";
- send_buffer_.reset(address, size);
+ {
+ base::AutoLock lock(write_lock_);
+ send_buffer_.reset(address, size);
+ }
kr = vm_allocate(mach_task_self(), &address, size,
VM_MAKE_TAG(VM_MEMORY_MACH_MSG) | VM_FLAGS_ANYWHERE);
@@ -207,7 +211,11 @@ class ChannelMac : public Channel,
watch_controller_.StopWatchingMachPort();
- send_buffer_.reset();
+ {
+ base::AutoLock lock(write_lock_);
+ send_buffer_.reset();
+ reject_writes_ = true;
+ }
receive_buffer_.reset();
incoming_handles_.clear();
@@ -315,7 +323,7 @@ class ChannelMac : public Channel,
SendPendingMessagesLocked();
}
- void SendPendingMessagesLocked() {
+ void SendPendingMessagesLocked() EXCLUSIVE_LOCKS_REQUIRED(write_lock_) {
// If a previous send failed due to the receiver's kernel message queue
// being full, attempt to send that failed message first.
if (send_buffer_contains_message_ && !reject_writes_) {
@@ -342,7 +350,8 @@ class ChannelMac : public Channel,
}
}
- bool SendMessageLocked(MessagePtr message) {
+ bool SendMessageLocked(MessagePtr message)
+ EXCLUSIVE_LOCKS_REQUIRED(write_lock_) {
DCHECK(!send_buffer_contains_message_);
base::BufferIterator<char> buffer(
reinterpret_cast<char*>(send_buffer_.address()), send_buffer_.size());
@@ -437,7 +446,8 @@ class ChannelMac : public Channel,
return MachMessageSendLocked(header);
}
- bool MachMessageSendLocked(mach_msg_header_t* header) {
+ bool MachMessageSendLocked(mach_msg_header_t* header)
+ EXCLUSIVE_LOCKS_REQUIRED(write_lock_) {
kern_return_t kr = mach_msg(header, MACH_SEND_MSG | MACH_SEND_TIMEOUT,
header->msgh_size, 0, MACH_PORT_NULL,
/*timeout=*/0, MACH_PORT_NULL);
@@ -659,7 +669,7 @@ class ChannelMac : public Channel,
}
// Marks the channel as unaccepting of new messages and shuts it down.
- void OnWriteErrorLocked(Error error) {
+ void OnWriteErrorLocked(Error error) EXCLUSIVE_LOCKS_REQUIRED(write_lock_) {
reject_writes_ = true;
io_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&ChannelMac::OnError, this, error));
@@ -701,17 +711,17 @@ class ChannelMac : public Channel,
// Lock that protects the following members.
base::Lock write_lock_;
// Whether writes should be rejected due to an internal error.
- bool reject_writes_ = false;
+ bool reject_writes_ GUARDED_BY(write_lock_) = false;
// IO buffer for sending Mach messages.
- base::mac::ScopedMachVM send_buffer_;
+ base::mac::ScopedMachVM send_buffer_ GUARDED_BY(write_lock_);
// If a message timed out during send in MachMessageSendLocked(), this will
// be true to indicate that |send_buffer_| contains a message that must
// be sent. If this is true, then other calls to Write() queue messages onto
// |pending_messages_|.
- bool send_buffer_contains_message_ = false;
+ bool send_buffer_contains_message_ GUARDED_BY(write_lock_) = false;
// When |handshake_done_| is false or |send_buffer_contains_message_| is true,
// calls to Write() will enqueue messages here.
- base::circular_deque<MessagePtr> pending_messages_;
+ base::circular_deque<MessagePtr> pending_messages_ GUARDED_BY(write_lock_);
};
} // namespace
diff --git a/mojo/core/channel_unittest.cc b/mojo/core/channel_unittest.cc
index e9dee384440ee5a0500e86c522eef19c12bd8045..47422267cbaa0d3f90be6adc851a0651c1b74133 100644
--- a/mojo/core/channel_unittest.cc
+++ b/mojo/core/channel_unittest.cc
@@ -712,6 +712,69 @@ TEST(ChannelTest, SendToDeadMachPortName) {
}
#endif // BUILDFLAG(IS_MAC)
+TEST(ChannelTest, ShutDownStress) {
+ base::test::SingleThreadTaskEnvironment task_environment(
+ base::test::TaskEnvironment::MainThreadType::IO);
+
+ // Create a second IO thread for Channel B.
+ base::Thread peer_thread("channel_b_io");
+ peer_thread.StartWithOptions(
+ base::Thread::Options(base::MessagePumpType::IO, 0));
+
+ // Create two channels, A and B, which run on different threads.
+ PlatformChannel platform_channel;
+
+ CallbackChannelDelegate delegate_a;
+ scoped_refptr<Channel> channel_a = Channel::Create(
+ &delegate_a, ConnectionParams(platform_channel.TakeLocalEndpoint()),
+ Channel::HandlePolicy::kRejectHandles,
+ task_environment.GetMainThreadTaskRunner());
+ channel_a->Start();
+
+ scoped_refptr<Channel> channel_b = Channel::Create(
+ nullptr, ConnectionParams(platform_channel.TakeRemoteEndpoint()),
+ Channel::HandlePolicy::kRejectHandles, peer_thread.task_runner());
+ channel_b->Start();
+
+ base::WaitableEvent go_event;
+
+ // Warm up the channel to ensure that A and B are connected, then quit.
+ channel_b->Write(Channel::Message::CreateMessage(0, 0));
+ {
+ base::RunLoop run_loop;
+ delegate_a.set_on_message(run_loop.QuitClosure());
+ run_loop.Run();
+ }
+
+ // Block the peer thread while some tasks are queued up from the test main
+ // thread.
+ peer_thread.task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&base::WaitableEvent::Wait, base::Unretained(&go_event)));
+
+ // First, write some messages for Channel B.
+ for (int i = 0; i < 500; ++i) {
+ channel_b->Write(Channel::Message::CreateMessage(0, 0));
+ }
+
+ // Then shut down channel B.
+ channel_b->ShutDown();
+
+ // Un-block the peer thread.
+ go_event.Signal();
+
+ // And then flood the channel with messages. This will suss out data races
+ // during Channel B's shutdown, since Writes can happen across threads
+ // without a PostTask.
+ for (int i = 0; i < 1000; ++i) {
+ channel_b->Write(Channel::Message::CreateMessage(0, 0));
+ }
+
+ // Explicitly join the thread to wait for pending tasks, which may reference
+ // stack variables, to complete.
+ peer_thread.Stop();
+}
+
} // namespace
} // namespace core
} // namespace mojo

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 6739b9de4b500d6173c04966905e26f856594502..f0082d88d70d4ea76604cfac77c09727de134f2a 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
@@ -2176,6 +2176,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.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>
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt
index 3823a752b99f506d11c50aee36474c6c51c849cd..eeed0dfc0def17b1ba636f7f6a076caf770e1327 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-properties-values-api/registered-property-computation-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/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.

View File

@@ -0,0 +1,364 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jun Kokatsu <jkokatsu@google.com>
Date: Thu, 22 Sep 2022 22:16:55 +0000
Subject: Unify security check for Javascript URL navigation
This change unifies CSP and Trusted Types check for Javascript URL
navigations.
Bug: 1365082
Change-Id: I46aea31a918c6397ea71fd5ab345bc9dc19d91c2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3905476
Auto-Submit: Jun Kokatsu <jkokatsu@google.com>
Commit-Queue: Jun Kokatsu <jkokatsu@google.com>
Reviewed-by: Nate Chapin <japhet@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1050416}
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
index 5ad3d687829db7ed64424b0f593e3aab7951e37e..da289bc7ffc4416ad817b0f344bc24cc0f084582 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
@@ -164,34 +164,9 @@ void ScriptController::ExecuteJavaScriptURL(
const DOMWrapperWorld* world_for_csp) {
DCHECK(url.ProtocolIsJavaScript());
- const int kJavascriptSchemeLength = sizeof("javascript:") - 1;
- String script_source = DecodeURLEscapeSequences(
- url.GetString(), DecodeURLMode::kUTF8OrIsomorphic);
-
if (!window_->GetFrame())
return;
- auto* policy = window_->GetContentSecurityPolicyForWorld(world_for_csp);
- if (csp_disposition == network::mojom::CSPDisposition::CHECK &&
- !policy->AllowInline(ContentSecurityPolicy::InlineType::kNavigation,
- nullptr, script_source, String() /* nonce */,
- window_->Url(), EventHandlerPosition().line_)) {
- return;
- }
-
- // TODO(crbug.com/896041): Investigate how trusted type checks can be
- // implemented for isolated worlds.
- const bool should_bypass_trusted_type_check =
- csp_disposition == network::mojom::CSPDisposition::DO_NOT_CHECK ||
- ContentSecurityPolicy::ShouldBypassMainWorldDeprecated(world_for_csp);
- script_source = script_source.Substring(kJavascriptSchemeLength);
- if (!should_bypass_trusted_type_check) {
- script_source = TrustedTypesCheckForJavascriptURLinNavigation(
- script_source, window_.Get());
- if (script_source.IsEmpty())
- return;
- }
-
bool had_navigation_before =
window_->GetFrame()->Loader().HasProvisionalNavigation();
@@ -199,6 +174,9 @@ void ScriptController::ExecuteJavaScriptURL(
// Step 6. "Let baseURL be settings's API base URL." [spec text]
const KURL base_url = window_->BaseURL();
+ String script_source = window_->CheckAndGetJavascriptUrl(
+ world_for_csp, url, nullptr /* element */, csp_disposition);
+
// Step 7. "Let script be the result of creating a classic script given
// scriptSource, settings, baseURL, and the default classic script fetch
// options." [spec text]
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 2f0615ee1454946d6f46f6626ce9b860a0e04fee..3eab00e4410e749aecdf600097cb68df22dcf072 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -415,6 +415,39 @@ bool LocalDOMWindow::CanExecuteScripts(
return script_enabled;
}
+String LocalDOMWindow::CheckAndGetJavascriptUrl(
+ const DOMWrapperWorld* world,
+ const KURL& url,
+ Element* element,
+ network::mojom::CSPDisposition csp_disposition) {
+ const int kJavascriptSchemeLength = sizeof("javascript:") - 1;
+ String decoded_url = DecodeURLEscapeSequences(
+ url.GetString(), DecodeURLMode::kUTF8OrIsomorphic);
+ String script_source = decoded_url.Substring(kJavascriptSchemeLength);
+
+ if (csp_disposition == network::mojom::CSPDisposition::DO_NOT_CHECK)
+ return script_source;
+
+ // Check the CSP of the caller (the "source browsing context") if required,
+ // as per https://html.spec.whatwg.org/C/#javascript-protocol.
+ if (!GetContentSecurityPolicyForWorld(world)->AllowInline(
+ ContentSecurityPolicy::InlineType::kNavigation, element, decoded_url,
+ String() /* nonce */, Url(), OrdinalNumber::First()))
+ return String();
+
+ // TODO(crbug.com/896041): Investigate how trusted type checks can be
+ // implemented for isolated worlds.
+ if (ContentSecurityPolicy::ShouldBypassMainWorldDeprecated(world))
+ return script_source;
+
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#require-trusted-types-for-pre-navigation-check
+ // 4.9.1.1. require-trusted-types-for Pre-Navigation check
+ script_source =
+ TrustedTypesCheckForJavascriptURLinNavigation(script_source, this);
+
+ return script_source;
+}
+
void LocalDOMWindow::ExceptionThrown(ErrorEvent* event) {
MainThreadDebugger::Instance()->ExceptionThrown(this, event);
}
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h
index dcc065abe83948ca3d906f676365226dd82c732d..da06213cfbe2bd156509cd1ff67d600d528c34b0 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.h
+++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -31,6 +31,7 @@
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "services/network/public/mojom/content_security_policy.mojom-blink.h"
#include "third_party/blink/public/common/frame/fullscreen_request_token.h"
#include "third_party/blink/public/common/frame/payment_request_token.h"
#include "third_party/blink/public/common/metrics/post_message_counter.h"
@@ -211,6 +212,16 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
mojom::blink::PermissionsPolicyFeature feature,
UseCounterImpl::PermissionsPolicyUsageType type);
+ // Checks if navigation to Javascript URL is allowed. This check should run
+ // before any action is taken (e.g. creating new window) for all
+ // same-origin navigations.
+ String CheckAndGetJavascriptUrl(
+ const DOMWrapperWorld* world,
+ const KURL& url,
+ Element* element,
+ network::mojom::CSPDisposition csp_disposition =
+ network::mojom::CSPDisposition::CHECK);
+
Document* InstallNewDocument(const DocumentInit&);
// EventTarget overrides:
diff --git a/third_party/blink/renderer/core/frame/location.cc b/third_party/blink/renderer/core/frame/location.cc
index a1aeede568cfe33267d87fa68f096d20a83d50f9..92740842827d470d63da34dd90bdb937321c1a83 100644
--- a/third_party/blink/renderer/core/frame/location.cc
+++ b/third_party/blink/renderer/core/frame/location.cc
@@ -270,23 +270,6 @@ void Location::SetLocation(const String& url,
return;
}
- // Check the source browsing context's CSP to fulfill the CSP check
- // requirement of https://html.spec.whatwg.org/C/#navigate for javascript
- // URLs. Although the spec states we should perform this check on task
- // execution, there are concerns about the correctness of that statement,
- // see http://github.com/whatwg/html/issues/2591.
- if (completed_url.ProtocolIsJavaScript()) {
- String script_source = DecodeURLEscapeSequences(
- completed_url.GetString(), DecodeURLMode::kUTF8OrIsomorphic);
- if (!incumbent_window->GetContentSecurityPolicyForCurrentWorld()
- ->AllowInline(ContentSecurityPolicy::InlineType::kNavigation,
- nullptr /* element */, script_source,
- String() /* nonce */, incumbent_window->Url(),
- OrdinalNumber::First())) {
- return;
- }
- }
-
V8DOMActivityLogger* activity_logger =
V8DOMActivityLogger::CurrentActivityLoggerIfIsolatedWorld();
if (activity_logger) {
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
index e2398389b2064f0d804977ea9f5233cf34da5dae..49601b48571fbaebda29b6c2848a65275e4fd861 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -547,19 +547,12 @@ bool FrameLoader::AllowRequestForThisFrame(const FrameLoadRequest& request) {
const KURL& url = request.GetResourceRequest().Url();
if (url.ProtocolIsJavaScript()) {
- // Check the CSP of the caller (the "source browsing context") if required,
- // as per https://html.spec.whatwg.org/C/#javascript-protocol.
- bool javascript_url_is_allowed =
- request.GetOriginWindow()
- ->GetContentSecurityPolicyForWorld(request.JavascriptWorld().get())
- ->AllowInline(ContentSecurityPolicy::InlineType::kNavigation,
- frame_->DeprecatedLocalOwner(), url.GetString(),
- String() /* nonce */,
- request.GetOriginWindow()->Url(),
- OrdinalNumber::First());
-
- if (!javascript_url_is_allowed)
+ if (request.GetOriginWindow()
+ ->CheckAndGetJavascriptUrl(request.JavascriptWorld().get(), url,
+ frame_->DeprecatedLocalOwner())
+ .IsEmpty()) {
return false;
+ }
if (frame_->Owner() && ((frame_->Owner()->GetFramePolicy().sandbox_flags &
network::mojom::blink::WebSandboxFlags::kOrigin) !=
diff --git a/third_party/blink/renderer/core/page/create_window.cc b/third_party/blink/renderer/core/page/create_window.cc
index c526aab02f300a32404253537df6ff6c506664f8..36796587c96a51bc90f460def64358ec9788c72e 100644
--- a/third_party/blink/renderer/core/page/create_window.cc
+++ b/third_party/blink/renderer/core/page/create_window.cc
@@ -294,15 +294,11 @@ Frame* CreateNewWindow(LocalFrame& opener_frame,
request.SetFrameType(mojom::RequestContextFrameType::kAuxiliary);
const KURL& url = request.GetResourceRequest().Url();
- auto* csp_for_world = opener_window.GetContentSecurityPolicyForCurrentWorld();
- if (url.ProtocolIsJavaScript() && csp_for_world) {
- String script_source = DecodeURLEscapeSequences(
- url.GetString(), DecodeURLMode::kUTF8OrIsomorphic);
-
- if (!csp_for_world->AllowInline(
- ContentSecurityPolicy::InlineType::kNavigation,
- nullptr /* element */, script_source, String() /* nonce */,
- opener_window.Url(), OrdinalNumber::First())) {
+ if (url.ProtocolIsJavaScript()) {
+ if (opener_window
+ .CheckAndGetJavascriptUrl(request.JavascriptWorld().get(), url,
+ nullptr /* element */)
+ .IsEmpty()) {
return nullptr;
}
}
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/support/frame-without-trusted-types.html b/third_party/blink/web_tests/external/wpt/trusted-types/support/frame-without-trusted-types.html
new file mode 100644
index 0000000000000000000000000000000000000000..25cf073e79fa48f4311c3729f0b39d9be2a64e7c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/support/frame-without-trusted-types.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<head>
+</head>
+<body>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-report-only-support.html b/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-report-only-support.html
index d00d0538753a74411feeec42d5682082031c09d4..5f7856fabb7bb16085ffaffffbf6d7553179e8f3 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-report-only-support.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-report-only-support.html
@@ -5,7 +5,8 @@
<p>Support page for trusted-types-navigation-report-only.*.html tests.</p>
<a id="anchor" href="#">link</a>
<script>
- if (location.search == "?defaultpolicy") {
+ const params = new URLSearchParams(location.search);
+ if (!!params.get("defaultpolicy")) {
trustedTypes.createPolicy("default", {
createScript: s => s.replace("continue", "defaultpolicywashere"),
});
@@ -36,9 +37,17 @@
// won't disturb delivery of that event to the opener.
const anchor = document.getElementById("anchor");
anchor.href = target;
+
+ if (!!params.get("frame")) {
+ const frame = document.createElement("iframe");
+ frame.src = "frame-without-trusted-types.html";
+ frames.name = "frame";
+ document.body.appendChild(frame);
+ anchor.target = "frame";
+ }
+
if (!location.hash) {
document.addEventListener("DOMContentLoaded", _ => anchor.click());
}
</script>
</body>
-
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-support.html b/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-support.html
index cd41f3968e7c74f84a7541506053808073ce541d..5e02e6d4bf5aff9fa4f0b4b897a35726ed24168b 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-support.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/support/navigation-support.html
@@ -5,7 +5,8 @@
<p>Support page for trusted-types-navigation.*.html tests.</p>
<a id="anchor" href="#">link</a>
<script>
- if (location.search == "?defaultpolicy") {
+ const params = new URLSearchParams(location.search);
+ if (!!params.get("defaultpolicy")) {
trustedTypes.createPolicy("default", {
createScript: s => s.replace("continue", "defaultpolicywashere"),
});
@@ -35,8 +36,16 @@
const anchor = document.getElementById("anchor");
anchor.href = target;
+
+ if (!!params.get("frame")) {
+ const frame = document.createElement("iframe");
+ frame.src = "frame-without-trusted-types.html";
+ frames.name = "frame";
+ document.body.appendChild(frame);
+ anchor.target = "frame";
+ }
+
if (!location.hash)
document.addEventListener("DOMContentLoaded", _ => anchor.click());
</script>
</body>
-
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-navigation.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-navigation.tentative.html
index 4e784611dd64ecf2f9995403b1d4e5a19f8b4548..2113711902ae787cb3ad5d0e44eaed0fc2e99b87 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-navigation.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-navigation.tentative.html
@@ -38,10 +38,10 @@
}, "Navigate a window with javascript:-urls in enforcing mode.");
promise_test(t => {
- openWindow(t, "support/navigation-support.html?defaultpolicy");
+ openWindow(t, "support/navigation-support.html?defaultpolicy=1");
return Promise.all([
- expectLoadedAsMessage("navigation-support.html?defaultpolicy"),
- expectLoadedAsMessage("navigation-support.html?defaultpolicy&defaultpolicywashere"),
+ expectLoadedAsMessage("navigation-support.html?defaultpolicy=1"),
+ expectLoadedAsMessage("navigation-support.html?defaultpolicy=1&defaultpolicywashere"),
]);
}, "Navigate a window with javascript:-urls w/ default policy in enforcing mode.");
@@ -55,12 +55,46 @@
}, "Navigate a window with javascript:-urls in report-only mode.");
promise_test(t => {
- const page = "navigation-report-only-support.html?defaultpolicy";
+ const page = "navigation-report-only-support.html?defaultpolicy=1";
openWindow(t, `support/${page}`);
return Promise.all([
expectLoadedAsMessage(page),
- expectLoadedAsMessage("navigation-support.html?defaultpolicy#defaultpolicywashere"),
+ expectLoadedAsMessage("navigation-support.html?defaultpolicy=1#defaultpolicywashere"),
]);
}, "Navigate a window with javascript:-urls w/ default policy in report-only mode.");
+
+ promise_test(t => {
+ openWindow(t, "support/navigation-support.html?frame=1");
+ return Promise.all([
+ expectLoadedAsMessage("navigation-support.html?frame=1"),
+ expectViolationAsMessage("Location href"),
+ ]);
+ }, "Navigate a frame with javascript:-urls in enforcing mode.");
+
+ promise_test(t => {
+ openWindow(t, "support/navigation-support.html?defaultpolicy=1&frame=1");
+ return Promise.all([
+ expectLoadedAsMessage("navigation-support.html?defaultpolicy=1&frame=1"),
+ expectLoadedAsMessage("navigation-support.html?defaultpolicy=1&frame=1&defaultpolicywashere"),
+ ]);
+ }, "Navigate a frame with javascript:-urls w/ default policy in enforcing mode.");
+
+ promise_test(t => {
+ const page = "navigation-report-only-support.html?frame=1"
+ openWindow(t, `support/${page}`);
+ return Promise.all([
+ expectLoadedAsMessage(page),
+ expectLoadedAsMessage("navigation-support.html?frame=1#continue"),
+ ]);
+ }, "Navigate a frame with javascript:-urls in report-only mode.");
+
+ promise_test(t => {
+ const page = "navigation-report-only-support.html?defaultpolicy=1&frame=1";
+ openWindow(t, `support/${page}`);
+ return Promise.all([
+ expectLoadedAsMessage(page),
+ expectLoadedAsMessage("navigation-support.html?defaultpolicy=1&frame=1#defaultpolicywashere"),
+ ]);
+ }, "Navigate a frame with javascript:-urls w/ default policy in report-only mode.");
</script>
</body>

View File

@@ -0,0 +1,115 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Joey Arhar <jarhar@chromium.org>
Date: Tue, 22 Nov 2022 00:12:31 +0000
Subject: Avoid use-after-free in ValidationMessageOverlayDelegate
When ValidationMessageOverlayDelegate calls
ForceSynchronousDocumentInstall, it can somehow cause another validation
overlay to be created and delete the ValidationMessageOverlayDelegate.
This patch avoids additional code from being run inside the deleted
ValidationMessageOverlayDelegate.
(cherry picked from commit a37b66ded21af7ff1442bddd2ec3a0845535b3d6)
Fixed: 1382581
Change-Id: I044f91ecb55c77c4a5c40030b6856fc9a8ac7f6f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4019655
Reviewed-by: David Baron <dbaron@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1071652}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4043489
Commit-Queue: David Baron <dbaron@chromium.org>
Auto-Submit: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/branch-heads/5359@{#911}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc b/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc
index 33575769b1fa9361c91d27815832f467f7a7f19c..a8a1df886fd8accfdf9fcf9d06ba24e11f16293a 100644
--- a/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc
+++ b/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc
@@ -85,6 +85,8 @@ ValidationMessageOverlayDelegate::~ValidationMessageOverlayDelegate() {
EventDispatchForbiddenScope::AllowUserAgentEvents allow_events;
page_->WillBeDestroyed();
}
+ if (destroyed_ptr_)
+ *destroyed_ptr_ = true;
}
LocalFrameView& ValidationMessageOverlayDelegate::FrameView() const {
@@ -175,7 +177,18 @@ void ValidationMessageOverlayDelegate::CreatePage(const FrameOverlay& overlay) {
WriteDocument(data.get());
float zoom_factor = anchor_->GetDocument().GetFrame()->PageZoomFactor();
frame->SetPageZoomFactor(zoom_factor);
+
+ // ForceSynchronousDocumentInstall can cause another call to
+ // ValidationMessageClientImpl::ShowValidationMessage, which will hide this
+ // validation message and may even delete this. In order to avoid continuing
+ // when this is destroyed, |destroyed| will be set to true in the destructor.
+ bool destroyed = false;
+ DCHECK(!destroyed_ptr_);
+ destroyed_ptr_ = &destroyed;
frame->ForceSynchronousDocumentInstall("text/html", data);
+ if (destroyed)
+ return;
+ destroyed_ptr_ = nullptr;
Element& main_message = GetElementById("main-message");
main_message.setTextContent(message_);
diff --git a/third_party/blink/renderer/core/page/validation_message_overlay_delegate.h b/third_party/blink/renderer/core/page/validation_message_overlay_delegate.h
index 9db786a4fbd12bc6aeefc520143f872965ad7df8..26e96d8ffad11938dcc3dc5b059f2c7ebf077b94 100644
--- a/third_party/blink/renderer/core/page/validation_message_overlay_delegate.h
+++ b/third_party/blink/renderer/core/page/validation_message_overlay_delegate.h
@@ -72,6 +72,10 @@ class CORE_EXPORT ValidationMessageOverlayDelegate
String sub_message_;
TextDirection message_dir_;
TextDirection sub_message_dir_;
+
+ // Used by CreatePage() to determine if this has been deleted in the middle of
+ // the function.
+ bool* destroyed_ptr_ = nullptr;
};
} // namespace blink
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/constraints/reportValidity-crash.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/constraints/reportValidity-crash.html
new file mode 100644
index 0000000000000000000000000000000000000000..d6bab924adc9fb481235af10d706cbf4d4ef2df9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/constraints/reportValidity-crash.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+<script>
+Object.prototype.__defineGetter__('then', prom);
+var prom_count = 0;
+function prom() {
+prom_count++;
+if (prom_count > 2) return;
+var v14 = x37.animate({},100);
+v14.reverse();
+v14.ready;
+v14.currentTime = 0;
+x57.reportValidity();
+}
+function f0() {
+var v38 = x37.animate({},300);
+v38.ready;
+x57.prepend(x78);
+}
+function f1() {
+var x57 = document.getElementById("x57");
+x57.disabled = false;
+}
+</script>
+</head>
+
+<body>
+<fieldset id="x37">
+<canvas onfocusin="f0()" >
+<input id="x78" autofocus="" onfocusout="f1()" >
+</canvas>
+<select id="x57" disabled="" required=""></select>
+</body>
+
+</html>

View File

@@ -0,0 +1,104 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maks Orlovich <morlovich@chromium.org>
Date: Tue, 22 Nov 2022 22:18:55 +0000
Subject: Align NetworkContext::SetNetworkConditions better with devtools
emulateNetworkConditions
The former used values of 0 to disable particular throttles, while the
later documents -1, and looks to be pretty much a direct client, and the
only one. So make NetworkService handle everything <= 0 as a disable,
clamping at intake of config.
Bug: 1382033
(cherry picked from commit ce463c2c939818a12bbcec5e2c91c35f2a0a1f0e)
Change-Id: I2fd3f075d5071cb0cf647838782115b5c00405bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4035891
Reviewed-by: Ken Buchanan <kenrb@chromium.org>
Reviewed-by: Eric Orth <ericorth@chromium.org>
Commit-Queue: Maks Orlovich <morlovich@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1073566}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4048289
Cr-Commit-Position: refs/branch-heads/5414@{#188}
Cr-Branched-From: 4417ee59d7bf6df7a9c9ea28f7722d2ee6203413-refs/heads/main@{#1070088}
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index b6a2ed2857ee9cb838542d76a5c3031a28483a8b..7f41b5a1cf98576bce93b14196cf7dfabf7aaa93 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -554,11 +554,11 @@ struct NetworkConditions {
// response received.
mojo_base.mojom.TimeDelta latency;
- // Maximal aggregated download throughput (bytes/sec). 0 disables download
+ // Maximal aggregated download throughput (bytes/sec). <=0 disables download
// throttling.
double download_throughput;
- // Maximal aggregated upload throughput (bytes/sec). 0 disables upload
+ // Maximal aggregated upload throughput (bytes/sec). <=0 disables upload
// throttling.
double upload_throughput;
};
diff --git a/services/network/throttling/network_conditions.cc b/services/network/throttling/network_conditions.cc
index 71cd4ac0e52cc1f262c5b58caf20448b57b6b64f..18b2b6e0efdc2e17dbbbfaa411b4ab49ec787bc4 100644
--- a/services/network/throttling/network_conditions.cc
+++ b/services/network/throttling/network_conditions.cc
@@ -4,6 +4,8 @@
#include "services/network/throttling/network_conditions.h"
+#include <algorithm>
+
namespace network {
NetworkConditions::NetworkConditions() : NetworkConditions(false) {}
@@ -16,9 +18,9 @@ NetworkConditions::NetworkConditions(bool offline,
double download_throughput,
double upload_throughput)
: offline_(offline),
- latency_(latency),
- download_throughput_(download_throughput),
- upload_throughput_(upload_throughput) {}
+ latency_(std::max(latency, 0.0)),
+ download_throughput_(std::max(download_throughput, 0.0)),
+ upload_throughput_(std::max(upload_throughput, 0.0)) {}
NetworkConditions::~NetworkConditions() {}
diff --git a/services/network/throttling/network_conditions.h b/services/network/throttling/network_conditions.h
index f8c8214b34bafcb1f656dd3a39a0cf17fea821ea..c5232231d308b09105234101f4bc575491505372 100644
--- a/services/network/throttling/network_conditions.h
+++ b/services/network/throttling/network_conditions.h
@@ -28,6 +28,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkConditions {
bool IsThrottling() const;
bool offline() const { return offline_; }
+
+ // These are 0 if the corresponding throttle is disabled, >0 otherwise.
double latency() const { return latency_; }
double download_throughput() const { return download_throughput_; }
double upload_throughput() const { return upload_throughput_; }
diff --git a/services/network/throttling/throttling_controller_unittest.cc b/services/network/throttling/throttling_controller_unittest.cc
index fbe2c6d20d1d5362a77bd951e87b3fe41be13098..e834f8bdc13b5691b1e458dcafead482a0537e14 100644
--- a/services/network/throttling/throttling_controller_unittest.cc
+++ b/services/network/throttling/throttling_controller_unittest.cc
@@ -297,7 +297,7 @@ TEST(ThrottlingControllerTest, DownloadOnly) {
ThrottlingControllerTestHelper helper;
TestCallback* callback = helper.callback();
- helper.SetNetworkState(false, 10000000, 0);
+ helper.SetNetworkState(false, 10000000, -1);
int rv = helper.Start(false);
EXPECT_EQ(rv, net::ERR_IO_PENDING);
helper.FastForwardUntilNoTasksRemain();
@@ -316,7 +316,7 @@ TEST(ThrottlingControllerTest, UploadOnly) {
ThrottlingControllerTestHelper helper;
TestCallback* callback = helper.callback();
- helper.SetNetworkState(false, 0, 1000000);
+ helper.SetNetworkState(false, -2, 1000000);
int rv = helper.Start(true);
EXPECT_EQ(rv, net::OK);
helper.FastForwardUntilNoTasksRemain();

View File

@@ -0,0 +1,78 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ilya Nikolaevskiy <ilnik@chromium.org>
Date: Mon, 14 Nov 2022 12:33:49 +0000
Subject: Fix UAF in VideoCaptureDeviceWin::FrameReceived
(cherry picked from commit d08a3822658cb4ca4261659f1487069a14b51bd9)
Bug: 1381401
Change-Id: Ib742ec7b86d3c419f37f12694bf9cd5f3f03305c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4013158
Reviewed-by: Markus Handell <handellm@google.com>
Commit-Queue: Ilya Nikolaevskiy <ilnik@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1069054}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4023295
Cr-Commit-Position: refs/branch-heads/5359@{#809}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/media/capture/video/win/video_capture_device_win.cc b/media/capture/video/win/video_capture_device_win.cc
index df0aef940a007a594c328f10a2ea26e1d381505f..b220ded61ed5c501426ccc5c128dd4494c448b2f 100644
--- a/media/capture/video/win/video_capture_device_win.cc
+++ b/media/capture/video/win/video_capture_device_win.cc
@@ -866,34 +866,35 @@ void VideoCaptureDeviceWin::FrameReceived(const uint8_t* buffer,
const VideoCaptureFormat& format,
base::TimeDelta timestamp,
bool flip_y) {
+ // We always calculate camera rotation for the first frame. We also cache
+ // the latest value to use when AutoRotation is turned off.
+ // To avoid potential deadlock, do this without holding a lock.
+ if (!camera_rotation_.has_value() || IsAutoRotationEnabled())
+ camera_rotation_ = GetCameraRotation(device_descriptor_.facing);
+
{
base::AutoLock lock(lock_);
if (state_ != kCapturing)
return;
- }
- if (first_ref_time_.is_null())
- first_ref_time_ = base::TimeTicks::Now();
+ if (first_ref_time_.is_null())
+ first_ref_time_ = base::TimeTicks::Now();
- // There is a chance that the platform does not provide us with the timestamp,
- // in which case, we use reference time to calculate a timestamp.
- if (timestamp == kNoTimestamp)
- timestamp = base::TimeTicks::Now() - first_ref_time_;
+ // There is a chance that the platform does not provide us with the
+ // timestamp, in which case, we use reference time to calculate a timestamp.
+ if (timestamp == kNoTimestamp)
+ timestamp = base::TimeTicks::Now() - first_ref_time_;
- // We always calculate camera rotation for the first frame. We also cache the
- // latest value to use when AutoRotation is turned off.
- if (!camera_rotation_.has_value() || IsAutoRotationEnabled())
- camera_rotation_ = GetCameraRotation(device_descriptor_.facing);
-
- // TODO(julien.isorce): retrieve the color space information using the
- // DirectShow api, AM_MEDIA_TYPE::VIDEOINFOHEADER2::dwControlFlags. If
- // AMCONTROL_COLORINFO_PRESENT, then reinterpret dwControlFlags as a
- // DXVA_ExtendedFormat. Then use its fields DXVA_VideoPrimaries,
- // DXVA_VideoTransferMatrix, DXVA_VideoTransferFunction and
- // DXVA_NominalRangeto build a gfx::ColorSpace. See http://crbug.com/959992.
- client_->OnIncomingCapturedData(buffer, length, format, gfx::ColorSpace(),
- camera_rotation_.value(), flip_y,
- base::TimeTicks::Now(), timestamp);
+ // TODO(julien.isorce): retrieve the color space information using the
+ // DirectShow api, AM_MEDIA_TYPE::VIDEOINFOHEADER2::dwControlFlags. If
+ // AMCONTROL_COLORINFO_PRESENT, then reinterpret dwControlFlags as a
+ // DXVA_ExtendedFormat. Then use its fields DXVA_VideoPrimaries,
+ // DXVA_VideoTransferMatrix, DXVA_VideoTransferFunction and
+ // DXVA_NominalRangeto build a gfx::ColorSpace. See http://crbug.com/959992.
+ client_->OnIncomingCapturedData(buffer, length, format, gfx::ColorSpace(),
+ camera_rotation_.value(), flip_y,
+ base::TimeTicks::Now(), timestamp);
+ }
while (!take_photo_callbacks_.empty()) {
TakePhotoCallback cb = std::move(take_photo_callbacks_.front());

View File

@@ -0,0 +1,115 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: evliu <evliu@google.com>
Date: Mon, 14 Nov 2022 20:05:12 +0000
Subject: Replace raw pointer to LocalMuter with weak ptr
This CL replaces a raw pointer to LocalMuter with a weak ptr. Additional
info about this bug here: http://crbug/1377783
(cherry picked from commit 9989b93eb12c93b9351d5bf2872c1069ef5f7d01)
Bug: 1377783
Change-Id: Id821ea800ba12f1cfae4677fc591c12dec112852
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3997421
Reviewed-by: Paul Semel <paulsemel@chromium.org>
Reviewed-by: Olga Sharonova <olka@chromium.org>
Commit-Queue: Evan Liu <evliu@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#1068776}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4024547
Auto-Submit: Evan Liu <evliu@google.com>
Owners-Override: Srinivas Sista <srinivassista@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Evan Liu <evliu@google.com>
Cr-Commit-Position: refs/branch-heads/5359@{#824}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/services/audio/local_muter.h b/services/audio/local_muter.h
index a484c7dfd60883b07c8fc61da768edf508ac53af..b108e32306a264be4d51027c4419efc70a5dbe0c 100644
--- a/services/audio/local_muter.h
+++ b/services/audio/local_muter.h
@@ -7,6 +7,7 @@
#include "base/callback.h"
#include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/unguessable_token.h"
#include "media/mojo/mojom/audio_stream_factory.mojom.h"
@@ -46,6 +47,8 @@ class LocalMuter final : public media::mojom::LocalMuter,
bool HasReceivers() { return !receivers_.empty(); }
+ base::WeakPtr<LocalMuter> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
+
private:
// Runs the |all_bindings_lost_callback_| when |bindings_| becomes empty.
void OnBindingLost();
@@ -57,6 +60,8 @@ class LocalMuter final : public media::mojom::LocalMuter,
base::RepeatingClosure all_bindings_lost_callback_;
SEQUENCE_CHECKER(sequence_checker_);
+
+ base::WeakPtrFactory<LocalMuter> weak_factory_{this};
};
} // namespace audio
diff --git a/services/audio/stream_factory.cc b/services/audio/stream_factory.cc
index 48152cb64769ab1a76920d2581f373b57fef85c9..60ff2766809d4c43c021e47cfa5087b9dbe089b8 100644
--- a/services/audio/stream_factory.cc
+++ b/services/audio/stream_factory.cc
@@ -181,8 +181,9 @@ void StreamFactory::BindMuter(
if (it == muters_.end()) {
auto muter_ptr = std::make_unique<LocalMuter>(&coordinator_, group_id);
muter = muter_ptr.get();
- muter->SetAllBindingsLostCallback(base::BindRepeating(
- &StreamFactory::DestroyMuter, base::Unretained(this), muter));
+ muter->SetAllBindingsLostCallback(
+ base::BindRepeating(&StreamFactory::DestroyMuter,
+ base::Unretained(this), muter_ptr->GetWeakPtr()));
muters_.emplace_back(std::move(muter_ptr));
} else {
muter = it->get();
@@ -254,9 +255,10 @@ void StreamFactory::DestroyOutputStream(OutputStream* stream) {
DCHECK_EQ(1u, erased);
}
-void StreamFactory::DestroyMuter(LocalMuter* muter) {
+void StreamFactory::DestroyMuter(base::WeakPtr<LocalMuter> muter) {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
- DCHECK(muter);
+ if (!muter)
+ return;
// Output streams have a task posting before destruction (see the OnError
// function in output_stream.cc). To ensure that stream destruction and
@@ -265,13 +267,11 @@ void StreamFactory::DestroyMuter(LocalMuter* muter) {
// Otherwise, a "destroy all streams, then destroy the muter" sequence may
// result in a brief blip of audio.
auto do_destroy = [](base::WeakPtr<StreamFactory> weak_this,
- LocalMuter* muter) {
- if (weak_this) {
-
+ base::WeakPtr<LocalMuter> muter) {
+ if (weak_this && muter) {
const auto it =
std::find_if(weak_this->muters_.begin(), weak_this->muters_.end(),
- base::MatchesUniquePtr(muter));
- DCHECK(it != weak_this->muters_.end());
+ base::MatchesUniquePtr(muter.get()));
// The LocalMuter can still have receivers if a receiver was bound after
// DestroyMuter is called but before the do_destroy task is run.
diff --git a/services/audio/stream_factory.h b/services/audio/stream_factory.h
index 2207c72cb39e666e5c207016035a9d295d708aa0..b6119025f043e433455b35ee71e2b130299d1d21 100644
--- a/services/audio/stream_factory.h
+++ b/services/audio/stream_factory.h
@@ -110,7 +110,7 @@ class StreamFactory final : public media::mojom::AudioStreamFactory {
void DestroyInputStream(InputStream* stream);
void DestroyOutputStream(OutputStream* stream);
- void DestroyMuter(LocalMuter* muter);
+ void DestroyMuter(base::WeakPtr<LocalMuter> muter);
void DestroyLoopbackStream(LoopbackStream* stream);
SEQUENCE_CHECKER(owning_sequence_);

View File

@@ -0,0 +1,46 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andy Paicu <andypaicu@chromium.org>
Date: Thu, 6 Oct 2022 21:04:23 +0000
Subject: Fix UAF issue around permission status observer list
(cherry picked from commit 4df595127d95d4b0bf115be1ab4604d95b75273c)
(cherry picked from commit 1dc5dda6112bdd811c923520cc728a474583409e)
Bug: 1363040
Change-Id: I1f64a901b83aa834ae652c8041456e9b7d253c1f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3907744
Reviewed-by: Kamila Hasanbega <hkamila@chromium.org>
Commit-Queue: Andy Paicu <andypaicu@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/main@{#1049058}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3929034
Reviewed-by: Illia Klimov <elklm@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/5304@{#483}
Cr-Original-Branched-From: 5d7b1fc9cb7103d9c82eed647cf4be38cf09738b-refs/heads/main@{#1047731}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3936291
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5249@{#764}
Cr-Branched-From: 4f7bea5de862aaa52e6bde5920755a9ef9db120b-refs/heads/main@{#1036826}
diff --git a/third_party/blink/renderer/modules/permissions/permission_status_listener.cc b/third_party/blink/renderer/modules/permissions/permission_status_listener.cc
index 424314c1dd49bd693643e41adb537f7a9d01e5d2..946e28ac3139a1927ac36281f04cec9f5faf76d2 100644
--- a/third_party/blink/renderer/modules/permissions/permission_status_listener.cc
+++ b/third_party/blink/renderer/modules/permissions/permission_status_listener.cc
@@ -62,7 +62,17 @@ void PermissionStatusListener::OnPermissionStatusChange(
status_ = status;
+ // The `observers_` list can change in response to permission status change
+ // events as the observers map to PermissionStatus JS objects which can be
+ // created and destroyed in the JS event handler function. To avoid UAF and
+ // list modification issues, a temporary snapshot of the observers is made and
+ // used instead.
+ HeapHashSet<WeakMember<Observer>> observers;
for (const auto& observer : observers_) {
+ observers.insert(observer);
+ }
+
+ for (const auto& observer : observers) {
if (observer)
observer->OnPermissionStatusChange(status);
else

View File

@@ -0,0 +1,622 @@
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 19c9c52fa5a796c93e80f77029727d64acfdfa07..4e5215739f8533d25831f3302515861df179525f 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,63 +255,86 @@ 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>" ],
+ "permissions": [
+ "tabs",
+ "<all_urls>",
+ "nativeMessaging"
+ ],
"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();
+ GURL test_page_url =
+ embedded_test_server()->GetURL("foo.com", "/title1.html");
int old_process_id =
- web_contents->GetPrimaryMainFrame()->GetProcess()->GetID();
+ active_web_contents()->GetPrimaryMainFrame()->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->GetPrimaryMainFrame()->GetProcess()->GetID();
+ active_web_contents()->GetPrimaryMainFrame()->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) {
@@ -319,12 +351,19 @@ 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_;
+ TestExtensionDir active_dir_;
+ TestExtensionDir spoofed_dir_;
raw_ptr<const Extension> active_extension_ = nullptr;
raw_ptr<const Extension> spoofed_extension_ = nullptr;
};
@@ -340,24 +379,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->GetPrimaryMainFrame()->GetProcess();
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
IPC::IpcSecurityTestUtil::PwnMessageReceived(
main_frame_process->GetChannel(),
@@ -371,24 +408,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->GetPrimaryMainFrame()->GetProcess();
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
IPC::IpcSecurityTestUtil::PwnMessageReceived(
main_frame_process->GetChannel(),
@@ -401,24 +436,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->GetPrimaryMainFrame()->GetProcess();
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
IPC::IpcSecurityTestUtil::PwnMessageReceived(
main_frame_process->GetChannel(),
@@ -432,25 +465,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->GetPrimaryMainFrame()->GetProcess();
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
IPC::IpcSecurityTestUtil::PwnMessageReceived(
main_frame_process->GetChannel(),
@@ -464,18 +495,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,
@@ -484,7 +513,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->GetPrimaryMainFrame()->GetProcess();
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
IPC::IpcSecurityTestUtil::PwnMessageReceived(
main_frame_process->GetChannel(),
@@ -494,4 +523,98 @@ 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
+
} // 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 a36b9901b50cd99ac641d70d2f316362006e45e7..73148877e2b8b28374ffd32aa10361d21e4911e4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -8595,10 +8595,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");
@@ -8670,8 +8678,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;
@@ -14757,11 +14765,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) {
@@ -14770,6 +14773,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;
@@ -15139,10 +15148,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) {
@@ -15150,7 +15155,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)) {
@@ -15275,7 +15287,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");
@@ -17848,8 +17861,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;
}
@@ -18016,8 +18029,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;
@@ -18257,11 +18270,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");
@@ -18274,14 +18296,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,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jaroslav Sevcik <jarin@chromium.org>
Date: Thu, 1 Dec 2022 14:15:52 +0000
Subject: Make WidgetBase::BeginMainFrame resilient to disposed 'this'
This patch makes sure that WidgetBase::BeginMainFrame can finish
execution even if processing the RAF-throttled handlers
(DispatchRafAlignedInput) destroys 'this' instance.
(cherry picked from commit af6e22c14bec7ad64115b24ece6d423f144214ca)
Bug: chromium:1381871
Change-Id: I81aa4ba697f80f8666bb2a3b5542cac210b1efa9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4030809
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1072864}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4068023
Auto-Submit: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Cr-Commit-Position: refs/branch-heads/5359@{#1053}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/third_party/blink/renderer/platform/widget/widget_base.cc b/third_party/blink/renderer/platform/widget/widget_base.cc
index e32cbe6473e1e51f4c523b68263cffd1bfb5527c..be585e22e071b078a62552b9fc3e72d1dd8eb036 100644
--- a/third_party/blink/renderer/platform/widget/widget_base.cc
+++ b/third_party/blink/renderer/platform/widget/widget_base.cc
@@ -861,8 +861,14 @@ void WidgetBase::BeginMainFrame(base::TimeTicks frame_time) {
if (ShouldRecordBeginMainFrameMetrics()) {
raf_aligned_input_start_time = base::TimeTicks::Now();
}
+
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
widget_input_handler_manager_->input_event_queue()->DispatchRafAlignedInput(
frame_time);
+ // DispatchRafAlignedInput could have detached the frame.
+ if (!weak_this)
+ return;
+
if (ShouldRecordBeginMainFrameMetrics()) {
client_->RecordDispatchRafAlignedInputTime(raf_aligned_input_start_time);
}

View File

@@ -0,0 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ted Meyer <tmathmeyer@chromium.org>
Date: Sat, 3 Dec 2022 00:09:22 +0000
Subject: Fix UAF caused by vector operations during iteration
MediaInspectorContextImpl::CullPlayers iterates through dead_players_
to remove their events, but this can cause a GC event which can
end up adding more players to the |dead_players_| vector, causing
it to get re-allocated and it's iterators invalidated.
We can fix this simply by not using an iterator, and removing elements
from the vector before we trigger any GC operations that might cause
other changes to the vector.
Bug: 1383991
Change-Id: I59f5824c156ff58cf6b55ac9b942c8efdb1ed65a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4064295
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Commit-Queue: Ted (Chromium) Meyer <tmathmeyer@chromium.org>
Reviewed-by: Thomas Guilbert <tguilbert@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1078842}
diff --git a/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc b/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc
index c0965693783d5cc0eade67fc78f026cec2942792..6e89262ca229b89407c3f6fff2ab5bf74be460e0 100644
--- a/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_media_context_impl.cc
@@ -109,9 +109,13 @@ void MediaInspectorContextImpl::TrimPlayer(const WebString& playerId) {
void MediaInspectorContextImpl::CullPlayers(const WebString& prefer_keep) {
// Erase all the dead players, but only erase the required number of others.
- for (const auto& playerId : dead_players_)
+ while (!dead_players_.IsEmpty()) {
+ auto playerId = dead_players_.back();
+ // remove it first, since |RemovePlayer| can cause a GC event which can
+ // potentially caues more players to get added to |dead_players_|.
+ dead_players_.pop_back();
RemovePlayer(playerId);
- dead_players_.clear();
+ }
while (!expendable_players_.IsEmpty()) {
if (total_event_count_ <= kMaxCachedPlayerEvents)

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 2dad433c7deb91a2d06f7a10077c9197bd2eba98..0a6e94a1f5327600c1c13cd6fd7586c7ca09037e 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -1069,26 +1069,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 d6d33df90907dd1521108cfbae1ecbd430bb4e8e..03f92c993a05122b0df1e3b6afdad50edd9e1b41 100644
--- a/components/autofill/core/browser/browser_autofill_manager.h
+++ b/components/autofill/core/browser/browser_autofill_manager.h
@@ -475,11 +475,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,119 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Corentin Wallez <cwallez@chromium.org>
Date: Tue, 29 Nov 2022 14:07:46 +0000
Subject: Keep a reference to the transfer buffer in Dawn read/write handles.
Previously the Dawn read/write handles in the GPU process only contained
a pointer to the inside of a shmem region owned by a gpu::Buffer that
had a different lifetime. This could allow a renderer process to
deallocate the memory from underneath the handle which is bad.
Fix this by keepind a scoped_refptr to the gpu::Buffer inside the
read/write handles to extend the lifetime of the shmem to be at least as
big as the handle's.
Fixed: chromium:1393177
Change-Id: I9d9c18d5155a46e0e3a01d385d221a6370bd2bea
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4056276
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1076828}
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 a15b6f9b3b345079d8cf8251ca5f77b6e7ef647a..10941d9f65c66e50303cf7293180c29fced8ffe2 100644
--- a/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
+++ b/gpu/command_buffer/service/dawn_service_memory_transfer_service.cc
@@ -6,6 +6,7 @@
#include "base/memory/raw_ptr.h"
#include "gpu/command_buffer/common/dawn_memory_transfer_handle.h"
+#include "gpu/command_buffer/service/command_buffer_service.h"
#include "gpu/command_buffer/service/common_decoder.h"
namespace gpu {
@@ -16,8 +17,8 @@ namespace {
class ReadHandleImpl
: public dawn::wire::server::MemoryTransferService::ReadHandle {
public:
- ReadHandleImpl(void* ptr, uint32_t size)
- : ReadHandle(), ptr_(ptr), size_(size) {}
+ ReadHandleImpl(scoped_refptr<Buffer> buffer, void* ptr, uint32_t size)
+ : buffer_(std::move(buffer)), ptr_(ptr), size_(size) {}
~ReadHandleImpl() override = default;
@@ -44,6 +45,8 @@ class ReadHandleImpl
}
private:
+ scoped_refptr<gpu::Buffer> buffer_;
+ // Pointer to client-visible shared memory owned by buffer_.
raw_ptr<void> ptr_;
uint32_t size_;
};
@@ -51,8 +54,8 @@ class ReadHandleImpl
class WriteHandleImpl
: public dawn::wire::server::MemoryTransferService::WriteHandle {
public:
- WriteHandleImpl(const void* ptr, uint32_t size)
- : WriteHandle(), ptr_(ptr), size_(size) {}
+ WriteHandleImpl(scoped_refptr<Buffer> buffer, const void* ptr, uint32_t size)
+ : buffer_(std::move(buffer)), ptr_(ptr), size_(size) {}
~WriteHandleImpl() override = default;
@@ -82,7 +85,9 @@ class WriteHandleImpl
}
private:
- raw_ptr<const void> ptr_; // Pointer to client-visible shared memory.
+ scoped_refptr<gpu::Buffer> buffer_;
+ // Pointer to client-visible shared memory owned by buffer_.
+ raw_ptr<const void> ptr_;
uint32_t size_;
};
@@ -111,13 +116,19 @@ bool DawnServiceMemoryTransferService::DeserializeReadHandle(
int32_t shm_id = handle->shm_id;
uint32_t shm_offset = handle->shm_offset;
- void* ptr = decoder_->GetAddressAndCheckSize(shm_id, shm_offset, size);
+ scoped_refptr<gpu::Buffer> buffer =
+ decoder_->command_buffer_service()->GetTransferBuffer(shm_id);
+ if (buffer == nullptr) {
+ return false;
+ }
+
+ void* ptr = buffer->GetDataAddress(shm_offset, size);
if (ptr == nullptr) {
return false;
}
DCHECK(read_handle);
- *read_handle = new ReadHandleImpl(ptr, size);
+ *read_handle = new ReadHandleImpl(std::move(buffer), ptr, size);
return true;
}
@@ -139,13 +150,19 @@ bool DawnServiceMemoryTransferService::DeserializeWriteHandle(
int32_t shm_id = handle->shm_id;
uint32_t shm_offset = handle->shm_offset;
- void* ptr = decoder_->GetAddressAndCheckSize(shm_id, shm_offset, size);
+ scoped_refptr<gpu::Buffer> buffer =
+ decoder_->command_buffer_service()->GetTransferBuffer(shm_id);
+ if (buffer == nullptr) {
+ return false;
+ }
+
+ const void* ptr = buffer->GetDataAddress(shm_offset, size);
if (ptr == nullptr) {
return false;
}
DCHECK(write_handle);
- *write_handle = new WriteHandleImpl(ptr, size);
+ *write_handle = new WriteHandleImpl(std::move(buffer), ptr, size);
return true;
}

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 5332ae4094c5a8062cb1b8c830869095b964eabc..8f2be276b702bf5a3071b1bf44a9a5419880acf1 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,
@@ -979,6 +970,7 @@ void VideoEncoder::ResetInternal() {
}
static void isConfigSupportedWithSoftwareOnly(
+ ScriptState* script_state,
ScriptPromiseResolver* resolver,
VideoEncoderSupport* support,
VideoEncoderTraits::ParsedConfig* config) {
@@ -1003,22 +995,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(
@@ -1105,7 +1100,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 c54d0a91447717f014f44d36e004d9092e98f8bb..dbe40e69a276983bc2df5dcddd7b9b483d2534b1 100644
--- a/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
+++ b/third_party/blink/renderer/core/workers/threaded_worklet_test.cc
@@ -234,6 +234,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());
@@ -280,6 +281,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_;
@@ -403,4 +414,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 834aabc12fe0c43f69bb3a5fa669571c84847c6d..2431c406268a3631df157a24c3fd7accf184cccc 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"
@@ -80,7 +81,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
@@ -103,7 +104,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
@@ -115,14 +116,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>
@@ -133,7 +134,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>
@@ -154,7 +155,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.
@@ -181,7 +182,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_;
}
@@ -325,7 +326,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.
@@ -410,7 +411,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;
@@ -444,7 +445,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_;
@@ -453,6 +454,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;
@@ -479,6 +484,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,122 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <samuel.r.attard@gmail.com>
Date: Wed, 5 Oct 2022 06:03:23 +0000
Subject: build: set DTSDKBuild correctly when generating plist files
Currently we set DTSDKBuild to the version of the SDK used to build
Chromium. This value is supposed to be the build version (this is
what xcode sets it to for instance). We read this value out of the
SDK directly and use it instead.
Change-Id: Ieb7990f13095683ad8c026f027b2605ae39523a4
diff --git a/build/config/mac/mac_sdk.gni b/build/config/mac/mac_sdk.gni
index 7b1761607c853ae79619d6b872167a00a39f8236..c8e07ad62519236ead55c9b7ce1b1a4c3d5491af 100644
--- a/build/config/mac/mac_sdk.gni
+++ b/build/config/mac/mac_sdk.gni
@@ -40,6 +40,11 @@ declare_args() {
# will fail.
mac_sdk_official_version = "12.3"
+ # The SDK build version used when making official builds. This is a single
+ # exact version found at "System/Library/CoreServices/SystemVersion.plist"
+ # inside the SDK.
+ mac_sdk_official_build_version = "21E226"
+
# Production builds should use hermetic Xcode. If you want to do production
# builds with system Xcode to test new SDKs, set this.
# Don't set this on any bots.
@@ -101,11 +106,13 @@ if (use_system_xcode) {
find_sdk_args = [
"--print_sdk_path",
"--print_bin_path",
+ "--print_sdk_build",
mac_sdk_min,
]
find_sdk_lines =
exec_script("//build/mac/find_sdk.py", find_sdk_args, "list lines")
- mac_sdk_version = find_sdk_lines[2]
+ mac_sdk_version = find_sdk_lines[3]
+ mac_sdk_build_version = find_sdk_lines[2]
if (mac_sdk_path == "") {
mac_sdk_path = find_sdk_lines[0]
mac_bin_path = find_sdk_lines[1]
@@ -114,6 +121,7 @@ if (use_system_xcode) {
}
} else {
mac_sdk_version = mac_sdk_official_version
+ mac_sdk_build_version = mac_sdk_official_build_version
_dev = _hermetic_xcode_path + "/Contents/Developer"
_sdk = "MacOSX${mac_sdk_version}.sdk"
mac_sdk_path = _dev + "/Platforms/MacOSX.platform/Developer/SDKs/$_sdk"
diff --git a/build/config/mac/rules.gni b/build/config/mac/rules.gni
index 03073f830401c4891376a3b59e2e7a870e3d34b7..04d403054c1a83fcbbc70be7cfd239ecbec315d3 100644
--- a/build/config/mac/rules.gni
+++ b/build/config/mac/rules.gni
@@ -41,7 +41,7 @@ template("mac_info_plist") {
apple_info_plist(target_name) {
format = "xml1"
extra_substitutions = [
- "MAC_SDK_BUILD=$mac_sdk_version",
+ "MAC_SDK_BUILD=$mac_sdk_build_version",
"MAC_SDK_NAME=$mac_sdk_name$mac_sdk_version",
"MACOSX_DEPLOYMENT_TARGET=$mac_deployment_target",
"CHROMIUM_MIN_SYSTEM_VERSION=$mac_min_system_version",
diff --git a/build/mac/find_sdk.py b/build/mac/find_sdk.py
index d86f3109357a9246d570cb02992dc82552ba7c20..b2400c7e8c70957e364444f509880900ce3b641f 100755
--- a/build/mac/find_sdk.py
+++ b/build/mac/find_sdk.py
@@ -24,6 +24,7 @@ Sample Output:
from __future__ import print_function
import os
+import plistlib
import re
import subprocess
import sys
@@ -51,6 +52,9 @@ def main():
parser.add_option("--print_bin_path",
action="store_true", dest="print_bin_path", default=False,
help="Additionally print the path the toolchain bin dir.")
+ parser.add_option("--print_sdk_build",
+ action="store_true", dest="print_sdk_build", default=False,
+ help="Additionally print the build version of the SDK.")
options, args = parser.parse_args()
if len(args) != 1:
parser.error('Please specify a minimum SDK version')
@@ -80,20 +84,30 @@ def main():
if not sdks:
raise Exception('No %s+ SDK found' % min_sdk_version)
best_sdk = sorted(sdks, key=parse_version)[0]
+ sdk_name = 'MacOSX' + best_sdk + '.sdk'
+ sdk_path = os.path.join(sdk_dir, sdk_name)
if options.print_sdk_path:
- sdk_name = 'MacOSX' + best_sdk + '.sdk'
- print(os.path.join(sdk_dir, sdk_name))
+ print(sdk_path)
if options.print_bin_path:
bin_path = 'Toolchains/XcodeDefault.xctoolchain/usr/bin/'
print(os.path.join(dev_dir, bin_path))
- return best_sdk
+ if options.print_sdk_build:
+ system_version_plist = os.path.join(sdk_path,
+ 'System/Library/CoreServices/SystemVersion.plist')
+ with open(system_version_plist, 'rb') as f:
+ system_version_info = plistlib.load(f)
+ if 'ProductBuildVersion' not in system_version_info:
+ raise Exception('Failed to determine ProductBuildVersion' +
+ 'for SDK at path %s' % system_version_plist)
+ print(system_version_info['ProductBuildVersion'])
+
+ print(best_sdk)
if __name__ == '__main__':
if sys.platform != 'darwin':
raise Exception("This script only runs on Mac")
- print(main())
- sys.exit(0)
+ sys.exit(main())

View File

@@ -0,0 +1,116 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Harald Alvestrand <hta@chromium.org>
Date: Wed, 18 Jan 2023 08:02:48 +0000
Subject: Delete PeerConnectionHandler in PeerConnection finalizer
Also guard against removal of PC during PeerConnectionHandler
call that may cause garbage collection.
(cherry picked from commit 5066dd66309d884762e5fb9be04b59582893d09a)
Bug: chromium:1405256
Change-Id: I9adf7b219e2026e07ccc0868c1a85f3b35cd9d26
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4154578
Commit-Queue: Harald Alvestrand <hta@chromium.org>
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1091801}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4176372
Auto-Submit: Harald Alvestrand <hta@chromium.org>
Cr-Commit-Position: refs/branch-heads/5481@{#418}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index bcb9e9f13cfa525499023e369cefe0ed23f47abc..cf01e7144fc2901c88f320ea7b1c093dfb6ab8b1 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -819,10 +819,11 @@ RTCPeerConnection::~RTCPeerConnection() {
}
void RTCPeerConnection::Dispose() {
- // Promptly clears the handler's pointer to |this|
+ // Promptly clears the handler
// so that content/ doesn't access it in a lazy sweeping phase.
+ // Other references to the handler use a weak pointer, preventing access.
if (peer_handler_) {
- peer_handler_->CloseAndUnregister();
+ peer_handler_.reset();
}
}
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
index 7662f2cda29b6265705a4f83dbf76ccaf50ab576..48bd8a4eee90b07a38c7f09f260da30c9e7e34bc 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
@@ -771,6 +771,8 @@ class RTCPeerConnectionHandler::WebRtcSetDescriptionObserverImpl
if (handler_) {
handler_->OnModifySctpTransport(std::move(states.sctp_transport_state));
}
+ // Since OnSessionDescriptionsUpdated can fire events, it may cause
+ // garbage collection. Ensure that handler_ is still valid.
if (handler_) {
handler_->OnModifyTransceivers(
states.signaling_state, std::move(states.transceiver_states),
@@ -1128,6 +1130,8 @@ bool RTCPeerConnectionHandler::Initialize(
CHECK(!initialize_called_);
initialize_called_ = true;
+ // Prevent garbage collection of client_ during processing.
+ auto* client_on_stack = client_;
peer_connection_tracker_ = PeerConnectionTracker::From(*frame);
configuration_ = server_configuration;
@@ -1165,8 +1169,8 @@ bool RTCPeerConnectionHandler::Initialize(
peer_connection_tracker_->RegisterPeerConnection(this, configuration_,
options, frame_);
}
-
- return true;
+ // Gratuitous usage of client_on_stack to prevent compiler errors.
+ return !!client_on_stack;
}
bool RTCPeerConnectionHandler::InitializeForTest(
@@ -2229,9 +2233,11 @@ void RTCPeerConnectionHandler::OnSessionDescriptionsUpdated(
pending_remote_description,
std::unique_ptr<webrtc::SessionDescriptionInterface>
current_remote_description) {
+ // Prevent garbage collection of client_ during processing.
+ auto* client_on_stack = client_;
if (!client_ || is_closed_)
return;
- client_->DidChangeSessionDescriptions(
+ client_on_stack->DidChangeSessionDescriptions(
pending_local_description
? CreateWebKitSessionDescription(pending_local_description.get())
: nullptr,
@@ -2552,8 +2558,12 @@ void RTCPeerConnectionHandler::OnIceCandidate(const String& sdp,
int sdp_mline_index,
int component,
int address_family) {
+ // In order to ensure that the RTCPeerConnection is not garbage collected
+ // from under the function, we keep a pointer to it on the stack.
+ auto* client_on_stack = client_;
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateImpl");
+ // This line can cause garbage collection.
auto* platform_candidate = MakeGarbageCollected<RTCIceCandidatePlatform>(
sdp, sdp_mid, sdp_mline_index);
if (peer_connection_tracker_) {
@@ -2573,7 +2583,7 @@ void RTCPeerConnectionHandler::OnIceCandidate(const String& sdp,
}
}
if (!is_closed_)
- client_->DidGenerateICECandidate(platform_candidate);
+ client_on_stack->DidGenerateICECandidate(platform_candidate);
}
void RTCPeerConnectionHandler::OnIceCandidateError(
@@ -2585,7 +2595,6 @@ void RTCPeerConnectionHandler::OnIceCandidateError(
const String& error_text) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateError");
-
if (peer_connection_tracker_) {
peer_connection_tracker_->TrackIceCandidateError(
this, address, port, host_candidate, url, error_code, error_text);

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 30e5b6bfb365a738d72fdab31fee0d657cbc26c7..e77370db8ae1115a9e99e658364b14efe8d27cd3 100644
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
@@ -644,16 +644,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 477dfc3a5384643f46804966888afa549769d39d..6a31cf39f3d1a03981ff438c9c1463f168f53423 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"
@@ -252,6 +253,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);
@@ -320,7 +326,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,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Wed, 7 Dec 2022 20:35:15 +0000
Subject: Mojo: Fix potential UAF in IPC Channel
(cherry picked from commit 120b4b05ac7eaa9024f677394aa663c2702174ce)
Fixed: 1394692
Change-Id: I1753b79eb6e9230ebb663eca47295d81dd859068
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4066994
Commit-Queue: Ken Rockot <rockot@google.com>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1077742}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4085806
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Ken Rockot <rockot@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5359@{#1115}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc
index a0bd86951a20cf2d60c7805a3a7fa687d66ca329..eb8fa358b0a72eea2e294c531549da5fc81f394c 100644
--- a/ipc/ipc_mojo_bootstrap.cc
+++ b/ipc/ipc_mojo_bootstrap.cc
@@ -629,9 +629,12 @@ class ChannelAssociatedGroupController
void OnSyncMessageEventReady() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- scoped_refptr<Endpoint> keepalive(this);
+ // SUBTLE: The order of these scoped_refptrs matters.
+ // `controller_keepalive` MUST outlive `keepalive` because the Endpoint
+ // holds raw pointer to the AssociatedGroupController.
scoped_refptr<AssociatedGroupController> controller_keepalive(
controller_.get());
+ scoped_refptr<Endpoint> keepalive(this);
base::AutoLock locker(controller_->lock_);
bool more_to_process = false;
if (!sync_messages_.empty()) {

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,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Vasiliy Telezhnikov <vasilyt@chromium.org>
Date: Mon, 16 Jan 2023 17:43:34 +0000
Subject: Remove NUM_COMMAND_BUFFER_NAMESPACES from SyncToken.mojom
Mojo validates input for allowed values, NUM_COMMAND_BUFFER_NAMESPACES
is not valid value to send over ipc and is used only to know maximum
value in code.
Bug: 1406115
Change-Id: I8e5c3b6b2a9a9206fbeb377b27ceb1242a4f54e2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4167409
Reviewed-by: danakj <danakj@chromium.org>
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1093100}
diff --git a/gpu/ipc/common/sync_token.mojom b/gpu/ipc/common/sync_token.mojom
index 7c957007e3a377bd1e9969f14d9edc80c7d76645..b24017647aa6a11080580dd48e4c3d1cd79d1cf3 100644
--- a/gpu/ipc/common/sync_token.mojom
+++ b/gpu/ipc/common/sync_token.mojom
@@ -11,9 +11,7 @@ enum CommandBufferNamespace {
GPU_IO,
IN_PROCESS,
MOJO,
- MOJO_LOCAL,
-
- NUM_COMMAND_BUFFER_NAMESPACES
+ MOJO_LOCAL
};
// See gpu/command_buffer/common/sync_token.h

View File

@@ -0,0 +1,103 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Victor Vasiliev <vasilvv@chromium.org>
Date: Thu, 12 Jan 2023 22:03:48 +0000
Subject: Ensure clean destruction of network::WebTransport
Once the destruction of the object begins, we should not process any
callbacks, nor should we attempt to reset the streams on a connection
that is already being closed.
(cherry picked from commit 57c54ae221d60e9f9394d7ee69634d66c9cd26f3)
Bug: 1376354
Change-Id: Ib49e0ce0b177062cccd0e52368782e291cf8166c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4117501
Reviewed-by: Eric Orth <ericorth@chromium.org>
Commit-Queue: Victor Vasiliev <vasilvv@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1085965}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4139783
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Cr-Commit-Position: refs/branch-heads/5359@{#1326}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/services/network/web_transport.cc b/services/network/web_transport.cc
index fd62b83d43052d9d588a211b59e46a6c25ffeb76..534954181abcd7c4cf11eade64a2aa97c62785cc 100644
--- a/services/network/web_transport.cc
+++ b/services/network/web_transport.cc
@@ -177,7 +177,7 @@ class WebTransport::Stream final {
~Stream() {
auto* stream = incoming_ ? incoming_.get() : outgoing_.get();
- if (!stream) {
+ if (!stream || transport_->closing_ || transport_->torn_down_) {
return;
}
stream->MaybeResetDueToStreamObjectGone();
@@ -399,7 +399,10 @@ WebTransport::WebTransport(
transport_->Connect();
}
-WebTransport::~WebTransport() = default;
+WebTransport::~WebTransport() {
+ // Ensure that we ignore all callbacks while mid-destruction.
+ torn_down_ = true;
+}
void WebTransport::SendDatagram(base::span<const uint8_t> data,
base::OnceCallback<void(bool)> callback) {
diff --git a/services/network/web_transport_unittest.cc b/services/network/web_transport_unittest.cc
index ffac5c19f9d154b91eb6aeac1e19a62277e4e7e8..46deb561091232fe64950be01e9157c8d891f111 100644
--- a/services/network/web_transport_unittest.cc
+++ b/services/network/web_transport_unittest.cc
@@ -611,6 +611,51 @@ TEST_F(WebTransportTest, EchoOnUnidirectionalStreams) {
EXPECT_EQ(0u, resets_sent.size());
}
+TEST_F(WebTransportTest, DeleteClientWithStreamsOpen) {
+ base::RunLoop run_loop_for_handshake;
+ mojo::PendingRemote<mojom::WebTransportHandshakeClient> handshake_client;
+ TestHandshakeClient test_handshake_client(
+ handshake_client.InitWithNewPipeAndPassReceiver(),
+ run_loop_for_handshake.QuitClosure());
+
+ CreateWebTransport(GetURL("/echo"),
+ url::Origin::Create(GURL("https://example.org/")),
+ std::move(handshake_client));
+
+ run_loop_for_handshake.Run();
+
+ ASSERT_TRUE(test_handshake_client.has_seen_connection_establishment());
+
+ TestClient client(test_handshake_client.PassClientReceiver());
+ mojo::Remote<mojom::WebTransport> transport_remote(
+ test_handshake_client.PassTransport());
+
+ constexpr int kNumStreams = 10;
+ auto writable_for_outgoing =
+ std::make_unique<mojo::ScopedDataPipeProducerHandle[]>(kNumStreams);
+ for (int i = 0; i < kNumStreams; i++) {
+ const MojoCreateDataPipeOptions options = {
+ sizeof(options), MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1, 4 * 1024};
+ mojo::ScopedDataPipeConsumerHandle readable_for_outgoing;
+ ASSERT_EQ(MOJO_RESULT_OK,
+ mojo::CreateDataPipe(&options, writable_for_outgoing[i],
+ readable_for_outgoing));
+ base::RunLoop run_loop_for_stream_creation;
+ bool stream_created;
+ transport_remote->CreateStream(
+ std::move(readable_for_outgoing),
+ /*writable=*/{},
+ base::BindLambdaForTesting([&](bool b, uint32_t /*id*/) {
+ stream_created = b;
+ run_loop_for_stream_creation.Quit();
+ }));
+ run_loop_for_stream_creation.Run();
+ ASSERT_TRUE(stream_created);
+ }
+
+ // Keep the streams open so that they are closed via destructor.
+}
+
// crbug.com/1129847: disabled because it is flaky.
TEST_F(WebTransportTest, DISABLED_EchoOnBidirectionalStream) {
base::RunLoop run_loop_for_handshake;

View File

@@ -0,0 +1,132 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: David Yeung <dayeung@chromium.org>
Date: Thu, 8 Dec 2022 17:56:44 +0000
Subject: Fix UaF in ui::DropTargetEvent::DropTargetEvent.
There is an async operation in WebContentsViewAura that uses a ui::DropTargetEvent. DropTargetEvent has a pointer to OSExchangeData which gets destroyed before the async operation is called. This triggers the UaF because the operation attempts to reference a freed object (OSExchangeData).
Fix is for WebContentsViewAura::DragUpdatedCallback to use a DropMetadata struct instead of a ui::DropTargetEvent. This is the same pattern used by other callbacks in WebContentsViewAura.
(cherry picked from commit 9f4b5761c546a118b7187c0c7ddcb9ee5756f32c)
Bug: 1392661
Change-Id: I3c62a7473ef9b6cdd223f75fbda50671f539f9eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4070787
Reviewed-by: Avi Drissman <avi@chromium.org>
Commit-Queue: David Yeung <dayeung@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1078218}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4085256
Cr-Commit-Position: refs/branch-heads/5359@{#1125}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index 6792e64b2f0f4a5080beb57804f861d8297524d2..aae78786a7fd9290fb1e79e3417f29662d58ed0d 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -348,6 +348,7 @@ aura::Window* GetHostWindow(aura::Window* window) {
WebContentsViewAura::DropMetadata::DropMetadata(
const ui::DropTargetEvent& event) {
localized_location = event.location_f();
+ root_location = event.root_location_f();
source_operations = event.source_operations();
flags = event.flags();
}
@@ -1444,7 +1445,7 @@ void WebContentsViewAura::OnDragEntered(const ui::DropTargetEvent& event) {
}
void WebContentsViewAura::DragUpdatedCallback(
- ui::DropTargetEvent event,
+ DropMetadata drop_metadata,
std::unique_ptr<DropData> drop_data,
base::WeakPtr<RenderWidgetHostViewBase> target,
absl::optional<gfx::PointF> transformed_pt) {
@@ -1465,24 +1466,23 @@ void WebContentsViewAura::DragUpdatedCallback(
aura::Window* root_window = GetNativeView()->GetRootWindow();
aura::client::ScreenPositionClient* screen_position_client =
aura::client::GetScreenPositionClient(root_window);
- gfx::PointF screen_pt = event.root_location_f();
+ gfx::PointF screen_pt = drop_metadata.root_location;
if (screen_position_client)
screen_position_client->ConvertPointToScreen(root_window, &screen_pt);
if (target_rwh != current_rwh_for_drag_.get()) {
if (current_rwh_for_drag_) {
- gfx::PointF transformed_leave_point = event.location_f();
+ gfx::PointF transformed_leave_point = drop_metadata.localized_location;
static_cast<RenderWidgetHostViewBase*>(
web_contents_->GetRenderWidgetHostView())
->TransformPointToCoordSpaceForView(
- event.location_f(),
+ drop_metadata.localized_location,
static_cast<RenderWidgetHostViewBase*>(
current_rwh_for_drag_->GetView()),
&transformed_leave_point);
current_rwh_for_drag_->DragTargetDragLeave(transformed_leave_point,
screen_pt);
}
- DropMetadata drop_metadata(event);
DragEnteredCallback(drop_metadata, std::move(drop_data), target,
transformed_pt);
}
@@ -1493,10 +1493,11 @@ void WebContentsViewAura::DragUpdatedCallback(
DCHECK(transformed_pt.has_value());
blink::DragOperationsMask op_mask =
- ConvertToDragOperationsMask(event.source_operations());
+ ConvertToDragOperationsMask(drop_metadata.source_operations);
target_rwh->DragTargetDragOver(
transformed_pt.value(), screen_pt, op_mask,
- ui::EventFlagsToWebEventModifiers(event.flags()), base::DoNothing());
+ ui::EventFlagsToWebEventModifiers(drop_metadata.flags),
+ base::DoNothing());
if (drag_dest_delegate_)
drag_dest_delegate_->OnDragOver();
@@ -1506,7 +1507,6 @@ aura::client::DragUpdateInfo WebContentsViewAura::OnDragUpdated(
const ui::DropTargetEvent& event) {
if (web_contents_->ShouldIgnoreInputEvents())
return aura::client::DragUpdateInfo();
-
aura::client::DragUpdateInfo drag_info;
auto* focused_frame = web_contents_->GetFocusedFrame();
if (focused_frame && !web_contents_->GetBrowserContext()->IsOffTheRecord()) {
@@ -1517,13 +1517,13 @@ aura::client::DragUpdateInfo WebContentsViewAura::OnDragUpdated(
std::unique_ptr<DropData> drop_data = std::make_unique<DropData>();
// Calling this here as event.data might become invalid inside the callback.
PrepareDropData(drop_data.get(), event.data());
-
+ DropMetadata drop_metadata(event);
web_contents_->GetInputEventRouter()
->GetRenderWidgetHostAtPointAsynchronously(
web_contents_->GetRenderViewHost()->GetWidget()->GetView(),
event.location_f(),
base::BindOnce(&WebContentsViewAura::DragUpdatedCallback,
- weak_ptr_factory_.GetWeakPtr(), event,
+ weak_ptr_factory_.GetWeakPtr(), drop_metadata,
std::move(drop_data)));
drag_info.drag_operation = static_cast<int>(current_drag_op_);
diff --git a/content/browser/web_contents/web_contents_view_aura.h b/content/browser/web_contents/web_contents_view_aura.h
index 17745664eda9832da61ec0150fe5085776c9c7bc..aaa42c930ef04d8f0d20d65fbb22d5fd06ba2d48 100644
--- a/content/browser/web_contents/web_contents_view_aura.h
+++ b/content/browser/web_contents/web_contents_view_aura.h
@@ -84,6 +84,10 @@ class CONTENT_EXPORT WebContentsViewAura
// Location local to WebContentsViewAura.
gfx::PointF localized_location;
+
+ // Root location of the drop target event.
+ gfx::PointF root_location;
+
// The supported DnD operation of the source. A bitmask of
// ui::mojom::DragOperations.
int source_operations;
@@ -263,7 +267,7 @@ class CONTENT_EXPORT WebContentsViewAura
std::unique_ptr<DropData> drop_data,
base::WeakPtr<RenderWidgetHostViewBase> target,
absl::optional<gfx::PointF> transformed_pt);
- void DragUpdatedCallback(ui::DropTargetEvent event,
+ void DragUpdatedCallback(DropMetadata drop_metadata,
std::unique_ptr<DropData> drop_data,
base::WeakPtr<RenderWidgetHostViewBase> target,
absl::optional<gfx::PointF> transformed_pt);

View File

@@ -0,0 +1,218 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Xiaocheng Hu <xiaochengh@chromium.org>
Date: Mon, 14 Nov 2022 20:01:38 +0000
Subject: Do not traverse directory symlinks when uploading folder
Previous patch crrev.com/c/3866767 removed symlink files when uploading
a folder. However, while the remaining files are themselves not
symlinks, they may be included as the result of traversing directory
symlink.
This patch further excludes such files by checking if any parent
directory is a symlink, all the way until the base directory (which is
the directory chosen for upload).
(cherry picked from commit 4fa830d8af6b2fb293219edeb39eebccfd322305)
Fixed: 1378997
Change-Id: I75a92df4cd50f9aba7824955a3de792583bc6154
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3997720
Reviewed-by: Austin Sullivan <asully@chromium.org>
Reviewed-by: Mason Freed <masonf@chromium.org>
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1067310}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4025427
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Srinivas Sista <srinivassista@chromium.org>
Owners-Override: Srinivas Sista <srinivassista@chromium.org>
Cr-Commit-Position: refs/branch-heads/5359@{#823}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/content/browser/web_contents/file_chooser_impl.cc b/content/browser/web_contents/file_chooser_impl.cc
index 1aa19f7a735b444f2c33d5084edcdd14e3c2f5c5..f4fa1afda64bf0606d28d4accaec56e2624133db 100644
--- a/content/browser/web_contents/file_chooser_impl.cc
+++ b/content/browser/web_contents/file_chooser_impl.cc
@@ -23,10 +23,24 @@ namespace content {
namespace {
+// Removes any file that is a symlink or is inside a directory symlink.
+// For |kUploadFolder| mode only. |base_dir| is the folder being uploaded.
std::vector<blink::mojom::FileChooserFileInfoPtr> RemoveSymlinks(
- std::vector<blink::mojom::FileChooserFileInfoPtr> files) {
+ std::vector<blink::mojom::FileChooserFileInfoPtr> files,
+ base::FilePath base_dir) {
+ DCHECK(!base_dir.empty());
auto new_end = base::ranges::remove_if(
- files, &base::IsLink,
+ files,
+ [&base_dir](const base::FilePath& file_path) {
+ if (base::IsLink(file_path))
+ return true;
+ for (base::FilePath path = file_path.DirName(); base_dir.IsParent(path);
+ path = path.DirName()) {
+ if (base::IsLink(path))
+ return true;
+ }
+ return false;
+ },
[](const auto& file) { return file->get_native_file()->file_path; });
files.erase(new_end, files.end());
return files;
@@ -78,7 +92,7 @@ void FileChooserImpl::FileSelectListenerImpl::FileSelected(
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
- base::BindOnce(&RemoveSymlinks, std::move(files)),
+ base::BindOnce(&RemoveSymlinks, std::move(files), base_dir),
base::BindOnce(&FileChooserImpl::FileSelected, owner_->GetWeakPtr(),
base_dir, mode));
}
diff --git a/content/browser/web_contents/file_chooser_impl_browsertest.cc b/content/browser/web_contents/file_chooser_impl_browsertest.cc
index f7519189638ece437c4285ddd490be3ea59e638d..7753f01681c21dc7afcb9ab124d301407874b76b 100644
--- a/content/browser/web_contents/file_chooser_impl_browsertest.cc
+++ b/content/browser/web_contents/file_chooser_impl_browsertest.cc
@@ -177,8 +177,8 @@ IN_PROC_BROWSER_TEST_F(FileChooserImplBrowserTest, UploadFolderWithSymlink) {
return;
}
- std::unique_ptr<FileChooserDelegate> delegate(
- new FileChooserDelegate({text_file, symlink_file}, base::OnceClosure()));
+ std::unique_ptr<FileChooserDelegate> delegate(new FileChooserDelegate(
+ {text_file, symlink_file}, folder_to_upload, base::OnceClosure()));
shell()->web_contents()->SetDelegate(delegate.get());
EXPECT_TRUE(ExecJs(shell(),
"(async () => {"
@@ -195,4 +195,45 @@ IN_PROC_BROWSER_TEST_F(FileChooserImplBrowserTest, UploadFolderWithSymlink) {
EvalJs(shell(), "document.getElementById('fileinput').files[0].name;"));
}
+// https://crbug.com/1378997
+IN_PROC_BROWSER_TEST_F(FileChooserImplBrowserTest, UploadFolderWithDirSymlink) {
+ EXPECT_TRUE(NavigateToURL(
+ shell(), GetTestUrl(".", "file_input_webkitdirectory.html")));
+
+ // The folder contains a regular file and a directory symbolic link.
+ // When uploading the folder, the symbolic link should not be followed.
+ 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_dir_symlink");
+
+ base::FilePath foo_file = folder_to_upload.AppendASCII("foo.txt");
+ base::FilePath dir_symlink = folder_to_upload.AppendASCII("symlink");
+ base::FilePath bar_file = dir_symlink.AppendASCII("bar.txt");
+
+ // Skip the test if symbolic links are not supported.
+ {
+ base::ScopedAllowBlockingForTesting allow_blocking;
+ if (!base::IsLink(dir_symlink))
+ return;
+ }
+
+ std::unique_ptr<FileChooserDelegate> delegate(new FileChooserDelegate(
+ {foo_file, bar_file}, folder_to_upload, 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(
+ "foo.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 c70d088bfd007e9a6cd9cfcb6f92b07b99653048..3e68311abfefc1e93ccc5c05de14137d8db0dc60 100644
--- a/content/test/content_browser_test_utils_internal.cc
+++ b/content/test/content_browser_test_utils_internal.cc
@@ -447,12 +447,16 @@ Shell* OpenPopup(const ToRenderFrameHost& opener,
}
FileChooserDelegate::FileChooserDelegate(std::vector<base::FilePath> files,
+ const base::FilePath& base_dir,
base::OnceClosure callback)
- : files_(std::move(files)), callback_(std::move(callback)) {}
+ : files_(std::move(files)),
+ base_dir_(base_dir),
+ callback_(std::move(callback)) {}
FileChooserDelegate::FileChooserDelegate(const base::FilePath& file,
base::OnceClosure callback)
: FileChooserDelegate(std::vector<base::FilePath>(1, file),
+ base::FilePath(),
std::move(callback)) {}
FileChooserDelegate::~FileChooserDelegate() = default;
@@ -461,6 +465,9 @@ void FileChooserDelegate::RunFileChooser(
RenderFrameHost* render_frame_host,
scoped_refptr<content::FileSelectListener> listener,
const blink::mojom::FileChooserParams& params) {
+ // |base_dir_| should be set for and only for |kUploadFolder| mode.
+ DCHECK(base_dir_.empty() ==
+ (params.mode != blink::mojom::FileChooserParams::Mode::kUploadFolder));
// Send the selected files to the renderer process.
std::vector<blink::mojom::FileChooserFileInfoPtr> files;
for (const auto& file : files_) {
@@ -468,7 +475,7 @@ void FileChooserDelegate::RunFileChooser(
blink::mojom::NativeFileInfo::New(file, std::u16string()));
files.push_back(std::move(file_info));
}
- listener->FileSelected(std::move(files), base::FilePath(), params.mode);
+ listener->FileSelected(std::move(files), base_dir_, params.mode);
params_ = params.Clone();
if (callback_)
diff --git a/content/test/content_browser_test_utils_internal.h b/content/test/content_browser_test_utils_internal.h
index 43c6aabc5414d0cc12fb5a03142e8b20e2a7fab3..bff69b028af40726107928868748ad0f19dc4459 100644
--- a/content/test/content_browser_test_utils_internal.h
+++ b/content/test/content_browser_test_utils_internal.h
@@ -179,7 +179,10 @@ class FileChooserDelegate : public WebContentsDelegate {
// 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);
+ // |base_dir| must be set to the folder being uploaded in |kUploadFolder|
+ // mode, and must be empty in all other modes.
FileChooserDelegate(std::vector<base::FilePath> files,
+ const base::FilePath& base_dir,
base::OnceClosure callback);
~FileChooserDelegate() override;
@@ -193,6 +196,7 @@ class FileChooserDelegate : public WebContentsDelegate {
private:
std::vector<base::FilePath> files_;
+ const base::FilePath base_dir_;
base::OnceClosure callback_;
blink::mojom::FileChooserParamsPtr params_;
};
diff --git a/content/test/data/file_chooser/dir_with_dir_symlink/foo.txt b/content/test/data/file_chooser/dir_with_dir_symlink/foo.txt
new file mode 100644
index 0000000000000000000000000000000000000000..257cc5642cb1a054f08cc83f2d943e56fd3ebe99
--- /dev/null
+++ b/content/test/data/file_chooser/dir_with_dir_symlink/foo.txt
@@ -0,0 +1 @@
+foo
diff --git a/content/test/data/file_chooser/dir_with_dir_symlink/symlink b/content/test/data/file_chooser/dir_with_dir_symlink/symlink
new file mode 120000
index 0000000000000000000000000000000000000000..10f6d1ab9ba9ede59b719d4ba1581588e172abb6
--- /dev/null
+++ b/content/test/data/file_chooser/dir_with_dir_symlink/symlink
@@ -0,0 +1 @@
+../linked_dir/
\ No newline at end of file
diff --git a/content/test/data/file_chooser/linked_dir/bar.txt b/content/test/data/file_chooser/linked_dir/bar.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5716ca5987cbf97d6bb54920bea6adde242d87e6
--- /dev/null
+++ b/content/test/data/file_chooser/linked_dir/bar.txt
@@ -0,0 +1 @@
+bar

View File

@@ -0,0 +1,55 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Austin Sullivan <asully@chromium.org>
Date: Tue, 11 Oct 2022 20:53:22 +0000
Subject: FSA: Block .url files in getFileHandle and getEntries
Fixed: 1354518
Change-Id: I663d4481ccc2047c49d7466bbfe9751e8c140edf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3945587
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Auto-Submit: Austin Sullivan <asully@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1057675}
diff --git a/content/browser/file_system_access/file_system_access_directory_handle_impl.cc b/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
index 7e673f903a71a309e8d92b966330875ef2772f84..13ce0b974268215f0e92ccedd2f56643c8a36679 100644
--- a/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
+++ b/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
@@ -444,9 +444,12 @@ bool IsShellIntegratedExtension(const base::FilePath::StringType& extension) {
// .lnk and .scf files may be used to execute arbitrary code (see
// https://nvd.nist.gov/vuln/detail/CVE-2010-2568 and
- // https://crbug.com/1227995, respectively).
+ // https://crbug.com/1227995, respectively). '.url' files can be used to read
+ // arbitrary files (see https://crbug.com/1307930 and
+ // https://crbug.com/1354518).
if (extension_lower == FILE_PATH_LITERAL("lnk") ||
- extension_lower == FILE_PATH_LITERAL("scf")) {
+ extension_lower == FILE_PATH_LITERAL("scf") ||
+ extension_lower == FILE_PATH_LITERAL("url")) {
return true;
}
diff --git a/content/browser/file_system_access/file_system_access_directory_handle_impl_unittest.cc b/content/browser/file_system_access/file_system_access_directory_handle_impl_unittest.cc
index 606e34473296199317747fa949158f402b163ec0..9dd03ca412fdc69d7e6bb18b08a157ac9b69bf13 100644
--- a/content/browser/file_system_access/file_system_access_directory_handle_impl_unittest.cc
+++ b/content/browser/file_system_access/file_system_access_directory_handle_impl_unittest.cc
@@ -150,6 +150,7 @@ TEST_F(FileSystemAccessDirectoryHandleImplTest, IsSafePathComponent) {
"My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
"a\\a",
"a.lnk",
+ "a.url",
"a/a",
"C:\\",
"C:/",
@@ -205,8 +206,8 @@ TEST_F(FileSystemAccessDirectoryHandleImplTest, GetEntries) {
constexpr const char* kSafeNames[] = {"a", "a.txt", "My Computer", "lnk.txt",
"a.local"};
constexpr const char* kUnsafeNames[] = {
- "con", "con.zip", "NUL", "a.",
- "a\"a", "a . .", "a.lnk", "My Computer.{a}",
+ "con", "con.zip", "NUL", "a.", "a\"a", "a . .",
+ "a.lnk", "My Computer.{a}", "a.url",
};
for (const char* name : kSafeNames) {
ASSERT_TRUE(base::WriteFile(dir_.GetPath().AppendASCII(name), "data"))

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 7e097b4eb6e9085be73ceb7fd84a4588baf64471..3908909d04f5b6cf4a9be4a3a3e004c3775a3d42 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
@@ -85,7 +85,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,156 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ryan Manuel <ryanm@cypress.io>
Date: Thu, 4 Aug 2022 22:37:01 -0500
Subject: Create browser v8 snapshot file name fuse
By default, chromium sets up one v8 snapshot to be used in all v8 contexts. This patch allows consumers
to have a dedicated browser process v8 snapshot defined by the file `browser_v8_context_snapshot.bin`.
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
index 328f8b800c36544f7906536416ac61dc87cc45d3..2f973efcf3e38edcc74060929339fc21bdf0aa3b 100644
--- a/content/app/content_main_runner_impl.cc
+++ b/content/app/content_main_runner_impl.cc
@@ -37,6 +37,7 @@
#include "base/process/memory.h"
#include "base/process/process.h"
#include "base/process/process_handle.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/task/thread_pool/thread_pool_instance.h"
@@ -232,8 +233,13 @@ std::string GetSnapshotDataDescriptor(const base::CommandLine& command_line) {
#endif
-void LoadV8SnapshotFile(const base::CommandLine& command_line) {
+void LoadV8SnapshotFile(const raw_ptr<ContentMainDelegate> delegate, const base::CommandLine& command_line) {
const gin::V8SnapshotFileType snapshot_type = GetSnapshotType(command_line);
+ base::StringPiece browser_v8_snapshot_file_name = delegate->GetBrowserV8SnapshotFilename();
+ if (!browser_v8_snapshot_file_name.empty()) {
+ gin::V8Initializer::LoadV8SnapshotFromFileName(browser_v8_snapshot_file_name, snapshot_type);
+ return;
+ }
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
base::FileDescriptorStore& file_descriptor_store =
base::FileDescriptorStore::GetInstance();
@@ -262,11 +268,12 @@ bool ShouldLoadV8Snapshot(const base::CommandLine& command_line,
#endif // V8_USE_EXTERNAL_STARTUP_DATA
-void LoadV8SnapshotIfNeeded(const base::CommandLine& command_line,
+void LoadV8SnapshotIfNeeded(const raw_ptr<ContentMainDelegate> delegate,
+ const base::CommandLine& command_line,
const std::string& process_type) {
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
if (ShouldLoadV8Snapshot(command_line, process_type))
- LoadV8SnapshotFile(command_line);
+ LoadV8SnapshotFile(delegate, command_line);
#endif // V8_USE_EXTERNAL_STARTUP_DATA
}
@@ -917,7 +924,7 @@ int ContentMainRunnerImpl::Initialize(ContentMainParams params) {
return TerminateForFatalInitializationError();
#endif // BUILDFLAG(IS_ANDROID) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE)
- LoadV8SnapshotIfNeeded(command_line, process_type);
+ LoadV8SnapshotIfNeeded(delegate_, command_line, process_type);
blink::TrialTokenValidator::SetOriginTrialPolicyGetter(
base::BindRepeating([]() -> blink::OriginTrialPolicy* {
diff --git a/content/public/app/content_main_delegate.cc b/content/public/app/content_main_delegate.cc
index ce6b8b454d0cc57ec4de81c7a19b5e0f0087a162..c421d3b5bc02b702e89c714d3d521207cbca156b 100644
--- a/content/public/app/content_main_delegate.cc
+++ b/content/public/app/content_main_delegate.cc
@@ -5,6 +5,7 @@
#include "content/public/app/content_main_delegate.h"
#include "base/check.h"
+#include "base/strings/string_piece.h"
#include "build/build_config.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
@@ -55,6 +56,10 @@ ContentMainDelegate::CreateVariationsIdsProvider() {
return nullptr;
}
+base::StringPiece ContentMainDelegate::GetBrowserV8SnapshotFilename() {
+ return base::StringPiece();
+}
+
ContentClient* ContentMainDelegate::CreateContentClient() {
return new ContentClient();
}
diff --git a/content/public/app/content_main_delegate.h b/content/public/app/content_main_delegate.h
index f81430b564a3cf44c2168e18c4c53c6629353d75..34a5531cd33b439114a796adc71af7251b6b1f81 100644
--- a/content/public/app/content_main_delegate.h
+++ b/content/public/app/content_main_delegate.h
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/strings/string_piece.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/common/main_function_params.h"
@@ -149,6 +150,8 @@ class CONTENT_EXPORT ContentMainDelegate {
virtual bool ShouldHandleConsoleControlEvents();
#endif
+ virtual base::StringPiece GetBrowserV8SnapshotFilename();
+
protected:
friend class ContentClientCreator;
friend class ContentClientInitializer;
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index 34a65998cbaa22241fd7c6cc60d8ab01982ca3ce..68c12e9bb1f334d6fec050018da8bc0a6db4a850 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -512,8 +512,7 @@ void V8Initializer::GetV8ExternalSnapshotData(const char** snapshot_data_out,
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
-// static
-void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
+void V8Initializer::LoadV8SnapshotFromFileName(base::StringPiece file_name, V8SnapshotFileType snapshot_file_type) {
if (g_mapped_snapshot) {
// TODO(crbug.com/802962): Confirm not loading different type of snapshot
// files in a process.
@@ -522,10 +521,17 @@ void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
base::MemoryMappedFile::Region file_region;
base::File file =
- OpenV8File(GetSnapshotFileName(snapshot_file_type), &file_region);
+ OpenV8File(file_name.data(), &file_region);
LoadV8SnapshotFromFile(std::move(file), &file_region, snapshot_file_type);
}
+// static
+void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
+ const char* file_name = GetSnapshotFileName(snapshot_file_type);
+
+ LoadV8SnapshotFromFileName(file_name, snapshot_file_type);
+}
+
// static
void V8Initializer::LoadV8SnapshotFromFile(
base::File snapshot_file,
diff --git a/gin/v8_initializer.h b/gin/v8_initializer.h
index 13a120c7fe8e69a44793473f3124c33d572a07a3..acb294780873c1d84546eb2b9acc00f86838361d 100644
--- a/gin/v8_initializer.h
+++ b/gin/v8_initializer.h
@@ -9,6 +9,7 @@
#include "base/files/file.h"
#include "base/files/memory_mapped_file.h"
+#include "base/strings/string_piece.h"
#include "build/build_config.h"
#include "gin/array_buffer.h"
#include "gin/gin_export.h"
@@ -42,6 +43,7 @@ class GIN_EXPORT V8Initializer {
int* snapshot_size_out);
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
+ static void LoadV8SnapshotFromFileName(base::StringPiece file_name, V8SnapshotFileType snapshot_file_type);
// Load V8 snapshot from default resources, if they are available.
static void LoadV8Snapshot(
V8SnapshotFileType snapshot_file_type = V8SnapshotFileType::kDefault);

View File

@@ -0,0 +1,59 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kyrylo Hrechykhin <khrechykhin@microsoft.com>
Date: Thu, 6 Oct 2022 18:30:53 +0200
Subject: fix: on-screen-keyboard hides on input blur in webview
Changes introduced by this patch fix issue where OSK does not hide on
input rendered inside webview is blurred. This patch should be removed
when proper fix in chromium repo is available.
Note: the issue still occurs if input rendered in webview blurred due
to touch outside of webview. It is caused by webview implementation
details. Specificaly due to webview has its own tree nodes and focused
node does not change in this case.
chromium-bug: https://crbug.com/1369605
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
index c56d5c06ca3eb5e2c11bd1af00a8667bfa422dc9..bccc940958180481947a5a5ee82562bd99d28b78 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.cc
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
@@ -985,6 +985,12 @@ RenderWidgetHostViewChildFrame::DidUpdateVisualProperties(
return viz::ScopedSurfaceIdAllocator(std::move(allocation_task));
}
+void RenderWidgetHostViewChildFrame::FocusedNodeChanged(
+ bool is_editable_node,
+ const gfx::Rect& node_bounds_in_screen) {
+ NOTREACHED();
+}
+
ui::TextInputType RenderWidgetHostViewChildFrame::GetTextInputType() const {
if (!text_input_manager_)
return ui::TEXT_INPUT_TYPE_NONE;
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.h b/content/browser/renderer_host/render_widget_host_view_child_frame.h
index 457dabe428e84230b2e831e9281feee06e7c8e76..9436d55b390ac6fa16398efebad0a87beef6e959 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.h
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.h
@@ -178,6 +178,8 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
void DisableAutoResize(const gfx::Size& new_size) override;
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(
const cc::RenderFrameMetadata& metadata) override;
+ void FocusedNodeChanged(bool is_editable_node,
+ const gfx::Rect& node_bounds_in_screen) override;
// RenderFrameMetadataProvider::Observer implementation.
void OnRenderFrameMetadataChangedBeforeActivation(
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 8982a2a4d2be23e56472b17e9d59e289e8255336..92f73106ba8c9559281add6fe7a2f2a613ca3cdc 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -7891,7 +7891,7 @@ void WebContentsImpl::OnFocusedElementChangedInFrame(
"WebContentsImpl::OnFocusedElementChangedInFrame",
"render_frame_host", frame);
RenderWidgetHostViewBase* root_view =
- static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView());
+ static_cast<RenderWidgetHostViewBase*>(GetTopLevelRenderWidgetHostView());
if (!root_view || !frame->GetView())
return;
// Convert to screen coordinates from window coordinates by adding the

View File

@@ -0,0 +1,536 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Thu, 10 Nov 2022 03:24:17 +0000
Subject: Mojo: Disable sync call interrupts in the browser
This changes the default Mojo sync call behavior in the browser process
to prevent any blocking sync calls from being interrupted by other
incoming sync IPC dispatches.
(cherry picked from commit b6f921260e0e763db7a72de9c7a3f0f78a99f21f)
Bug: 1376099
Change-Id: I53681ef379fdd3c2bfc37d7e16b3de17acad5d20
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3989408
Commit-Queue: Ken Rockot <rockot@google.com>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1065369}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4018257
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Auto-Submit: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Ken Rockot <rockot@google.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5359@{#719}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
index 2f973efcf3e38edcc74060929339fc21bdf0aa3b..f8f72678fd8bbcf857bf09176b8b6388d35e3605 100644
--- a/content/app/content_main_runner_impl.cc
+++ b/content/app/content_main_runner_impl.cc
@@ -92,6 +92,7 @@
#include "media/media_buildflags.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
+#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/system/dynamic_library_support.h"
#include "mojo/public/cpp/system/invitation.h"
@@ -1073,6 +1074,11 @@ int ContentMainRunnerImpl::RunBrowser(MainFunctionParams main_params,
if (is_browser_main_loop_started_)
return -1;
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSingleProcess)) {
+ mojo::SyncCallRestrictions::DisableSyncCallInterrupts();
+ }
+
if (!mojo_ipc_support_) {
const auto invoked_in = main_params.ui_task
? InvokedIn::kBrowserProcessUnderTest
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc
index eb8fa358b0a72eea2e294c531549da5fc81f394c..8c13ef236ba6f7cf05584cffba522a3cb54536c9 100644
--- a/ipc/ipc_mojo_bootstrap.cc
+++ b/ipc/ipc_mojo_bootstrap.cc
@@ -16,13 +16,15 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/check_op.h"
+#include "base/containers/circular_deque.h"
#include "base/containers/contains.h"
-#include "base/containers/queue.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/no_destructor.h"
+#include "base/ranges/algorithm.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
+#include "base/synchronization/waitable_event.h"
#include "base/task/common/task_annotator.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
@@ -48,6 +50,7 @@
#include "mojo/public/cpp/bindings/pipe_control_message_proxy.h"
#include "mojo/public/cpp/bindings/sequence_local_sync_event_watcher.h"
#include "mojo/public/cpp/bindings/tracing_helpers.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace IPC {
@@ -466,6 +469,11 @@ class ChannelAssociatedGroupController
return *this;
}
+ bool HasRequestId(uint64_t request_id) {
+ return !value_.IsNull() && value_.version() >= 1 &&
+ value_.header_v1()->request_id == request_id;
+ }
+
mojo::Message& value() { return value_; }
private:
@@ -557,10 +565,15 @@ class ChannelAssociatedGroupController
sync_watcher_.reset();
}
- uint32_t EnqueueSyncMessage(MessageWrapper message) {
+ absl::optional<uint32_t> EnqueueSyncMessage(MessageWrapper message) {
controller_->lock_.AssertAcquired();
+ if (exclusive_wait_ && exclusive_wait_->TryFulfillingWith(message)) {
+ exclusive_wait_ = nullptr;
+ return absl::nullopt;
+ }
+
uint32_t id = GenerateSyncMessageId();
- sync_messages_.emplace(id, std::move(message));
+ sync_messages_.emplace_back(id, std::move(message));
SignalSyncMessageEvent();
return id;
}
@@ -577,7 +590,7 @@ class ChannelAssociatedGroupController
if (sync_messages_.empty() || sync_messages_.front().first != id)
return MessageWrapper();
MessageWrapper message = std::move(sync_messages_.front().second);
- sync_messages_.pop();
+ sync_messages_.pop_front();
return message;
}
@@ -607,10 +620,38 @@ class ChannelAssociatedGroupController
return sync_watcher_->SyncWatch(&should_stop);
}
+ MessageWrapper WaitForIncomingSyncReply(uint64_t request_id) {
+ absl::optional<ExclusiveSyncWait> wait;
+ {
+ base::AutoLock lock(controller_->lock_);
+ for (auto& [id, message] : sync_messages_) {
+ if (message.HasRequestId(request_id)) {
+ return std::move(message);
+ }
+ }
+
+ DCHECK(!exclusive_wait_);
+ wait.emplace(request_id);
+ exclusive_wait_ = &wait.value();
+ }
+
+ wait->event.Wait();
+ return std::move(wait->message);
+ }
+
bool SyncWatchExclusive(uint64_t request_id) override {
- // We don't support exclusive waits on Channel-associated interfaces.
- NOTREACHED();
- return false;
+ MessageWrapper message = WaitForIncomingSyncReply(request_id);
+ if (message.value().IsNull() || !client_) {
+ return false;
+ }
+
+ if (!client_->HandleIncomingMessage(&message.value())) {
+ base::AutoLock locker(controller_->lock_);
+ controller_->RaiseError();
+ return false;
+ }
+
+ return true;
}
void RegisterExternalSyncWaiter(uint64_t request_id) override {}
@@ -624,6 +665,9 @@ class ChannelAssociatedGroupController
DCHECK(closed_);
DCHECK(peer_closed_);
DCHECK(!sync_watcher_);
+ if (exclusive_wait_) {
+ exclusive_wait_->event.Signal();
+ }
}
void OnSyncMessageEventReady() {
@@ -640,7 +684,7 @@ class ChannelAssociatedGroupController
if (!sync_messages_.empty()) {
MessageWrapper message_wrapper =
std::move(sync_messages_.front().second);
- sync_messages_.pop();
+ sync_messages_.pop_front();
bool dispatch_succeeded;
mojo::InterfaceEndpointClient* client = client_;
@@ -688,6 +732,28 @@ class ChannelAssociatedGroupController
return id;
}
+ // Tracks the state of a pending sync wait which excludes all other incoming
+ // IPC on the waiting thread.
+ struct ExclusiveSyncWait {
+ explicit ExclusiveSyncWait(uint64_t request_id)
+ : request_id(request_id) {}
+ ~ExclusiveSyncWait() = default;
+
+ bool TryFulfillingWith(MessageWrapper& wrapper) {
+ if (!wrapper.HasRequestId(request_id)) {
+ return false;
+ }
+
+ message = std::move(wrapper);
+ event.Signal();
+ return true;
+ }
+
+ uint64_t request_id;
+ base::WaitableEvent event;
+ MessageWrapper message;
+ };
+
const raw_ptr<ChannelAssociatedGroupController> controller_;
const mojo::InterfaceId id_;
@@ -699,7 +765,8 @@ class ChannelAssociatedGroupController
raw_ptr<mojo::InterfaceEndpointClient> client_ = nullptr;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
std::unique_ptr<mojo::SequenceLocalSyncEventWatcher> sync_watcher_;
- base::queue<std::pair<uint32_t, MessageWrapper>> sync_messages_;
+ base::circular_deque<std::pair<uint32_t, MessageWrapper>> sync_messages_;
+ ExclusiveSyncWait* exclusive_wait_ = nullptr;
uint32_t next_sync_message_id_ = 0;
};
@@ -932,12 +999,15 @@ class ChannelAssociatedGroupController
// sync message queue. If the endpoint was blocking, it will dequeue the
// message and dispatch it. Otherwise the posted |AcceptSyncMessage()|
// call will dequeue the message and dispatch it.
- uint32_t message_id =
+ absl::optional<uint32_t> message_id =
endpoint->EnqueueSyncMessage(std::move(message_wrapper));
- task_runner->PostTask(
- FROM_HERE,
- base::BindOnce(&ChannelAssociatedGroupController::AcceptSyncMessage,
- this, id, message_id));
+ if (message_id) {
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &ChannelAssociatedGroupController::AcceptSyncMessage, this,
+ id, *message_id));
+ }
return true;
}
diff --git a/mojo/public/cpp/bindings/interface_endpoint_controller.h b/mojo/public/cpp/bindings/interface_endpoint_controller.h
index 89dbe39994620148e0ef33910b7cc7baacd7cc2e..8649abe1ac9c4b964c2bf833b850aa6f898b7103 100644
--- a/mojo/public/cpp/bindings/interface_endpoint_controller.h
+++ b/mojo/public/cpp/bindings/interface_endpoint_controller.h
@@ -36,6 +36,10 @@ class InterfaceEndpointController {
// Watches the endpoint for a specific incoming sync reply. This method only
// returns true once the reply is received, or false if the endpoint is
// detached or destroyed beforehand.
+ //
+ // Unlike with SyncWatch(), no other IPCs (not even other sync IPCs) can be
+ // dispatched to the calling thread while SyncWatchExclusive() is waiting on
+ // the reply for `request_id`.
virtual bool SyncWatchExclusive(uint64_t request_id) = 0;
// Notifies the controller that a specific in-flight sync message identified
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
index 6e87db197c603d8ac44b591f2cd70023217dcbe2..1a786923f6d66c0b8d17765ea7b629add2db104c 100644
--- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
+++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -387,7 +387,9 @@ void ThreadSafeInterfaceEndpointClientProxy::SendMessageWithResponder(
}
// If the Remote is bound on another sequence, post the call.
- const bool allow_interrupt = !message.has_flag(Message::kFlagNoInterrupt);
+ const bool allow_interrupt =
+ SyncCallRestrictions::AreSyncCallInterruptsEnabled() &&
+ !message.has_flag(Message::kFlagNoInterrupt);
auto response = base::MakeRefCounted<SyncResponseInfo>();
auto response_signaler = std::make_unique<SyncResponseSignaler>(response);
task_runner_->PostTask(
@@ -625,7 +627,9 @@ bool InterfaceEndpointClient::SendMessageWithResponder(
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);
+ const bool exclusive_wait =
+ message->has_flag(Message::kFlagNoInterrupt) ||
+ !SyncCallRestrictions::AreSyncCallInterruptsEnabled();
if (!controller_->SendMessage(message))
return false;
diff --git a/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc b/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc
index 329901dec12572e8d8833eba33ad1cc793919084..6242391074ee6279cfea29cf1e73ac4ef874445a 100644
--- a/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc
+++ b/mojo/public/cpp/bindings/lib/sync_call_restrictions.cc
@@ -4,8 +4,6 @@
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
-#if ENABLE_SYNC_CALL_RESTRICTIONS
-
#include "base/check_op.h"
#include "base/debug/leak_annotations.h"
#include "base/logging.h"
@@ -19,6 +17,11 @@ namespace mojo {
namespace {
+// Sync call interrupts are enabled by default.
+bool g_enable_sync_call_interrupts = true;
+
+#if ENABLE_SYNC_CALL_RESTRICTIONS
+
class GlobalSyncCallSettings {
public:
GlobalSyncCallSettings() = default;
@@ -61,8 +64,12 @@ bool SyncCallRestrictionsEnforceable() {
return base::internal::SequenceLocalStorageMap::IsSetForCurrentThread();
}
+#endif // ENABLE_SYNC_CALL_RESTRICTIONS
+
} // namespace
+#if ENABLE_SYNC_CALL_RESTRICTIONS
+
// static
void SyncCallRestrictions::AssertSyncCallAllowed() {
if (GetGlobalSettings().sync_call_allowed_by_default() ||
@@ -102,6 +109,21 @@ void SyncCallRestrictions::DecreaseScopedAllowCount() {
--GetSequenceLocalScopedAllowCount();
}
-} // namespace mojo
-
#endif // ENABLE_SYNC_CALL_RESTRICTIONS
+
+// static
+void SyncCallRestrictions::DisableSyncCallInterrupts() {
+ g_enable_sync_call_interrupts = false;
+}
+
+// static
+void SyncCallRestrictions::EnableSyncCallInterruptsForTesting() {
+ g_enable_sync_call_interrupts = true;
+}
+
+// static
+bool SyncCallRestrictions::AreSyncCallInterruptsEnabled() {
+ return g_enable_sync_call_interrupts;
+}
+
+} // namespace mojo
diff --git a/mojo/public/cpp/bindings/sync_call_restrictions.h b/mojo/public/cpp/bindings/sync_call_restrictions.h
index e7e67ee824b2a87eb14b45a3f2d76d471ff864fb..1653fd63033383b40b643c03500b26bdc65a44a6 100644
--- a/mojo/public/cpp/bindings/sync_call_restrictions.h
+++ b/mojo/public/cpp/bindings/sync_call_restrictions.h
@@ -86,6 +86,20 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) SyncCallRestrictions {
static void DisallowSyncCall() {}
#endif
+ // Globally disables sync call interrupts. This means that all sync calls in
+ // the current process will be strictly blocking until a reply is received,
+ // and no incoming sync calls can dispatch on the blocking thread in interim.
+ static void DisableSyncCallInterrupts();
+
+ // Used only in tests to re-enable sync call interrupts after disabling them.
+ static void EnableSyncCallInterruptsForTesting();
+
+ // Indicates whether sync call interrupts are enabled in the calling process.
+ // They're enabled by default, so any sync message that isn't marked [Sync]
+ // may have its blocking call interrupted to dispatch other incoming sync
+ // IPCs which target the blocking thread.
+ static bool AreSyncCallInterruptsEnabled();
+
private:
// DO NOT ADD ANY OTHER FRIEND STATEMENTS, talk to mojo/OWNERS first.
// BEGIN ALLOWED USAGE.
diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
index cfac737af29e653d788eb1ce7669f73ae7b320d4..d794d29df07d289d34b3b1aae9f8574fc914c050 100644
--- a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
@@ -25,6 +25,7 @@
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "mojo/public/cpp/bindings/shared_associated_remote.h"
#include "mojo/public/cpp/bindings/shared_remote.h"
+#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
#include "mojo/public/cpp/bindings/tests/bindings_test_base.h"
#include "mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom.h"
#include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h"
@@ -1563,7 +1564,144 @@ TEST_P(SyncInterruptTest, SharedAssociatedRemoteNoInterrupt) {
EXPECT_EQ(0, same_pipe_ponger().num_sync_pongs());
}
+class SyncService : public mojom::SyncService {
+ public:
+ explicit SyncService(PendingReceiver<mojom::SyncService> receiver)
+ : receiver_(this, std::move(receiver)) {}
+
+ void SetCallHandler(base::OnceClosure call_handler) {
+ call_handler_ = std::move(call_handler);
+ }
+
+ // mojom::SyncService:
+ void SyncCall(SyncCallCallback callback) override {
+ std::move(callback).Run();
+ if (call_handler_) {
+ std::move(call_handler_).Run();
+ }
+ }
+
+ private:
+ Receiver<mojom::SyncService> receiver_;
+ base::OnceClosure call_handler_;
+};
+
+class DisableSyncInterruptTest : public BindingsTestBase {
+ public:
+ void SetUp() override {
+ mojo::SyncCallRestrictions::DisableSyncCallInterrupts();
+ }
+
+ void TearDown() override {
+ mojo::SyncCallRestrictions::EnableSyncCallInterruptsForTesting();
+ }
+};
+
+TEST_P(DisableSyncInterruptTest, NoInterruptWhenDisabled) {
+ PendingRemote<mojom::SyncService> interrupter;
+ SyncService service(interrupter.InitWithNewPipeAndPassReceiver());
+
+ base::RunLoop wait_for_main_thread_service_call;
+ bool main_thread_service_called = false;
+ service.SetCallHandler(base::BindLambdaForTesting([&] {
+ main_thread_service_called = true;
+ wait_for_main_thread_service_call.Quit();
+ }));
+
+ Remote<mojom::SyncService> caller;
+ base::Thread background_service_thread("SyncService");
+ background_service_thread.Start();
+ base::SequenceBound<SyncService> background_service{
+ background_service_thread.task_runner(),
+ caller.BindNewPipeAndPassReceiver()};
+
+ base::Thread interrupter_thread("Interrupter");
+ interrupter_thread.Start();
+ interrupter_thread.task_runner()->PostTask(
+ FROM_HERE, base::BindLambdaForTesting([&interrupter] {
+ // Issue a sync call to the SyncService on the main thread. This should
+ // never be dispatched until *after* the sync call *from* the main
+ // thread completes below.
+ Remote<mojom::SyncService>(std::move(interrupter))->SyncCall();
+ }));
+
+ // The key test expectation here is that `main_thread_service_called` cannot
+ // be set to true until after SyncCall() returns and we can pump the thread's
+ // message loop. If sync interrupts are not properly disabled, this
+ // expectation can fail flakily (and often.)
+ caller->SyncCall();
+ EXPECT_FALSE(main_thread_service_called);
+
+ // Now the incoming sync call can be dispatched.
+ wait_for_main_thread_service_call.Run();
+ EXPECT_TRUE(main_thread_service_called);
+
+ background_service.SynchronouslyResetForTest();
+ interrupter_thread.Stop();
+ background_service_thread.Stop();
+}
+
+TEST_P(DisableSyncInterruptTest, SharedRemoteNoInterruptWhenDisabled) {
+ PendingRemote<mojom::SyncService> interrupter;
+ SyncService service(interrupter.InitWithNewPipeAndPassReceiver());
+
+ base::RunLoop wait_for_main_thread_service_call;
+ bool main_thread_service_called = false;
+ service.SetCallHandler(base::BindLambdaForTesting([&] {
+ main_thread_service_called = true;
+ wait_for_main_thread_service_call.Quit();
+ }));
+
+ // Bind a SharedRemote to another background thread so that we exercise
+ // SharedRemote's own sync wait codepath when called into from the main
+ // thread.
+ base::Thread background_client_thread("Client");
+ background_client_thread.Start();
+
+ base::Thread background_service_thread("Service");
+ background_service_thread.Start();
+
+ SharedRemote<mojom::SyncService> caller;
+ base::SequenceBound<SyncService> background_service{
+ background_service_thread.task_runner(),
+ caller.BindNewPipeAndPassReceiver(
+ background_client_thread.task_runner())};
+
+ base::Thread interrupter_thread("Interrupter");
+ interrupter_thread.Start();
+ interrupter_thread.task_runner()->PostTask(
+ FROM_HERE, base::BindLambdaForTesting([&interrupter] {
+ // Issue a sync call to the SyncService on the main thread. This should
+ // never be dispatched until *after* the sync call *from* the main
+ // thread completes below.
+ Remote<mojom::SyncService>(std::move(interrupter))->SyncCall();
+ }));
+
+ // The key test expectation here is that `main_thread_service_called` cannot
+ // be set to true until after SyncCall() returns and we can pump the thread's
+ // message loop. If sync interrupts are not properly disabled, this
+ // expectation can fail flakily (and often.)
+ caller->SyncCall();
+ EXPECT_FALSE(main_thread_service_called);
+
+ // Now the incoming sync call can be dispatched.
+ wait_for_main_thread_service_call.Run();
+ EXPECT_TRUE(main_thread_service_called);
+
+ background_service.SynchronouslyResetForTest();
+
+ // We need to reset the SharedRemote before the client thread is stopped, to
+ // ensure the necessary teardown work is executed on that thread. Otherwise
+ // the underlying pipe and related state will leak, and ASan will complain.
+ caller.reset();
+
+ interrupter_thread.Stop();
+ background_service_thread.Stop();
+ background_client_thread.Stop();
+}
+
INSTANTIATE_MOJO_BINDINGS_TEST_SUITE_P(SyncInterruptTest);
+INSTANTIATE_MOJO_BINDINGS_TEST_SUITE_P(DisableSyncInterruptTest);
} // namespace
} // namespace sync_method_unittest
diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom b/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom
index 383b54f3ab654d664192522c061058b29fd0509a..951442b3585ad22f936568e211ad41f8ae358705 100644
--- a/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom
+++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom
@@ -45,3 +45,7 @@ interface Ponger {
[Sync] Pong() => ();
PongAsync();
};
+
+interface SyncService {
+ [Sync] SyncCall() => ();
+};

View File

@@ -0,0 +1,953 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Cheng <dcheng@chromium.org>
Date: Sat, 12 Nov 2022 00:27:56 +0000
Subject: Validate that a message is allowed to use the sync flag.
This changes consists of several coordinated changes:
- The C++ bindings generator now emits an array of method ordinals that
are allowed to use sync calls, but only if any method has a [Sync]
annotation. This is intended to minimize the code cost to interfaces
that do not have any sync methods (i.e. most of them).
- The C++ binding endpoints (mojo::Receiver, et cetera) now plumb the
array of sync-allowed ordinals to the InterfaceEndpointClient.
- Processing an incoming message checks if the incoming message is
allowed to use the sync flag by filtering it against the array of
sync-allowed ordinals that was previously passed to the
InterfaceEndpointClient.
This also fixes an incorrect forward declaration of ValidationContext in
the generated bindings that discovered in the process of writing the
test.
(cherry picked from commit 4365dddb49847a422bce674383b4aa4f38ff9e89)
Bug: 1376099
Change-Id: Icb5864dcab96ccd18c98b4cc6ade7cdef39e209f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3994146
Reviewed-by: Ken Rockot <rockot@google.com>
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1067894}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4018151
Auto-Submit: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/branch-heads/5359@{#774}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/mojo/public/cpp/bindings/BUILD.gn b/mojo/public/cpp/bindings/BUILD.gn
index 2c27474d1200f80ff7abc773eaafdc9d30494f58..de587d8759f2e850ef9de355551c4be12f3ca6e7 100644
--- a/mojo/public/cpp/bindings/BUILD.gn
+++ b/mojo/public/cpp/bindings/BUILD.gn
@@ -183,6 +183,7 @@ component("bindings") {
"lib/sync_event_watcher.cc",
"lib/sync_handle_registry.cc",
"lib/sync_handle_watcher.cc",
+ "lib/sync_method_traits.h",
"lib/task_runner_helper.cc",
"lib/task_runner_helper.h",
"lib/thread_safe_forwarder_base.cc",
diff --git a/mojo/public/cpp/bindings/associated_receiver.h b/mojo/public/cpp/bindings/associated_receiver.h
index 78c53543ed01cafe627d0559c31be1d792750685..59b86367122074e8c59fcbd9877bf59d669cc436 100644
--- a/mojo/public/cpp/bindings/associated_receiver.h
+++ b/mojo/public/cpp/bindings/associated_receiver.h
@@ -5,15 +5,19 @@
#ifndef MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_RECEIVER_H_
#define MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_RECEIVER_H_
+#include <stdint.h>
+
#include <memory>
#include <utility>
#include "base/check.h"
+#include "base/containers/span.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_piece.h"
#include "base/task/sequenced_task_runner.h"
+#include "mojo/public/cpp/bindings/lib/sync_method_traits.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"
@@ -60,7 +64,7 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) AssociatedReceiverBase {
void BindImpl(ScopedInterfaceEndpointHandle handle,
MessageReceiverWithResponderStatus* receiver,
std::unique_ptr<MessageReceiver> payload_validator,
- bool expect_sync_requests,
+ base::span<const uint32_t> sync_method_ordinals,
scoped_refptr<base::SequencedTaskRunner> runner,
uint32_t interface_version,
const char* interface_name,
@@ -201,8 +205,8 @@ class AssociatedReceiver : public internal::AssociatedReceiverBase {
if (pending_receiver) {
BindImpl(pending_receiver.PassHandle(), &stub_,
base::WrapUnique(new typename Interface::RequestValidator_()),
- Interface::HasSyncMethods_, std::move(task_runner),
- Interface::Version_, Interface::Name_,
+ internal::SyncMethodTraits<Interface>::GetOrdinals(),
+ std::move(task_runner), Interface::Version_, Interface::Name_,
Interface::MessageToStableIPCHash_,
Interface::MessageToMethodName_);
} else {
diff --git a/mojo/public/cpp/bindings/interface_endpoint_client.h b/mojo/public/cpp/bindings/interface_endpoint_client.h
index dcc6e2aa8d9e97ff716d6ab1de02a83eba95eec2..93aea2bd29c5171f63401bc5d88fb7d6dc302e71 100644
--- a/mojo/public/cpp/bindings/interface_endpoint_client.h
+++ b/mojo/public/cpp/bindings/interface_endpoint_client.h
@@ -13,6 +13,7 @@
#include "base/callback.h"
#include "base/component_export.h"
+#include "base/containers/span.h"
#include "base/dcheck_is_on.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
@@ -56,7 +57,7 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) InterfaceEndpointClient
InterfaceEndpointClient(ScopedInterfaceEndpointHandle handle,
MessageReceiverWithResponderStatus* receiver,
std::unique_ptr<MessageReceiver> payload_validator,
- bool expect_sync_requests,
+ base::span<const uint32_t> sync_method_ordinals,
scoped_refptr<base::SequencedTaskRunner> task_runner,
uint32_t interface_version,
const char* interface_name,
@@ -220,6 +221,10 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) InterfaceEndpointClient
// The router lock must be held when calling this.
void ForgetAsyncRequest(uint64_t request_id);
+ base::span<const uint32_t> sync_method_ordinals() const {
+ return sync_method_ordinals_;
+ }
+
private:
struct PendingAsyncResponse {
public:
@@ -281,7 +286,7 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) InterfaceEndpointClient
bool HandleValidatedMessage(Message* message);
- const bool expect_sync_requests_ = false;
+ const base::span<const uint32_t> sync_method_ordinals_;
// The callback to invoke when our peer endpoint sends us NotifyIdle and we
// have no outstanding unacked messages. If null, no callback has been set and
diff --git a/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.cc b/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.cc
index 957ce42c4fa8e69ce63ee876653ef8f8a2ae5b28..a8b86f529329c8358172e4d0d6c3fe61fbede31b 100644
--- a/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.cc
+++ b/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.cc
@@ -4,6 +4,11 @@
#include "mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h"
+#include <stdint.h>
+
+#include <utility>
+
+#include "base/containers/span.h"
#include "mojo/public/cpp/bindings/lib/task_runner_helper.h"
namespace mojo {
@@ -70,7 +75,8 @@ void AssociatedInterfacePtrStateBase::Bind(
// The version is only queried from the client so the value passed here
// will not be used.
endpoint_client_ = std::make_unique<InterfaceEndpointClient>(
- std::move(handle), nullptr, std::move(validator), false,
+ std::move(handle), nullptr, std::move(validator),
+ /*sync_method_ordinals=*/base::span<const uint32_t>(),
GetTaskRunnerToUseFromUserProvidedTaskRunner(std::move(runner)), 0u,
interface_name, ipc_hash_callback, method_name_callback);
}
diff --git a/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h b/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h
index d9a4ef1fd6c8141a69de15895ae411a77a03462a..81806976b9c5ccc3d001344a55633d447ac2df24 100644
--- a/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h
+++ b/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h
@@ -141,6 +141,10 @@ class AssociatedInterfacePtrState : public AssociatedInterfacePtrStateBase {
return info;
}
+ InterfaceEndpointClient* endpoint_client_for_test() {
+ return endpoint_client();
+ }
+
private:
std::unique_ptr<Proxy> proxy_;
};
diff --git a/mojo/public/cpp/bindings/lib/associated_receiver.cc b/mojo/public/cpp/bindings/lib/associated_receiver.cc
index be3d8689cbdeaaa685f470f39fef3650d19f0aa0..413104e622a879db15ab6d6fa631462104a409e4 100644
--- a/mojo/public/cpp/bindings/lib/associated_receiver.cc
+++ b/mojo/public/cpp/bindings/lib/associated_receiver.cc
@@ -64,7 +64,7 @@ void AssociatedReceiverBase::BindImpl(
ScopedInterfaceEndpointHandle handle,
MessageReceiverWithResponderStatus* receiver,
std::unique_ptr<MessageReceiver> payload_validator,
- bool expect_sync_requests,
+ base::span<const uint32_t> sync_method_ordinals,
scoped_refptr<base::SequencedTaskRunner> runner,
uint32_t interface_version,
const char* interface_name,
@@ -74,7 +74,7 @@ void AssociatedReceiverBase::BindImpl(
endpoint_client_ = std::make_unique<InterfaceEndpointClient>(
std::move(handle), receiver, std::move(payload_validator),
- expect_sync_requests,
+ sync_method_ordinals,
internal::GetTaskRunnerToUseFromUserProvidedTaskRunner(std::move(runner)),
interface_version, interface_name, ipc_hash_callback,
method_name_callback);
diff --git a/mojo/public/cpp/bindings/lib/binding_state.cc b/mojo/public/cpp/bindings/lib/binding_state.cc
index c40b244184601a6fc661a623f6ae45430925b789..a07943d50add0f840752eceb5d7c56f11ce958e6 100644
--- a/mojo/public/cpp/bindings/lib/binding_state.cc
+++ b/mojo/public/cpp/bindings/lib/binding_state.cc
@@ -107,7 +107,7 @@ void BindingStateBase::BindInternal(
const char* interface_name,
std::unique_ptr<MessageReceiver> request_validator,
bool passes_associated_kinds,
- bool has_sync_methods,
+ base::span<const uint32_t> sync_method_ordinals,
MessageReceiverWithResponderStatus* stub,
uint32_t interface_version,
MessageToStableIPCHashCallback ipc_hash_callback,
@@ -121,7 +121,7 @@ void BindingStateBase::BindInternal(
MultiplexRouter::Config config =
passes_associated_kinds
? MultiplexRouter::MULTI_INTERFACE
- : (has_sync_methods
+ : (!sync_method_ordinals.empty()
? MultiplexRouter::SINGLE_INTERFACE_WITH_SYNC_METHODS
: MultiplexRouter::SINGLE_INTERFACE);
router_ = MultiplexRouter::CreateAndStartReceiving(
@@ -131,7 +131,7 @@ void BindingStateBase::BindInternal(
endpoint_client_ = std::make_unique<InterfaceEndpointClient>(
router_->CreateLocalEndpointHandle(kPrimaryInterfaceId), stub,
- std::move(request_validator), has_sync_methods,
+ std::move(request_validator), sync_method_ordinals,
std::move(sequenced_runner), interface_version, interface_name,
ipc_hash_callback, method_name_callback);
endpoint_client_->SetIdleTrackingEnabledCallback(
diff --git a/mojo/public/cpp/bindings/lib/binding_state.h b/mojo/public/cpp/bindings/lib/binding_state.h
index 64e3fb139fcd8afcf66a85f68e5264dbb47ca997..949b6d8a6eb5ae7d19e26e1b0afe63f1640cff76 100644
--- a/mojo/public/cpp/bindings/lib/binding_state.h
+++ b/mojo/public/cpp/bindings/lib/binding_state.h
@@ -5,6 +5,8 @@
#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_
+#include <stdint.h>
+
#include <memory>
#include <utility>
@@ -12,6 +14,7 @@
#include "base/callback.h"
#include "base/check.h"
#include "base/component_export.h"
+#include "base/containers/span.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_piece.h"
@@ -23,6 +26,7 @@
#include "mojo/public/cpp/bindings/interface_id.h"
#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
#include "mojo/public/cpp/bindings/lib/pending_receiver_state.h"
+#include "mojo/public/cpp/bindings/lib/sync_method_traits.h"
#include "mojo/public/cpp/bindings/message_header_validator.h"
#include "mojo/public/cpp/bindings/pending_flush.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -90,7 +94,7 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) BindingStateBase {
const char* interface_name,
std::unique_ptr<MessageReceiver> request_validator,
bool passes_associated_kinds,
- bool has_sync_methods,
+ base::span<const uint32_t> sync_method_ordinals,
MessageReceiverWithResponderStatus* stub,
uint32_t interface_version,
MessageToStableIPCHashCallback ipc_hash_callback,
@@ -121,9 +125,9 @@ class BindingState : public BindingStateBase {
BindingStateBase::BindInternal(
std::move(receiver_state), runner, Interface::Name_,
std::make_unique<typename Interface::RequestValidator_>(),
- Interface::PassesAssociatedKinds_, Interface::HasSyncMethods_, &stub_,
- Interface::Version_, Interface::MessageToStableIPCHash_,
- Interface::MessageToMethodName_);
+ Interface::PassesAssociatedKinds_,
+ SyncMethodTraits<Interface>::GetOrdinals(), &stub_, Interface::Version_,
+ Interface::MessageToStableIPCHash_, Interface::MessageToMethodName_);
}
PendingReceiver<Interface> Unbind() {
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
index 1a786923f6d66c0b8d17765ea7b629add2db104c..c1e7efe6954ae3dc9186d33067bc324b05273e65 100644
--- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
+++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -439,13 +439,13 @@ InterfaceEndpointClient::InterfaceEndpointClient(
ScopedInterfaceEndpointHandle handle,
MessageReceiverWithResponderStatus* receiver,
std::unique_ptr<MessageReceiver> payload_validator,
- bool expect_sync_requests,
+ base::span<const uint32_t> sync_method_ordinals,
scoped_refptr<base::SequencedTaskRunner> task_runner,
uint32_t interface_version,
const char* interface_name,
MessageToStableIPCHashCallback ipc_hash_callback,
MessageToMethodNameCallback method_name_callback)
- : expect_sync_requests_(expect_sync_requests),
+ : sync_method_ordinals_(sync_method_ordinals),
handle_(std::move(handle)),
incoming_receiver_(receiver),
dispatcher_(&thunk_),
@@ -849,7 +849,8 @@ void InterfaceEndpointClient::InitControllerIfNecessary() {
controller_ = handle_.group_controller()->AttachEndpointClient(handle_, this,
task_runner_);
- if (expect_sync_requests_ && task_runner_->RunsTasksInCurrentSequence())
+ if (!sync_method_ordinals_.empty() &&
+ task_runner_->RunsTasksInCurrentSequence())
controller_->AllowWokenUpBySyncWatchOnSameThread();
}
diff --git a/mojo/public/cpp/bindings/lib/interface_ptr_state.cc b/mojo/public/cpp/bindings/lib/interface_ptr_state.cc
index 8607d5fba2fd59f4f0ca154a9085c47a26ff2c21..aa12189148f79a742be39f3cfaeba9cf54c2dc91 100644
--- a/mojo/public/cpp/bindings/lib/interface_ptr_state.cc
+++ b/mojo/public/cpp/bindings/lib/interface_ptr_state.cc
@@ -4,6 +4,11 @@
#include "mojo/public/cpp/bindings/lib/interface_ptr_state.h"
+#include <stdint.h>
+
+#include <utility>
+
+#include "base/containers/span.h"
#include "mojo/public/cpp/bindings/lib/task_runner_helper.h"
namespace mojo {
@@ -100,7 +105,9 @@ bool InterfacePtrStateBase::InitializeEndpointClient(
interface_name);
endpoint_client_ = std::make_unique<InterfaceEndpointClient>(
router_->CreateLocalEndpointHandle(kPrimaryInterfaceId), nullptr,
- std::move(payload_validator), false, std::move(runner_),
+ std::move(payload_validator),
+ /* sync_method_ordinals= */ base::span<const uint32_t>(),
+ std::move(runner_),
// The version is only queried from the client so the value passed here
// will not be used.
0u, interface_name, ipc_hash_callback, method_name_callback);
diff --git a/mojo/public/cpp/bindings/lib/interface_ptr_state.h b/mojo/public/cpp/bindings/lib/interface_ptr_state.h
index 2d379a081e6731db5cd2182365529da2200e3d7b..5b7bb34ac5c9a4764ee9a41c1d3ce324c6a93b13 100644
--- a/mojo/public/cpp/bindings/lib/interface_ptr_state.h
+++ b/mojo/public/cpp/bindings/lib/interface_ptr_state.h
@@ -25,6 +25,7 @@
#include "mojo/public/cpp/bindings/interface_endpoint_client.h"
#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
#include "mojo/public/cpp/bindings/lib/pending_remote_state.h"
+#include "mojo/public/cpp/bindings/lib/sync_method_traits.h"
#include "mojo/public/cpp/bindings/pending_flush.h"
#include "mojo/public/cpp/bindings/thread_safe_proxy.h"
#include "mojo/public/cpp/system/message_pipe.h"
@@ -249,6 +250,10 @@ class InterfacePtrState : public InterfacePtrStateBase {
endpoint_client()->RaiseError();
}
+ InterfaceEndpointClient* endpoint_client_for_test() {
+ return endpoint_client();
+ }
+
private:
void ConfigureProxyIfNecessary() {
// The proxy has been configured.
@@ -259,7 +264,8 @@ class InterfacePtrState : public InterfacePtrStateBase {
}
if (InitializeEndpointClient(
- Interface::PassesAssociatedKinds_, Interface::HasSyncMethods_,
+ Interface::PassesAssociatedKinds_,
+ !SyncMethodTraits<Interface>::GetOrdinals().empty(),
Interface::HasUninterruptableMethods_,
std::make_unique<typename Interface::ResponseValidator_>(),
Interface::Name_, Interface::MessageToStableIPCHash_,
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc
index b9c92d5ec9eab57972cf870efff51fe09e381623..c04999f0ac8881cc86ed34761ddeb8e8dfc83164 100644
--- a/mojo/public/cpp/bindings/lib/multiplex_router.cc
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
@@ -1067,6 +1067,12 @@ bool MultiplexRouter::ProcessIncomingMessage(
bool can_direct_call;
if (message->has_flag(Message::kFlagIsSync)) {
+ if (!message->has_flag(Message::kFlagIsResponse) &&
+ !base::Contains(endpoint->client()->sync_method_ordinals(),
+ message->name())) {
+ RaiseErrorInNonTestingMode();
+ return true;
+ }
can_direct_call = client_call_behavior != NO_DIRECT_CLIENT_CALLS &&
endpoint->task_runner()->RunsTasksInCurrentSequence();
} else {
diff --git a/mojo/public/cpp/bindings/lib/sync_method_traits.h b/mojo/public/cpp/bindings/lib/sync_method_traits.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b334f8d01c2edb7c3e6b98fb8d35925aded11ab
--- /dev/null
+++ b/mojo/public/cpp/bindings/lib/sync_method_traits.h
@@ -0,0 +1,31 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_SYNC_METHOD_TRAITS_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SYNC_METHOD_TRAITS_H_
+
+#include <stdint.h>
+
+#include <type_traits>
+
+#include "base/containers/span.h"
+
+namespace mojo::internal {
+
+template <typename Interface, typename SFINAE = void>
+struct SyncMethodTraits {
+ static constexpr base::span<const uint32_t> GetOrdinals() { return {}; }
+};
+
+template <typename Interface>
+struct SyncMethodTraits<Interface,
+ std::void_t<decltype(Interface::kSyncMethodOrdinals)>> {
+ static constexpr base::span<const uint32_t> GetOrdinals() {
+ return Interface::kSyncMethodOrdinals;
+ }
+};
+
+} // namespace mojo::internal
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SYNC_METHOD_TRAITS_H_
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn
index 248176f6f350b57bb5138924c68c4393ba1c11a8..25cfe56438d099ddcb4ed04a4e83b9abb89b8d14 100644
--- a/mojo/public/cpp/bindings/tests/BUILD.gn
+++ b/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -65,6 +65,7 @@ source_set("tests") {
":mojo_public_bindings_test_utils",
":test_extra_cpp_template_mojom",
":test_mojom",
+ ":test_mojom__generate_message_ids",
"//base/test:test_support",
"//mojo/core/test:test_support",
"//mojo/public/cpp/bindings",
diff --git a/mojo/public/cpp/bindings/tests/bindings_perftest.cc b/mojo/public/cpp/bindings/tests/bindings_perftest.cc
index 2c44aaedd8b1a9415d41d8215266aad5033e34e3..1bb2c2d7c03f3b2069e09c1746b17cfea0477b0b 100644
--- a/mojo/public/cpp/bindings/tests/bindings_perftest.cc
+++ b/mojo/public/cpp/bindings/tests/bindings_perftest.cc
@@ -213,12 +213,12 @@ TEST_F(MojoBindingsPerftest, MultiplexRouterPingPong) {
InterfaceEndpointClient client0(
router0->CreateLocalEndpointHandle(kPrimaryInterfaceId), &paddle0,
- nullptr, false, base::ThreadTaskRunnerHandle::Get(), 0u,
- kTestInterfaceName, MessageToStableIPCHash, MessageToMethodName);
+ nullptr, {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ MessageToStableIPCHash, MessageToMethodName);
InterfaceEndpointClient client1(
router1->CreateLocalEndpointHandle(kPrimaryInterfaceId), &paddle1,
- nullptr, false, base::ThreadTaskRunnerHandle::Get(), 0u,
- kTestInterfaceName, MessageToStableIPCHash, MessageToMethodName);
+ nullptr, {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ MessageToStableIPCHash, MessageToMethodName);
paddle0.set_sender(&client0);
paddle1.set_sender(&client1);
@@ -265,8 +265,8 @@ TEST_F(MojoBindingsPerftest, MultiplexRouterDispatchCost) {
CounterReceiver receiver;
InterfaceEndpointClient client(
router->CreateLocalEndpointHandle(kPrimaryInterfaceId), &receiver,
- nullptr, false, base::ThreadTaskRunnerHandle::Get(), 0u,
- kTestInterfaceName, MessageToStableIPCHash, MessageToMethodName);
+ nullptr, {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ MessageToStableIPCHash, MessageToMethodName);
static const uint32_t kIterations[] = {1000, 3000000};
diff --git a/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc b/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc
index 300ead4aefd2d5167c29c0afae4ea7c1a3f85426..1dcb7bcddc04cc8584300e4add052cb2059613cf 100644
--- a/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/multiplex_router_unittest.cc
@@ -74,13 +74,13 @@ class MultiplexRouterTest : public testing::Test {
TEST_F(MultiplexRouterTest, BasicRequestResponse) {
InterfaceEndpointClient client0(
- std::move(endpoint0_), nullptr, std::make_unique<PassThroughFilter>(),
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ std::move(endpoint0_), nullptr, std::make_unique<PassThroughFilter>(), {},
+ base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
MessageToStableIPCHash, MessageToMethodName);
ResponseGenerator generator;
InterfaceEndpointClient client1(
std::move(endpoint1_), &generator, std::make_unique<PassThroughFilter>(),
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
MessageToStableIPCHash, MessageToMethodName);
Message request;
@@ -123,13 +123,13 @@ TEST_F(MultiplexRouterTest, BasicRequestResponse) {
TEST_F(MultiplexRouterTest, BasicRequestResponse_Synchronous) {
InterfaceEndpointClient client0(
- std::move(endpoint0_), nullptr, std::make_unique<PassThroughFilter>(),
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ std::move(endpoint0_), nullptr, std::make_unique<PassThroughFilter>(), {},
+ base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
MessageToStableIPCHash, MessageToMethodName);
ResponseGenerator generator;
InterfaceEndpointClient client1(
std::move(endpoint1_), &generator, std::make_unique<PassThroughFilter>(),
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
MessageToStableIPCHash, MessageToMethodName);
Message request;
@@ -173,15 +173,15 @@ TEST_F(MultiplexRouterTest, BasicRequestResponse_Synchronous) {
TEST_F(MultiplexRouterTest, LazyResponses) {
InterfaceEndpointClient client0(
std::move(endpoint0_), nullptr, base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
MessageToStableIPCHash, MessageToMethodName);
base::RunLoop run_loop;
LazyResponseGenerator generator(run_loop.QuitClosure());
InterfaceEndpointClient client1(std::move(endpoint1_), &generator,
- base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get(),
- 0u, kTestInterfaceName,
- MessageToStableIPCHash, MessageToMethodName);
+ base::WrapUnique(new PassThroughFilter()), {},
+ base::ThreadTaskRunnerHandle::Get(), 0u,
+ kTestInterfaceName, MessageToStableIPCHash,
+ MessageToMethodName);
Message request;
AllocRequestMessage(1, "hello", &request);
@@ -247,7 +247,7 @@ TEST_F(MultiplexRouterTest, MissingResponses) {
base::RunLoop run_loop0, run_loop1;
InterfaceEndpointClient client0(
std::move(endpoint0_), nullptr, base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
MessageToStableIPCHash, MessageToMethodName);
bool error_handler_called0 = false;
client0.set_connection_error_handler(base::BindOnce(
@@ -256,10 +256,10 @@ TEST_F(MultiplexRouterTest, MissingResponses) {
base::RunLoop run_loop3;
LazyResponseGenerator generator(run_loop3.QuitClosure());
InterfaceEndpointClient client1(std::move(endpoint1_), &generator,
- base::WrapUnique(new PassThroughFilter()),
- false, base::ThreadTaskRunnerHandle::Get(),
- 0u, kTestInterfaceName,
- MessageToStableIPCHash, MessageToMethodName);
+ base::WrapUnique(new PassThroughFilter()), {},
+ base::ThreadTaskRunnerHandle::Get(), 0u,
+ kTestInterfaceName, MessageToStableIPCHash,
+ MessageToMethodName);
bool error_handler_called1 = false;
client1.set_connection_error_handler(base::BindOnce(
&ForwardErrorHandler, &error_handler_called1, run_loop1.QuitClosure()));
@@ -306,13 +306,13 @@ TEST_F(MultiplexRouterTest, LateResponse) {
{
InterfaceEndpointClient client0(
std::move(endpoint0_), nullptr, std::make_unique<PassThroughFilter>(),
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
- MessageToStableIPCHash, MessageToMethodName);
- InterfaceEndpointClient client1(
- std::move(endpoint1_), &generator,
- std::make_unique<PassThroughFilter>(), false,
- base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
MessageToStableIPCHash, MessageToMethodName);
+ InterfaceEndpointClient client1(std::move(endpoint1_), &generator,
+ std::make_unique<PassThroughFilter>(), {},
+ base::ThreadTaskRunnerHandle::Get(), 0u,
+ kTestInterfaceName, MessageToStableIPCHash,
+ MessageToMethodName);
Message request;
AllocRequestMessage(1, "hello", &request);
diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
index d794d29df07d289d34b3b1aae9f8574fc914c050..6de90c8ec9619358e97d50726d7c8c6820df7990 100644
--- a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <tuple>
#include <utility>
#include "base/barrier_closure.h"
@@ -9,15 +10,21 @@
#include "base/check.h"
#include "base/run_loop.h"
#include "base/sequence_token.h"
+#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "base/threading/sequence_bound.h"
+#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "mojo/public/cpp/bindings/lib/message_fragment.h"
+#include "mojo/public/cpp/bindings/lib/send_message_helper.h"
+#include "mojo/public/cpp/bindings/lib/serialization_util.h"
+#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote.h"
@@ -27,10 +34,16 @@
#include "mojo/public/cpp/bindings/shared_remote.h"
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
#include "mojo/public/cpp/bindings/tests/bindings_test_base.h"
+#include "mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom-shared-message-ids.h"
#include "mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom.h"
#include "mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
+// This needs to be included last, since it forward declares a bunch of classes
+// but depends on those definitions to be included by headers that sort
+// lexicographically after.
+#include "mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom-params-data.h"
+
namespace mojo {
namespace test {
namespace sync_method_unittest {
@@ -1703,6 +1716,237 @@ TEST_P(DisableSyncInterruptTest, SharedRemoteNoInterruptWhenDisabled) {
INSTANTIATE_MOJO_BINDINGS_TEST_SUITE_P(SyncInterruptTest);
INSTANTIATE_MOJO_BINDINGS_TEST_SUITE_P(DisableSyncInterruptTest);
+class OneSyncImpl;
+
+class NoSyncImpl : public mojom::NoSync {
+ public:
+ explicit NoSyncImpl(PendingReceiver<mojom::NoSync> receiver)
+ : receiver_(this, std::move(receiver)) {}
+
+ explicit NoSyncImpl(
+ PendingAssociatedReceiver<mojom::NoSync> associated_receiver)
+ : associated_receiver_(this, std::move(associated_receiver)) {}
+
+ // mojom::NoSync implementation:
+ void Method(MethodCallback callback) override;
+ void BindNoSync(PendingAssociatedReceiver<mojom::NoSync> receiver) override;
+ void BindOneSync(PendingAssociatedReceiver<mojom::OneSync> receiver) override;
+
+ private:
+ Receiver<mojom::NoSync> receiver_{this};
+ AssociatedReceiver<mojom::NoSync> associated_receiver_{this};
+
+ std::unique_ptr<NoSyncImpl> associated_no_sync_;
+ std::unique_ptr<OneSyncImpl> associated_one_sync_;
+};
+
+class OneSyncImpl : public mojom::OneSync {
+ public:
+ explicit OneSyncImpl(PendingReceiver<mojom::OneSync> receiver)
+ : receiver_(this, std::move(receiver)) {}
+
+ explicit OneSyncImpl(
+ PendingAssociatedReceiver<mojom::OneSync> associated_receiver)
+ : associated_receiver_(this, std::move(associated_receiver)) {}
+
+ // mojom::OneSync implementation:
+ void Method(MethodCallback callback) override;
+ void SyncMethod(SyncMethodCallback callback) override;
+ void BindNoSync(PendingAssociatedReceiver<mojom::NoSync> receiver) override;
+ void BindOneSync(PendingAssociatedReceiver<mojom::OneSync> receiver) override;
+
+ private:
+ Receiver<mojom::OneSync> receiver_{this};
+ AssociatedReceiver<mojom::OneSync> associated_receiver_{this};
+
+ std::unique_ptr<NoSyncImpl> associated_no_sync_;
+ std::unique_ptr<OneSyncImpl> associated_one_sync_;
+};
+
+void NoSyncImpl::Method(MethodCallback callback) {
+ EXPECT_TRUE(false);
+ std::move(callback).Run();
+}
+
+void NoSyncImpl::BindNoSync(PendingAssociatedReceiver<mojom::NoSync> receiver) {
+ associated_no_sync_ = std::make_unique<NoSyncImpl>(std::move(receiver));
+}
+
+void NoSyncImpl::BindOneSync(
+ PendingAssociatedReceiver<mojom::OneSync> receiver) {
+ associated_one_sync_ = std::make_unique<OneSyncImpl>(std::move(receiver));
+}
+
+void OneSyncImpl::Method(MethodCallback callback) {
+ EXPECT_TRUE(false);
+ std::move(callback).Run();
+}
+
+void OneSyncImpl::SyncMethod(MethodCallback callback) {
+ std::move(callback).Run();
+}
+
+void OneSyncImpl::BindNoSync(
+ PendingAssociatedReceiver<mojom::NoSync> receiver) {
+ associated_no_sync_ = std::make_unique<NoSyncImpl>(std::move(receiver));
+}
+
+void OneSyncImpl::BindOneSync(
+ PendingAssociatedReceiver<mojom::OneSync> receiver) {
+ associated_one_sync_ = std::make_unique<OneSyncImpl>(std::move(receiver));
+}
+
+class NoResponseExpectedResponder : public MessageReceiver {
+ public:
+ explicit NoResponseExpectedResponder() = default;
+
+ // MessageReceiver implementation:
+ bool Accept(Message* message) override {
+ EXPECT_TRUE(false);
+ return true;
+ }
+};
+
+class SyncFlagValidationTest : public ::testing::TestWithParam<uint32_t> {
+ protected:
+ Message MakeNoSyncMethodMessage() {
+ const uint32_t flags =
+ // Always set the sync flag, as that's the primary point of the test.
+ Message::kFlagIsSync |
+ // InterfaceEndpointClient requires this flag if sending a message with
+ // a responder.
+ Message::kFlagExpectsResponse | GetParam();
+ Message message(mojom::internal::kNoSync_Method_Name, flags, 0, 0, nullptr);
+ ::mojo::internal::MessageFragment<
+ mojom::internal::NoSync_Method_Params_Data>
+ params(message);
+ params.Allocate();
+ return message;
+ }
+
+ Message MakeOneSyncMethodMessage() {
+ const uint32_t flags =
+ // Always set the sync flag, as that's the primary point of the test.
+ Message::kFlagIsSync |
+ // InterfaceEndpointClient requires this flag if sending a message with
+ // a responder.
+ Message::kFlagExpectsResponse | GetParam();
+ Message message(mojom::internal::kOneSync_Method_Name, flags, 0, 0,
+ nullptr);
+ ::mojo::internal::MessageFragment<
+ mojom::internal::NoSync_Method_Params_Data>
+ params(message);
+ params.Allocate();
+ return message;
+ }
+
+ void FlushPostedTasks() {
+ base::RunLoop run_loop;
+ base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
+ run_loop.Run();
+ }
+
+ private:
+ base::test::SingleThreadTaskEnvironment task_environment;
+};
+
+TEST_P(SyncFlagValidationTest, NonSync) {
+ Remote<mojom::NoSync> remote;
+ NoSyncImpl impl(remote.BindNewPipeAndPassReceiver());
+
+ Message message = MakeNoSyncMethodMessage();
+ auto responder = std::make_unique<NoResponseExpectedResponder>();
+ ASSERT_TRUE(remote.internal_state()->endpoint_client_for_test());
+ ::mojo::internal::SendMojoMessage(
+ *remote.internal_state()->endpoint_client_for_test(), message,
+ std::move(responder));
+}
+
+TEST_P(SyncFlagValidationTest, OneSync) {
+ Remote<mojom::OneSync> remote;
+ OneSyncImpl impl(remote.BindNewPipeAndPassReceiver());
+
+ Message message = MakeOneSyncMethodMessage();
+ auto responder = std::make_unique<NoResponseExpectedResponder>();
+ ASSERT_TRUE(remote.internal_state()->endpoint_client_for_test());
+ ::mojo::internal::SendMojoMessage(
+ *remote.internal_state()->endpoint_client_for_test(), message,
+ std::move(responder));
+}
+
+TEST_P(SyncFlagValidationTest, NoSyncAssociatedWithNoSync) {
+ Remote<mojom::NoSync> remote;
+ NoSyncImpl impl(remote.BindNewPipeAndPassReceiver());
+
+ AssociatedRemote<mojom::NoSync> associated_remote;
+ remote->BindNoSync(associated_remote.BindNewEndpointAndPassReceiver());
+
+ FlushPostedTasks();
+
+ Message message = MakeNoSyncMethodMessage();
+ auto responder = std::make_unique<NoResponseExpectedResponder>();
+ ASSERT_TRUE(remote.internal_state()->endpoint_client_for_test());
+ ::mojo::internal::SendMojoMessage(
+ *associated_remote.internal_state()->endpoint_client_for_test(), message,
+ std::move(responder));
+}
+
+TEST_P(SyncFlagValidationTest, OneSyncAssociatedWithNoSync) {
+ Remote<mojom::NoSync> remote;
+ NoSyncImpl impl(remote.BindNewPipeAndPassReceiver());
+
+ AssociatedRemote<mojom::OneSync> associated_remote;
+ remote->BindOneSync(associated_remote.BindNewEndpointAndPassReceiver());
+
+ FlushPostedTasks();
+
+ Message message = MakeOneSyncMethodMessage();
+ auto responder = std::make_unique<NoResponseExpectedResponder>();
+ ASSERT_TRUE(remote.internal_state()->endpoint_client_for_test());
+ ::mojo::internal::SendMojoMessage(
+ *associated_remote.internal_state()->endpoint_client_for_test(), message,
+ std::move(responder));
+}
+
+TEST_P(SyncFlagValidationTest, NoSyncAssociatedWithOneSync) {
+ Remote<mojom::OneSync> remote;
+ OneSyncImpl impl(remote.BindNewPipeAndPassReceiver());
+
+ AssociatedRemote<mojom::NoSync> associated_remote;
+ remote->BindNoSync(associated_remote.BindNewEndpointAndPassReceiver());
+
+ FlushPostedTasks();
+
+ Message message = MakeNoSyncMethodMessage();
+ auto responder = std::make_unique<NoResponseExpectedResponder>();
+ ASSERT_TRUE(remote.internal_state()->endpoint_client_for_test());
+ ::mojo::internal::SendMojoMessage(
+ *associated_remote.internal_state()->endpoint_client_for_test(), message,
+ std::move(responder));
+}
+
+TEST_P(SyncFlagValidationTest, OneSyncAssociatedWithOneSync) {
+ Remote<mojom::OneSync> remote;
+ OneSyncImpl impl(remote.BindNewPipeAndPassReceiver());
+
+ AssociatedRemote<mojom::OneSync> associated_remote;
+ remote->BindOneSync(associated_remote.BindNewEndpointAndPassReceiver());
+
+ FlushPostedTasks();
+
+ Message message = MakeOneSyncMethodMessage();
+ auto responder = std::make_unique<NoResponseExpectedResponder>();
+ ASSERT_TRUE(remote.internal_state()->endpoint_client_for_test());
+ ::mojo::internal::SendMojoMessage(
+ *associated_remote.internal_state()->endpoint_client_for_test(), message,
+ std::move(responder));
+}
+
+INSTANTIATE_TEST_SUITE_P(,
+ SyncFlagValidationTest,
+ ::testing::Values(0, Message::kFlagIsResponse));
+
} // namespace
} // namespace sync_method_unittest
} // namespace test
diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom b/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom
index 951442b3585ad22f936568e211ad41f8ae358705..0cc5f7c6d288f988b6114ff6b5b80546558eb378 100644
--- a/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom
+++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.test-mojom
@@ -49,3 +49,20 @@ interface Ponger {
interface SyncService {
[Sync] SyncCall() => ();
};
+
+interface NoSync {
+ Method() => ();
+
+ BindNoSync(pending_associated_receiver<NoSync> no_sync);
+ BindOneSync(pending_associated_receiver<OneSync> one_sync);
+};
+
+interface OneSync {
+ Method() => ();
+
+ [Sync]
+ SyncMethod() => ();
+
+ BindNoSync(pending_associated_receiver<NoSync> no_sync);
+ BindOneSync(pending_associated_receiver<OneSync> one_sync);
+};
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
index c09a1ec210acbc8d09cdf4d4e09916a8809fa586..57d9f66922475c73f65b4d2713ad50cbb3ae0f23 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
@@ -29,7 +29,12 @@ class {{export_attribute}} {{interface.name}}
{%- endif %}
static constexpr uint32_t Version_ = {{interface.version}};
static constexpr bool PassesAssociatedKinds_ = {% if interface|passes_associated_kinds %}true{% else %}false{% endif %};
- static constexpr bool HasSyncMethods_ = {% if interface|has_sync_methods %}true{% else %}false{% endif %};
+{%- set sync_method_ordinals = interface|get_sync_method_ordinals -%}
+{%- if sync_method_ordinals %}
+ static inline constexpr uint32_t kSyncMethodOrdinals[] = {
+ {{sync_method_ordinals|sort|join(', \n')|indent(4)}}
+ };
+{%- endif %}
static constexpr bool HasUninterruptableMethods_ =
{%- if interface|has_uninterruptable_methods %} true
{%- else %} false{% endif %};
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl
index af3bc5168beb5f9e5b9cfe63354dbdb6b29ff8a1..ab71e91dab403f4c552165eba5da7e32a61b1b83 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl
@@ -17,13 +17,15 @@
#pragma clang diagnostic ignored "-Wunused-private-field"
#endif
+namespace mojo::internal {
+class ValidationContext;
+}
+
{%- for namespace in namespaces_as_array %}
namespace {{namespace}} {
{%- endfor %}
namespace internal {
-class ValidationContext;
-
{#--- Interface parameter definitions #}
{%- for interface in interfaces %}
{%- for method in interface.methods %}
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
index 014f2bf04da4f2e11a13d57d910ecc8a8b489113..add5a877cb7e38da4599d3ae76ea0bd9486637da 100644
--- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
+++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -403,7 +403,7 @@ class Generator(generator.Generator):
"get_qualified_name_for_kind": self._GetQualifiedNameForKind,
"has_callbacks": mojom.HasCallbacks,
"has_packed_method_ordinals": HasPackedMethodOrdinals,
- "has_sync_methods": mojom.HasSyncMethods,
+ "get_sync_method_ordinals": mojom.GetSyncMethodOrdinals,
"has_uninterruptable_methods": mojom.HasUninterruptableMethods,
"method_supports_lazy_serialization":
self._MethodSupportsLazySerialization,
diff --git a/mojo/public/tools/mojom/mojom/generate/module.py b/mojo/public/tools/mojom/mojom/generate/module.py
index 160ad1ef37d7bab86fb15081e0b202845820f8b5..a34d9f0e8134281806a6dc7e7f21e649bce95674 100644
--- a/mojo/public/tools/mojom/mojom/generate/module.py
+++ b/mojo/public/tools/mojom/mojom/generate/module.py
@@ -1739,11 +1739,8 @@ def MethodPassesInterfaces(method):
return _AnyMethodParameterRecursive(method, IsInterfaceKind)
-def HasSyncMethods(interface):
- for method in interface.methods:
- if method.sync:
- return True
- return False
+def GetSyncMethodOrdinals(interface):
+ return [method.ordinal for method in interface.methods if method.sync]
def HasUninterruptableMethods(interface):

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: David Bienvenu <davidbienvenu@chromium.org>
Date: Fri, 10 Jun 2022 23:41:51 +0000
Subject: win: Fix touch mode detection DCHECK in canary
Remove the DCHECK that the ConvertibleSlateMode key exists. If it does
exist, and is set to 1 (physical keyboard available), then we're not
in touch mode. If the key doesn't exist, or is set to the default (0),
use IsDeviceUsedAsATablet() to determine if we're in touch mode.
Bug: 1330848
Change-Id: Ic2d02979c4eb2d318fcc08b37a56163bb7cce55b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3696127
Commit-Queue: David Bienvenu <davidbienvenu@chromium.org>
Reviewed-by: Jesse McKenna <jessemckenna@google.com>
Cr-Commit-Position: refs/heads/main@{#1013189}
diff --git a/base/win/win_util.cc b/base/win/win_util.cc
index a5c20144f6b512ad5d3e2d6f911ab9ad5570bece..ba489fc83d4cc3e91a3c7c8938bf95de46ebe33c 100644
--- a/base/win/win_util.cc
+++ b/base/win/win_util.cc
@@ -253,16 +253,19 @@ bool IsWindows10OrGreaterTabletMode(HWND hwnd) {
// instead we check if we're in slate mode or not - 0 value means slate
// mode. See
// https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-gpiobuttons-convertibleslatemode
+
+ constexpr int kKeyboardPresent = 1;
base::win::RegKey registry_key(
HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Control\\PriorityControl", KEY_READ);
DWORD slate_mode = 0;
bool value_exists = registry_key.ReadValueDW(L"ConvertibleSlateMode",
&slate_mode) == ERROR_SUCCESS;
- DCHECK(value_exists) << "ConvertibleSlateMode value not in registry";
- // Some devices don't set the reg key to 0 for non touch devices, so also
- // check if the device is used as a tablet.
- return value_exists && slate_mode == 0 &&
+ // Some devices don't set the reg key to 1 for keyboard-only devices, so
+ // also check if the device is used as a tablet if it is not 1. Some devices
+ // don't set the registry key at all; fall back to checking if the device
+ // is used as a tablet for them as well.
+ return !(value_exists && slate_mode == kKeyboardPresent) &&
IsDeviceUsedAsATablet(/*reason=*/nullptr);
}

View File

@@ -21,5 +21,9 @@
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
"src/electron/patches/sqlite": "src/third_party/sqlite/src"
"src/electron/patches/sqlite": "src/third_party/sqlite/src",
"src/electron/patches/skia": "src/third_party/skia",
"src/electron/patches/libaom": "src/third_party/libaom/source/libaom"
}

1
patches/libaom/.patches Normal file
View File

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

View File

@@ -0,0 +1,72 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marco Paniconi <marpan@google.com>
Date: Mon, 28 Nov 2022 14:25:08 -0800
Subject: rtc: Avoid scene detection on resize
Don't enter scene detection under external resize.
Add rc->prev_coded_width/height to track the
previous encoded frame eweight/height.
The rc is part of layer context so this will be
per spatial layer for SVC.
This fixes the buffer overflow issue below.
Bug: chromium:1393384
Change-Id: I4b11818a27c439c2d2c42036dff7b8777f70a86e
(cherry picked from commit bee1caded272127a6d6b70ac79479083d183d5d0)
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 40da4f4564e670a74353613620ce162d445f32f8..daadb3ee7d70066d2e38293c4b2029cfee2aab4d 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -2128,6 +2128,9 @@ void av1_rc_postencode_update(AV1_COMP *cpi, uint64_t bytes_used) {
}
#endif
if (current_frame->frame_type == KEY_FRAME) rc->frames_since_key = 0;
+
+ rc->prev_coded_width = cm->width;
+ rc->prev_coded_height = cm->height;
// if (current_frame->frame_number == 1 && cm->show_frame)
/*
rc->this_frame_target =
@@ -2144,6 +2147,8 @@ void av1_rc_postencode_update_drop_frame(AV1_COMP *cpi) {
cpi->rc.rc_2_frame = 0;
cpi->rc.rc_1_frame = 0;
cpi->rc.prev_avg_frame_bandwidth = cpi->rc.avg_frame_bandwidth;
+ cpi->rc.prev_coded_width = cpi->common.width;
+ cpi->rc.prev_coded_height = cpi->common.height;
}
int av1_find_qindex(double desired_q, aom_bit_depth_t bit_depth,
@@ -3083,8 +3088,15 @@ void av1_get_one_pass_rt_params(AV1_COMP *cpi,
}
}
// Check for scene change: for SVC check on base spatial layer only.
- if (cpi->sf.rt_sf.check_scene_detection && svc->spatial_layer_id == 0)
- rc_scene_detection_onepass_rt(cpi);
+ if (cpi->sf.rt_sf.check_scene_detection && svc->spatial_layer_id == 0) {
+ if (rc->prev_coded_width == cm->width &&
+ rc->prev_coded_height == cm->height) {
+ rc_scene_detection_onepass_rt(cpi);
+ } else if (cpi->src_sad_blk_64x64) {
+ aom_free(cpi->src_sad_blk_64x64);
+ cpi->src_sad_blk_64x64 = NULL;
+ }
+ }
// Check for dynamic resize, for single spatial layer for now.
// For temporal layers only check on base temporal layer.
if (cpi->oxcf.resize_cfg.resize_mode == RESIZE_DYNAMIC) {
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
index 5ac9660ab8d31440a5608bab6794286e63203da7..5291323ff4f1401a6a02a8332e552aa8c33b0b0f 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -252,6 +252,9 @@ typedef struct {
int frame_level_fast_extra_bits;
double frame_level_rate_correction_factors[RATE_FACTOR_LEVELS];
+
+ int prev_coded_width;
+ int prev_coded_height;
/*!\endcond */
} RATE_CONTROL;

View File

@@ -45,3 +45,6 @@ json_parse_errors_made_user-friendly.patch
build_ensure_v8_pointer_compression_sandbox_is_enabled_on_64bit.patch
build_ensure_native_module_compilation_fails_if_not_using_a_new.patch
buffer_fix_atob_input_validation.patch
fix_expose_the_built-in_electron_module_via_the_esm_loader.patch
chore_enable_c_17_for_native_modules.patch
cherry-pick-09ae62b.patch

View File

@@ -0,0 +1,236 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Dawson <mdawson@devrus.com>
Date: Tue, 25 Oct 2022 17:39:41 -0400
Subject: node-api: handle no support for external buffers
Refs: https://github.com/electron/electron/issues/35801
Refs: https://github.com/nodejs/abi-stable-node/issues/441
Electron recently dropped support for external
buffers. Provide a way for addon authors to:
- hide the methods to create external buffers so they can
avoid using them if they want the broadest compatibility.
- call the methods that create external buffers at runtime
to check if external buffers are supported and either
use them or not based on the return code.
Signed-off-by: Michael Dawson <mdawson@devrus.com>
PR-URL: https://github.com/nodejs/node/pull/45181
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
diff --git a/doc/api/n-api.md b/doc/api/n-api.md
index 3d1741bad82359af6a258fb2a059656f1528bba0..d64f80e2635074df7f8ecd72d1fde7d1747786fa 100644
--- a/doc/api/n-api.md
+++ b/doc/api/n-api.md
@@ -579,6 +579,7 @@ typedef enum {
napi_arraybuffer_expected,
napi_detachable_arraybuffer_expected,
napi_would_deadlock, /* unused */
+ napi_no_external_buffers_allowed
} napi_status;
```
@@ -2394,6 +2395,19 @@ napi_create_external_arraybuffer(napi_env env,
Returns `napi_ok` if the API succeeded.
+**Some runtimes other than Node.js have dropped support for external buffers**.
+On runtimes other than Node.js this method may return
+`napi_no_external_buffers_allowed` to indicate that external
+buffers are not supported. One such runtime is Electron as
+described in this issue
+[electron/issues/35801](https://github.com/electron/electron/issues/35801).
+
+In order to maintain broadest compatibility with all runtimes
+you may define `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` in your addon before
+includes for the node-api headers. Doing so will hide the 2 functions
+that create external buffers. This will ensure a compilation error
+occurs if you accidentally use one of these methods.
+
This API returns a Node-API value corresponding to a JavaScript `ArrayBuffer`.
The underlying byte buffer of the `ArrayBuffer` is externally allocated and
managed. The caller must ensure that the byte buffer remains valid until the
@@ -2438,6 +2452,19 @@ napi_status napi_create_external_buffer(napi_env env,
Returns `napi_ok` if the API succeeded.
+**Some runtimes other than Node.js have dropped support for external buffers**.
+On runtimes other than Node.js this method may return
+`napi_no_external_buffers_allowed` to indicate that external
+buffers are not supported. One such runtime is Electron as
+described in this issue
+[electron/issues/35801](https://github.com/electron/electron/issues/35801).
+
+In order to maintain broadest compatibility with all runtimes
+you may define `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` in your addon before
+includes for the node-api headers. Doing so will hide the 2 functions
+that create external buffers. This will ensure a compilation error
+occurs if you accidentally use one of these methods.
+
This API allocates a `node::Buffer` object and initializes it with data
backed by the passed in buffer. While this is still a fully-supported data
structure, in most cases using a `TypedArray` will suffice.
diff --git a/src/js_native_api.h b/src/js_native_api.h
index 50ccf11e2405802f1c48764067b4010e8b9a0815..2ddf3780e8bde8df59b202c0913cf6434a6581ce 100644
--- a/src/js_native_api.h
+++ b/src/js_native_api.h
@@ -404,6 +404,7 @@ NAPI_EXTERN napi_status napi_create_arraybuffer(napi_env env,
size_t byte_length,
void** data,
napi_value* result);
+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
NAPI_EXTERN napi_status
napi_create_external_arraybuffer(napi_env env,
void* external_data,
@@ -411,6 +412,7 @@ napi_create_external_arraybuffer(napi_env env,
napi_finalize finalize_cb,
void* finalize_hint,
napi_value* result);
+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
NAPI_EXTERN napi_status napi_get_arraybuffer_info(napi_env env,
napi_value arraybuffer,
void** data,
diff --git a/src/js_native_api_types.h b/src/js_native_api_types.h
index 6aba06629b31543c13698dbb02b82db309587c4a..7529b853655a25dd6f945df77c9dd024a0403b26 100644
--- a/src/js_native_api_types.h
+++ b/src/js_native_api_types.h
@@ -92,7 +92,8 @@ typedef enum {
napi_date_expected,
napi_arraybuffer_expected,
napi_detachable_arraybuffer_expected,
- napi_would_deadlock // unused
+ napi_would_deadlock, // unused
+ napi_no_external_buffers_allowed
} napi_status;
// Note: when adding a new enum value to `napi_status`, please also update
// * `const int last_status` in the definition of `napi_get_last_error_info()'
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
index 1c29c43836a0c35a832e494f8eaebbbe1eee8ea4..108ba4bedbd1684b9a69834ae12347faf4670a27 100644
--- a/src/js_native_api_v8.cc
+++ b/src/js_native_api_v8.cc
@@ -721,29 +721,30 @@ void Reference::SecondPassCallback(
} // end of namespace v8impl
// Warning: Keep in-sync with napi_status enum
-static
-const char* error_messages[] = {nullptr,
- "Invalid argument",
- "An object was expected",
- "A string was expected",
- "A string or symbol was expected",
- "A function was expected",
- "A number was expected",
- "A boolean was expected",
- "An array was expected",
- "Unknown failure",
- "An exception is pending",
- "The async work item was cancelled",
- "napi_escape_handle already called on scope",
- "Invalid handle scope usage",
- "Invalid callback scope usage",
- "Thread-safe function queue is full",
- "Thread-safe function handle is closing",
- "A bigint was expected",
- "A date was expected",
- "An arraybuffer was expected",
- "A detachable arraybuffer was expected",
- "Main thread would deadlock",
+static const char* error_messages[] = {
+ nullptr,
+ "Invalid argument",
+ "An object was expected",
+ "A string was expected",
+ "A string or symbol was expected",
+ "A function was expected",
+ "A number was expected",
+ "A boolean was expected",
+ "An array was expected",
+ "Unknown failure",
+ "An exception is pending",
+ "The async work item was cancelled",
+ "napi_escape_handle already called on scope",
+ "Invalid handle scope usage",
+ "Invalid callback scope usage",
+ "Thread-safe function queue is full",
+ "Thread-safe function handle is closing",
+ "A bigint was expected",
+ "A date was expected",
+ "An arraybuffer was expected",
+ "A detachable arraybuffer was expected",
+ "Main thread would deadlock",
+ "External buffers are not allowed",
};
napi_status napi_get_last_error_info(napi_env env,
@@ -755,7 +756,7 @@ napi_status napi_get_last_error_info(napi_env env,
// message in the `napi_status` enum each time a new error message is added.
// We don't have a napi_status_last as this would result in an ABI
// change each time a message was added.
- const int last_status = napi_would_deadlock;
+ const int last_status = napi_no_external_buffers_allowed;
static_assert(
NAPI_ARRAYSIZE(error_messages) == last_status + 1,
diff --git a/src/node_api.cc b/src/node_api.cc
index 60fbe96b8ef272768736ce029bac3ff72f3c84a5..6f8575bb8f289aab041bc126b2fd5f53b1116af5 100644
--- a/src/node_api.cc
+++ b/src/node_api.cc
@@ -929,6 +929,10 @@ napi_status napi_create_external_buffer(napi_env env,
NAPI_PREAMBLE(env);
CHECK_ARG(env, result);
+#if defined(V8_ENABLE_SANDBOX)
+ return napi_set_last_error(env, napi_no_external_buffers_allowed);
+#endif
+
v8::Isolate* isolate = env->isolate;
// The finalizer object will delete itself after invoking the callback.
diff --git a/src/node_api.h b/src/node_api.h
index 1772c67c15afb2d2712b1900a584f627852e3d7e..47703198fed09a61c3e9e06fa5781d340cc39cf9 100644
--- a/src/node_api.h
+++ b/src/node_api.h
@@ -138,12 +138,14 @@ NAPI_EXTERN napi_status napi_create_buffer(napi_env env,
size_t length,
void** data,
napi_value* result);
+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
NAPI_EXTERN napi_status napi_create_external_buffer(napi_env env,
size_t length,
void* data,
napi_finalize finalize_cb,
void* finalize_hint,
napi_value* result);
+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
NAPI_EXTERN napi_status napi_create_buffer_copy(napi_env env,
size_t length,
const void* data,
diff --git a/test/js-native-api/test_general/test_general.c b/test/js-native-api/test_general/test_general.c
index 7b755ce9a9f202eaf91e5103d6c0204925f99cac..b474ab442cb763cb84ec77901da91a6f1471c946 100644
--- a/test/js-native-api/test_general/test_general.c
+++ b/test/js-native-api/test_general/test_general.c
@@ -1,3 +1,8 @@
+// we define NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED here to
+// validate that it can be used as a form of test itself. It is
+// not related to any of the other tests
+// defined in the file
+#define NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
diff --git a/test/node-api/test_general/test_general.c b/test/node-api/test_general/test_general.c
index d430e2df4f3520fddbc5ce8d260adba565e6c3c9..b8d837d5e45650fcb9ba04030721b0f51377f078 100644
--- a/test/node-api/test_general/test_general.c
+++ b/test/node-api/test_general/test_general.c
@@ -1,4 +1,9 @@
#define NAPI_EXPERIMENTAL
+// we define NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED here to validate that it can
+// be used as a form of test itself. It is
+// not related to any of the other tests
+// defined in the file
+#define NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
#include <node_api.h>
#include <stdlib.h>
#include "../../js-native-api/common.h"

View File

@@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Wed, 16 Nov 2022 13:18:23 +0900
Subject: chore: enable c++17 for native modules
V8 headers shipped since 10.4 use C++17 featuers, update the compile flags
correspondinly for native addons. C++ version in this file should be updated
following the version bump in upstream.
Next update: crbug.com/1284275
diff --git a/common.gypi b/common.gypi
index 6bf1b3395250d05cad215bd56f6efea9abc7a7aa..d6b026511acf7a69b1e86093075db30e2f518e17 100644
--- a/common.gypi
+++ b/common.gypi
@@ -308,7 +308,10 @@
],
'msvs_settings': {
'VCCLCompilerTool': {
- 'AdditionalOptions': ['/Zc:__cplusplus'],
+ 'AdditionalOptions': [
+ '/Zc:__cplusplus',
+ '-std:c++17',
+ ],
'BufferSecurityCheck': 'true',
'DebugInformationFormat': 1, # /Z7 embed info in .obj files
'ExceptionHandling': 0, # /EHsc
@@ -440,7 +443,7 @@
}],
[ 'OS in "linux freebsd openbsd solaris android aix cloudabi"', {
'cflags': [ '-Wall', '-Wextra', '-Wno-unused-parameter', ],
- 'cflags_cc': [ '-fno-rtti', '-fno-exceptions', '-std=gnu++14' ],
+ 'cflags_cc': [ '-fno-rtti', '-fno-exceptions', '-std=gnu++17' ],
'defines': [ '__STDC_FORMAT_MACROS' ],
'ldflags': [ '-rdynamic' ],
'target_conditions': [
@@ -580,7 +583,7 @@
['clang==1', {
'xcode_settings': {
'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
- 'CLANG_CXX_LANGUAGE_STANDARD': 'gnu++14', # -std=gnu++14
+ 'CLANG_CXX_LANGUAGE_STANDARD': 'gnu++17', # -std=gnu++17
'CLANG_CXX_LIBRARY': 'libc++',
},
}],
@@ -653,7 +656,7 @@
'-qASM',
],
'cflags_cc': [
- '-qxclang=-std=c++14',
+ '-qxclang=-std=c++17',
],
'ldflags': [
'-q64',

View File

@@ -0,0 +1,87 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <sattard@salesforce.com>
Date: Thu, 6 Oct 2022 04:09:16 -0700
Subject: fix: expose the built-in electron module via the ESM loader
This allows usage of `import { app } from 'electron'` and `import('electron')` natively in the browser + non-sandboxed renderer
diff --git a/lib/internal/modules/esm/get_format.js b/lib/internal/modules/esm/get_format.js
index 5ae0e17dcfb5e24a1a117c33c4d42891686e693f..619fe6cef3b02eb575410225f41d3e7d51f37b93 100644
--- a/lib/internal/modules/esm/get_format.js
+++ b/lib/internal/modules/esm/get_format.js
@@ -31,6 +31,7 @@ const protocolHandlers = ObjectAssign(ObjectCreate(null), {
'http:': getHttpProtocolModuleFormat,
'https:': getHttpProtocolModuleFormat,
'node:'() { return 'builtin'; },
+ 'electron:'() { return 'commonjs'; },
});
function getDataProtocolModuleFormat(parsed) {
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
index 3576f75f0a40a64dceb7e2649b344b83ebc04b39..314fbb78931eef154a1e47c655e2d4bafe11bac3 100644
--- a/lib/internal/modules/esm/resolve.js
+++ b/lib/internal/modules/esm/resolve.js
@@ -888,6 +888,8 @@ function parsePackageName(specifier, base) {
return { packageName, packageSubpath, isScoped };
}
+const electronSpecifiers = new SafeSet(['electron', 'electron/main', 'electron/common', 'electron/renderer']);
+
/**
* @param {string} specifier
* @param {string | URL | undefined} base
@@ -898,6 +900,10 @@ function packageResolve(specifier, base, conditions) {
if (NativeModule.canBeRequiredByUsers(specifier))
return new URL('node:' + specifier);
+ if (electronSpecifiers.has(specifier)) {
+ return new URL('electron:electron');
+ }
+
const { packageName, packageSubpath, isScoped } =
parsePackageName(specifier, base);
@@ -1099,7 +1105,7 @@ function checkIfDisallowedImport(specifier, parsed, parsedParentURL) {
function throwIfUnsupportedURLProtocol(url) {
if (url.protocol !== 'file:' && url.protocol !== 'data:' &&
- url.protocol !== 'node:') {
+ url.protocol !== 'node:' && url.protocol !== 'electron:') {
throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(url);
}
}
diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js
index d7f4c7edec63d3ce500955a37c6eac00e3e524fd..b97cac53365b121f8e232f0085ff166511c3dda3 100644
--- a/lib/internal/modules/esm/translators.js
+++ b/lib/internal/modules/esm/translators.js
@@ -155,7 +155,7 @@ translators.set('commonjs', async function commonjsStrategy(url, source,
if (!cjsParse) await initCJSParse();
const { module, exportNames } = cjsPreparseModuleExports(filename);
- const namesWithDefault = exportNames.has('default') ?
+ const namesWithDefault = filename === 'electron' ? ['default', ...Object.keys(module.exports)] : exportNames.has('default') ?
[...exportNames] : ['default', ...exportNames];
return new ModuleWrap(url, undefined, namesWithDefault, function() {
@@ -174,7 +174,7 @@ translators.set('commonjs', async function commonjsStrategy(url, source,
}
}
- for (const exportName of exportNames) {
+ for (const exportName of namesWithDefault) {
if (!ObjectPrototypeHasOwnProperty(exports, exportName) ||
exportName === 'default')
continue;
diff --git a/lib/internal/url.js b/lib/internal/url.js
index 939374a495856cf2b9c573fa98dc1895eee5e143..c37258ac29e8b7558c1f9a2af7ba6bdd0eab1355 100644
--- a/lib/internal/url.js
+++ b/lib/internal/url.js
@@ -1418,6 +1418,8 @@ function fileURLToPath(path) {
path = new URL(path);
else if (!isURLInstance(path))
throw new ERR_INVALID_ARG_TYPE('path', ['string', 'URL'], path);
+ if (path.protocol === 'electron:')
+ return 'electron';
if (path.protocol !== 'file:')
throw new ERR_INVALID_URL_SCHEME('file');
return isWindows ? getPathFromURLWin32(path) : getPathFromURLPosix(path);

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 0ff55edd47e9eaa7d9ac9912806fd29e0043a498..ad42f11b93b9e269a997f9e02e58078f03a51844 100644
--- a/src/gpu/ganesh/GrDirectContext.cpp
+++ b/src/gpu/ganesh/GrDirectContext.cpp
@@ -144,9 +144,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,2 +1,3 @@
utf-8_q_simplify_20the_20logic_20that_20converts_20the_20_1_20.patch
utf-8_q_when_20applying_20the_20omit-order-by_20optimization.patch
utf-8_q_m102-lts_20enhance_20defensive_20mode_20so_20that_20i.patch

View File

@@ -11,3 +11,14 @@ revert_runtime_dhceck_terminating_exception_in_microtasks.patch
allow_disabling_of_v8_sandboxed_pointers.patch
chore_disable_is_execution_terminating_dcheck.patch
ext-code-space_fix_coderange_allocation_logic.patch
cherry-pick-8b040cb69e96.patch
cherry-pick-2f6a2939514f.patch
cherry-pick-194bcc127f21.patch
cherry-pick-ec236fef54b8.patch
cherry-pick-80ed4b917477.patch
cherry-pick-2ac0620a5bbb.patch
cherry-pick-177e8bcd3584.patch
cherry-pick-27fa951ae4a3.patch
cherry-pick-c79148742421.patch
cherry-pick-0f481c9ddf2a.patch
cherry-pick-28b9c1c04e78.patch

View File

@@ -0,0 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Clemens Backes <clemensb@chromium.org>
Date: Thu, 15 Dec 2022 11:58:50 +0100
Subject: Merged: [wasm][turbofan] Load 32-bit values more efficiently
When loading a 32-bit value from the stack, just load 32 bit and
zero-extend them into the target register, instead of loading the full
64 bits.
As there are things to fix (see https://crbug.com/1356461), we only
enable this optimization for Wasm for now.
Also include the related fix https://crrev.com/c/4096985.
R=mslekova@chromium.org
(cherry picked from commit 2ee52447c878721c89a55a780eb689ecba6817d3)
(cherry picked from commit a38209949fcbf045231c316e2d790b8b70ccb7ef)
Bug: chromium:1395604
Change-Id: I54a2182ada6fadbfcf5565f0dc8d4f477ecff393
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4110897
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.8@{#46}
Cr-Branched-From: f1bc03fd6b4c201abd9f0fd9d51fb989150f97b9-refs/heads/10.8.168@{#1}
Cr-Branched-From: 237de893e1c0a0628a57d0f5797483d3add7f005-refs/heads/main@{#83672}
diff --git a/src/compiler/backend/x64/code-generator-x64.cc b/src/compiler/backend/x64/code-generator-x64.cc
index 9fd4635d8911716019bf0116123b85a408e247ca..86e017936bab415c003476844cb981e8ad5d1e56 100644
--- a/src/compiler/backend/x64/code-generator-x64.cc
+++ b/src/compiler/backend/x64/code-generator-x64.cc
@@ -5119,7 +5119,22 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case MoveType::kStackToRegister: {
Operand src = g.ToOperand(source);
if (source->IsStackSlot()) {
- __ movq(g.ToRegister(destination), src);
+ MachineRepresentation mr =
+ LocationOperand::cast(source)->representation();
+ const bool is_32_bit = mr == MachineRepresentation::kWord32 ||
+ mr == MachineRepresentation::kCompressed ||
+ mr == MachineRepresentation::kCompressedPointer;
+ // TODO(13581): Fix this for other code kinds (see
+ // https://crbug.com/1356461).
+ if (code_kind() == CodeKind::WASM_FUNCTION && is_32_bit) {
+ // When we need only 32 bits, move only 32 bits. Benefits:
+ // - Save a byte here and there (depending on the destination
+ // register; "movl eax, ..." is smaller than "movq rax, ...").
+ // - Safeguard against accidental decompression of compressed slots.
+ __ movl(g.ToRegister(destination), src);
+ } else {
+ __ movq(g.ToRegister(destination), src);
+ }
} else {
DCHECK(source->IsFPStackSlot());
XMMRegister dst = g.ToDoubleRegister(destination);
diff --git a/src/wasm/graph-builder-interface.cc b/src/wasm/graph-builder-interface.cc
index 3d899eded2d744731f2acfadce6f4d55b1417c4d..a9587d7548495dfdb0a6cf43ab22a3d06d1a76e7 100644
--- a/src/wasm/graph-builder-interface.cc
+++ b/src/wasm/graph-builder-interface.cc
@@ -2061,7 +2061,7 @@ class WasmGraphBuildingInterface {
if (exception_value != nullptr) {
// TODO(manoskouk): Can we assign a wasm type to the exception value?
*exception_value = builder_->LoopExitValue(
- *exception_value, MachineRepresentation::kWord32);
+ *exception_value, MachineRepresentation::kTaggedPointer);
}
if (wrap_exit_values) {
WrapLocalsAtLoopExit(decoder, control);

View File

@@ -0,0 +1,144 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Darius M <dmercadier@chromium.org>
Date: Mon, 7 Nov 2022 08:40:11 +0100
Subject: Merged: [compiler] fix bug in inlining of Array.At
The inlined version of Array.At was only checking the kind of the
maps, rather than the maps themselves. When the feedback was
containing an array map that "supports_fast_array_iteration", then its
kind was added to the list of supported kinds. If this Array.at was
later called with a non-array map with the same kind, then the object
would be wrongly treated as an array.
This is now fixed: inlining Array.at checks the maps directly rather
than only their kinds.
Bug: chromium:1377775
(cherry picked from commit 0ce27310674150b46605c1e226b8f1a2503bac8c)
Change-Id: I2398f2f7a1ea37808962ba5eb3d1fe00a54fd614
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3990747
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.6@{#49}
Cr-Branched-From: 41bc7435693fbce8ef86753cd9239e30550a3e2d-refs/heads/10.6.194@{#1}
Cr-Branched-From: d5f29b929ce7746409201d77f44048f3e9529b40-refs/heads/main@{#82548}
diff --git a/src/compiler/js-call-reducer.cc b/src/compiler/js-call-reducer.cc
index 65d3dfe1db8e690a949f6ea3140dda4813a0b0d5..10f3301e3a10d215d731e8bd7d2ec67537d66989 100644
--- a/src/compiler/js-call-reducer.cc
+++ b/src/compiler/js-call-reducer.cc
@@ -719,9 +719,8 @@ class IteratingArrayBuiltinReducerAssembler : public JSCallReducerAssembler {
MapInference* inference, const bool has_stability_dependency,
ElementsKind kind, const SharedFunctionInfoRef& shared,
const NativeContextRef& native_context, ArrayEverySomeVariant variant);
- TNode<Object> ReduceArrayPrototypeAt(ZoneVector<ElementsKind> kinds,
- bool needs_fallback_builtin_call,
- Node* receiver_kind);
+ TNode<Object> ReduceArrayPrototypeAt(ZoneVector<const MapRef*> kinds,
+ bool needs_fallback_builtin_call);
TNode<Object> ReduceArrayPrototypeIndexOfIncludes(
ElementsKind kind, ArrayIndexOfIncludesVariant variant);
@@ -1331,24 +1330,26 @@ TNode<String> JSCallReducerAssembler::ReduceStringPrototypeSlice() {
}
TNode<Object> IteratingArrayBuiltinReducerAssembler::ReduceArrayPrototypeAt(
- ZoneVector<ElementsKind> kinds, bool needs_fallback_builtin_call,
- Node* receiver_kind) {
+ ZoneVector<const MapRef*> maps, bool needs_fallback_builtin_call) {
TNode<JSArray> receiver = ReceiverInputAs<JSArray>();
TNode<Object> index = ArgumentOrZero(0);
TNode<Number> index_num = CheckSmi(index);
TNode<FixedArrayBase> elements = LoadElements(receiver);
+ TNode<Map> receiver_map =
+ TNode<Map>::UncheckedCast(LoadField(AccessBuilder::ForMap(), receiver));
+
auto out = MakeLabel(MachineRepresentation::kTagged);
- for (ElementsKind kind : kinds) {
+ for (const MapRef* map : maps) {
+ DCHECK(map->supports_fast_array_iteration());
auto correct_map_label = MakeLabel(), wrong_map_label = MakeLabel();
- Branch(NumberEqual(TNode<Number>::UncheckedCast(receiver_kind),
- NumberConstant(kind)),
- &correct_map_label, &wrong_map_label);
+ TNode<Boolean> is_map_equal = ReferenceEqual(receiver_map, Constant(*map));
+ Branch(is_map_equal, &correct_map_label, &wrong_map_label);
Bind(&correct_map_label);
- TNode<Number> length = LoadJSArrayLength(receiver, kind);
+ TNode<Number> length = LoadJSArrayLength(receiver, map->elements_kind());
// If index is less than 0, then subtract from length.
TNode<Boolean> cond = NumberLessThan(index_num, ZeroConstant());
@@ -1367,15 +1368,16 @@ TNode<Object> IteratingArrayBuiltinReducerAssembler::ReduceArrayPrototypeAt(
// Retrieving element at index.
TNode<Object> element = LoadElement<Object>(
- AccessBuilder::ForFixedArrayElement(kind), elements, real_index_num);
- if (IsHoleyElementsKind(kind)) {
+ AccessBuilder::ForFixedArrayElement(map->elements_kind()), elements,
+ real_index_num);
+ if (IsHoleyElementsKind(map->elements_kind())) {
// This case is needed in particular for HOLEY_DOUBLE_ELEMENTS: raw
// doubles are stored in the FixedDoubleArray, and need to be converted to
// HeapNumber or to Smi so that this function can return an Object. The
// automatic converstion performed by
// RepresentationChanger::GetTaggedRepresentationFor does not handle
// holes, so we convert manually a potential hole here.
- element = TryConvertHoleToUndefined(element, kind);
+ element = TryConvertHoleToUndefined(element, map->elements_kind());
}
Goto(&out, element);
@@ -5639,25 +5641,22 @@ Reduction JSCallReducer::ReduceArrayPrototypeAt(Node* node) {
MapInference inference(broker(), receiver, effect);
if (!inference.HaveMaps()) return NoChange();
- // Collecting kinds
- ZoneVector<ElementsKind> kinds(broker()->zone());
+ // Collecting maps, and checking if a fallback builtin call will be required
+ // (it is required if at least one map doesn't support fast array iteration).
+ ZoneVector<const MapRef*> maps(broker()->zone());
bool needs_fallback_builtin_call = false;
for (const MapRef& map : inference.GetMaps()) {
if (map.supports_fast_array_iteration()) {
- ElementsKind kind = map.elements_kind();
- // Checking that |kind| isn't already in |kinds|. Using std::find should
- // be fast enough since |kinds| can contain at most 4 items.
- if (std::find(kinds.begin(), kinds.end(), kind) == kinds.end()) {
- kinds.push_back(kind);
- }
+ maps.push_back(&map);
} else {
needs_fallback_builtin_call = true;
}
}
+
inference.RelyOnMapsPreferStability(dependencies(), jsgraph(), &effect,
control, p.feedback());
- if (kinds.empty()) {
+ if (maps.empty()) {
// No map in the feedback supports fast iteration. Keeping the builtin call.
return NoChange();
}
@@ -5666,13 +5665,11 @@ Reduction JSCallReducer::ReduceArrayPrototypeAt(Node* node) {
return NoChange();
}
- Node* receiver_kind = LoadReceiverElementsKind(receiver, &effect, control);
-
IteratingArrayBuiltinReducerAssembler a(this, node);
a.InitializeEffectControl(effect, control);
- TNode<Object> subgraph = a.ReduceArrayPrototypeAt(
- kinds, needs_fallback_builtin_call, receiver_kind);
+ TNode<Object> subgraph =
+ a.ReduceArrayPrototypeAt(maps, needs_fallback_builtin_call);
return ReplaceWithSubgraph(&a, subgraph);
}

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 4fb04ae2bd8960deb7e978641d3cf75297f72bda..45aea59373067d1f0fe63d2fcc7059b788c8277b 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)
@@ -1115,6 +1152,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 72ee5773abfcf344e3964d58ea855461ca1ca79d..e0f4eca359b2f7cdca326702d0181b83d3dc322c 100644
--- a/src/compiler/compilation-dependencies.h
+++ b/src/compiler/compilation-dependencies.h
@@ -94,6 +94,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 1b4755e2db290701740cbcbaf6fcab2154c68132..241186706d9388fe6127c5cf1d1e6befecf229f7 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,209 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Toon Verwaest <verwaest@chromium.org>
Date: Wed, 30 Nov 2022 15:07:26 +0100
Subject: Fix eval tracking
Due to mismatch in strictness we otherwise invalidly mark scopes as
calling sloppy eval.
Bug: chromium:1394403
Change-Id: Iece45df87f171616a2917c2aba5540636880a7c6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4066044
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84575}
diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc
index 679472c7c62916727735cbbcd7c6caf1fa7ae8bb..54709de5b747f0c6f450943e110c4f82b97c29ca 100644
--- a/src/ast/scopes.cc
+++ b/src/ast/scopes.cc
@@ -888,9 +888,8 @@ void DeclarationScope::AddLocal(Variable* var) {
}
void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
- DCHECK(!IsCleared());
- DCHECK_EQ(new_parent, outer_scope_and_calls_eval_.GetPointer()->inner_scope_);
- DCHECK_EQ(new_parent->outer_scope_, outer_scope_and_calls_eval_.GetPointer());
+ DCHECK_EQ(new_parent, outer_scope_->inner_scope_);
+ DCHECK_EQ(new_parent->outer_scope_, outer_scope_);
DCHECK_EQ(new_parent, new_parent->GetClosureScope());
DCHECK_NULL(new_parent->inner_scope_);
DCHECK(new_parent->unresolved_list_.is_empty());
@@ -915,12 +914,11 @@ void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
new_parent->sibling_ = top_inner_scope_;
}
- Scope* outer_scope = outer_scope_and_calls_eval_.GetPointer();
- new_parent->unresolved_list_.MoveTail(&outer_scope->unresolved_list_,
+ new_parent->unresolved_list_.MoveTail(&outer_scope_->unresolved_list_,
top_unresolved_);
// Move temporaries allocated for complex parameter initializers.
- DeclarationScope* outer_closure = outer_scope->GetClosureScope();
+ DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
for (auto it = top_local_; it != outer_closure->locals()->end(); ++it) {
Variable* local = *it;
DCHECK_EQ(VariableMode::kTemporary, local->mode());
@@ -932,16 +930,10 @@ void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
outer_closure->locals_.Rewind(top_local_);
// Move eval calls since Snapshot's creation into new_parent.
- if (outer_scope_and_calls_eval_->calls_eval_) {
- new_parent->RecordDeclarationScopeEvalCall();
- new_parent->inner_scope_calls_eval_ = true;
+ if (outer_scope_->calls_eval_) {
+ new_parent->RecordEvalCall();
+ declaration_scope_->sloppy_eval_can_extend_vars_ = false;
}
-
- // We are in the arrow function case. The calls eval we may have recorded
- // is intended for the inner scope and we should simply restore the
- // original "calls eval" flag of the outer scope.
- RestoreEvalFlag();
- Clear();
}
void Scope::ReplaceOuterScope(Scope* outer) {
@@ -2579,6 +2571,9 @@ void Scope::AllocateVariablesRecursively() {
this->ForEach([](Scope* scope) -> Iteration {
DCHECK(!scope->already_resolved_);
if (WasLazilyParsed(scope)) return Iteration::kContinue;
+ if (scope->sloppy_eval_can_extend_vars_) {
+ scope->num_heap_slots_ = Context::MIN_CONTEXT_EXTENDED_SLOTS;
+ }
DCHECK_EQ(scope->ContextHeaderLength(), scope->num_heap_slots_);
// Allocate variables for this scope.
diff --git a/src/ast/scopes.h b/src/ast/scopes.h
index 9f4970931454e78468eba7bc2cf01289fa598289..29e329833f247d901e20fb227ceedbdd2ee4127a 100644
--- a/src/ast/scopes.h
+++ b/src/ast/scopes.h
@@ -112,12 +112,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
class Snapshot final {
public:
- Snapshot()
- : outer_scope_and_calls_eval_(nullptr, false),
- top_unresolved_(),
- top_local_() {
- DCHECK(IsCleared());
- }
inline explicit Snapshot(Scope* scope);
// Disallow copy and move.
@@ -125,45 +119,31 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
Snapshot(Snapshot&&) = delete;
~Snapshot() {
- // If we're still active, there was no arrow function. In that case outer
- // calls eval if it already called eval before this snapshot started, or
- // if the code during the snapshot called eval.
- if (!IsCleared() && outer_scope_and_calls_eval_.GetPayload()) {
- RestoreEvalFlag();
+ // Restore eval flags from before the scope was active.
+ if (sloppy_eval_can_extend_vars_) {
+ declaration_scope_->sloppy_eval_can_extend_vars_ = true;
}
- }
-
- void RestoreEvalFlag() {
- if (outer_scope_and_calls_eval_.GetPayload()) {
- // This recreates both calls_eval and sloppy_eval_can_extend_vars.
- outer_scope_and_calls_eval_.GetPointer()->RecordEvalCall();
+ if (calls_eval_) {
+ outer_scope_->calls_eval_ = true;
}
}
void Reparent(DeclarationScope* new_parent);
- bool IsCleared() const {
- return outer_scope_and_calls_eval_.GetPointer() == nullptr;
- }
-
- void Clear() {
- outer_scope_and_calls_eval_.SetPointer(nullptr);
-#ifdef DEBUG
- outer_scope_and_calls_eval_.SetPayload(false);
- top_inner_scope_ = nullptr;
- top_local_ = base::ThreadedList<Variable>::Iterator();
- top_unresolved_ = UnresolvedList::Iterator();
-#endif
- }
private:
- // During tracking calls_eval caches whether the outer scope called eval.
- // Upon move assignment we store whether the new inner scope calls eval into
- // the move target calls_eval bit, and restore calls eval on the outer
- // scope.
- base::PointerWithPayload<Scope, bool, 1> outer_scope_and_calls_eval_;
+ Scope* outer_scope_;
+ Scope* declaration_scope_;
Scope* top_inner_scope_;
UnresolvedList::Iterator top_unresolved_;
base::ThreadedList<Variable>::Iterator top_local_;
+ // While the scope is active, the scope caches the flag values for
+ // outer_scope_ / declaration_scope_ they can be used to know what happened
+ // while parsing the arrow head. If this turns out to be an arrow head, new
+ // values on the respective scopes will be cleared and moved to the inner
+ // scope. Otherwise the cached flags will be merged with the flags from the
+ // arrow head.
+ bool calls_eval_;
+ bool sloppy_eval_can_extend_vars_;
};
enum class DeserializationMode { kIncludingVariables, kScopesOnly };
@@ -909,8 +889,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
void RecordDeclarationScopeEvalCall() {
calls_eval_ = true;
- // If this isn't a sloppy eval, we don't care about it.
- if (language_mode() != LanguageMode::kSloppy) return;
+ // The caller already checked whether we're in sloppy mode.
+ CHECK(is_sloppy(language_mode()));
// Sloppy eval in script scopes can only introduce global variables anyway,
// so we don't care that it calls sloppy eval.
@@ -944,7 +924,6 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
}
sloppy_eval_can_extend_vars_ = true;
- num_heap_slots_ = Context::MIN_CONTEXT_EXTENDED_SLOTS;
}
bool sloppy_eval_can_extend_vars() const {
@@ -1369,7 +1348,9 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
void Scope::RecordEvalCall() {
calls_eval_ = true;
- GetDeclarationScope()->RecordDeclarationScopeEvalCall();
+ if (is_sloppy(language_mode())) {
+ GetDeclarationScope()->RecordDeclarationScopeEvalCall();
+ }
RecordInnerScopeEvalCall();
// The eval contents might access "super" (if it's inside a function that
// binds super).
@@ -1382,14 +1363,18 @@ void Scope::RecordEvalCall() {
}
Scope::Snapshot::Snapshot(Scope* scope)
- : outer_scope_and_calls_eval_(scope, scope->calls_eval_),
+ : outer_scope_(scope),
+ declaration_scope_(scope->GetDeclarationScope()),
top_inner_scope_(scope->inner_scope_),
top_unresolved_(scope->unresolved_list_.end()),
- top_local_(scope->GetClosureScope()->locals_.end()) {
- // Reset in order to record eval calls during this Snapshot's lifetime.
- outer_scope_and_calls_eval_.GetPointer()->calls_eval_ = false;
- outer_scope_and_calls_eval_.GetPointer()->sloppy_eval_can_extend_vars_ =
- false;
+ top_local_(scope->GetClosureScope()->locals_.end()),
+ calls_eval_(outer_scope_->calls_eval_),
+ sloppy_eval_can_extend_vars_(
+ declaration_scope_->sloppy_eval_can_extend_vars_) {
+ // Reset in order to record (sloppy) eval calls during this Snapshot's
+ // lifetime.
+ outer_scope_->calls_eval_ = false;
+ declaration_scope_->sloppy_eval_can_extend_vars_ = false;
}
class ModuleScope final : public DeclarationScope {

View File

@@ -0,0 +1,77 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Clemens Backes <clemensb@chromium.org>
Date: Tue, 13 Dec 2022 22:37:27 +0100
Subject: Merged: [arm] Do not emit the constant pool before a branch
After computing the branch offset but before emitting the actual branch,
we should not emit a constant pool. Otherwise the previously computed
offset would be off.
Instead of handling this indirectly via the Assembler::branch_offset
method, do this directly in the Assembler::b method (and friends), so it
is not missed on other call sites.
R=nicohartmann@chromium.org
(cherry picked from commit 9be597d194e108ba718610b9a611fe19a0fbfde5)
Bug: chromium:1399424
Change-Id: Ie30ba70508b4fb8913f79e049a33108608915704
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4118864
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.8@{#48}
Cr-Branched-From: f1bc03fd6b4c201abd9f0fd9d51fb989150f97b9-refs/heads/10.8.168@{#1}
Cr-Branched-From: 237de893e1c0a0628a57d0f5797483d3add7f005-refs/heads/main@{#83672}
diff --git a/src/codegen/arm/assembler-arm.cc b/src/codegen/arm/assembler-arm.cc
index 645edb17a4892aec70f0221cec889996a6868242..a95d4df308fd4651093a4911ad1c50226e059ebb 100644
--- a/src/codegen/arm/assembler-arm.cc
+++ b/src/codegen/arm/assembler-arm.cc
@@ -1462,10 +1462,6 @@ int Assembler::branch_offset(Label* L) {
L->link_to(pc_offset());
}
- // Block the emission of the constant pool, since the branch instruction must
- // be emitted at the pc offset recorded by the label.
- if (!is_const_pool_blocked()) BlockConstPoolFor(1);
-
return target_pos - (pc_offset() + Instruction::kPcLoadDelta);
}
@@ -1476,6 +1472,11 @@ void Assembler::b(int branch_offset, Condition cond, RelocInfo::Mode rmode) {
int imm24 = branch_offset >> 2;
const bool b_imm_check = is_int24(imm24);
CHECK(b_imm_check);
+
+ // Block the emission of the constant pool before the next instruction.
+ // Otherwise the passed-in branch offset would be off.
+ BlockConstPoolFor(1);
+
emit(cond | B27 | B25 | (imm24 & kImm24Mask));
if (cond == al) {
@@ -1490,6 +1491,11 @@ void Assembler::bl(int branch_offset, Condition cond, RelocInfo::Mode rmode) {
int imm24 = branch_offset >> 2;
const bool bl_imm_check = is_int24(imm24);
CHECK(bl_imm_check);
+
+ // Block the emission of the constant pool before the next instruction.
+ // Otherwise the passed-in branch offset would be off.
+ BlockConstPoolFor(1);
+
emit(cond | B27 | B25 | B24 | (imm24 & kImm24Mask));
}
@@ -1499,6 +1505,11 @@ void Assembler::blx(int branch_offset) {
int imm24 = branch_offset >> 2;
const bool blx_imm_check = is_int24(imm24);
CHECK(blx_imm_check);
+
+ // Block the emission of the constant pool before the next instruction.
+ // Otherwise the passed-in branch offset would be off.
+ BlockConstPoolFor(1);
+
emit(kSpecialCondition | B27 | B25 | h | (imm24 & kImm24Mask));
}

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 5b3256fe6d1c431adf4c10c84dfa9340d4e99754..3d899eded2d744731f2acfadce6f4d55b1417c4d 100644
--- a/src/wasm/graph-builder-interface.cc
+++ b/src/wasm/graph-builder-interface.cc
@@ -91,6 +91,7 @@ class WasmGraphBuildingInterface {
struct TryInfo : public ZoneObject {
SsaEnv* catch_env;
TFNode* exception = nullptr;
+ bool first_catch = true;
bool might_throw() const { return exception != nullptr; }
@@ -937,6 +938,10 @@ class WasmGraphBuildingInterface {
TFNode* exception = block->try_info->exception;
SetEnv(block->try_info->catch_env);
+ if (block->try_info->first_catch) {
+ LoadContextIntoSsa(ssa_env_, decoder);
+ block->try_info->first_catch = false;
+ }
TFNode* if_catch = nullptr;
TFNode* if_no_catch = nullptr;
@@ -1014,6 +1019,9 @@ class WasmGraphBuildingInterface {
}
SetEnv(block->try_info->catch_env);
+ if (block->try_info->first_catch) {
+ LoadContextIntoSsa(ssa_env_, decoder);
+ }
}
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,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 5825045052be450516b30e09a2cdf3e55c42c70e..909a6781d60729d7e21d9f8dfe265ff853855ed3 100644
--- a/src/compiler/effect-control-linearizer.cc
+++ b/src/compiler/effect-control-linearizer.cc
@@ -5380,6 +5380,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);
@@ -5396,8 +5398,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}.
@@ -5411,8 +5413,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);
}
}
@@ -5420,9 +5422,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.
@@ -5450,27 +5449,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 2b269516dd302c06a3eebc1c9d70f4d36612b942..3f768f8f5adcc1bfd1d64e68c638a5bf2e737051 100644
--- a/src/wasm/baseline/liftoff-compiler.cc
+++ b/src/wasm/baseline/liftoff-compiler.cc
@@ -1421,9 +1421,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
@@ -1435,9 +1437,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,122 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shu-yu Guo <syg@chromium.org>
Date: Fri, 28 Oct 2022 10:21:27 -0700
Subject: Merged: Reland "[Promise.any] Fix errors allocation"
Bug: chromium:1379054
(cherry picked from commit 8b35091b2d244c975975e1c78e4cd09cb479b5dc)
Change-Id: Iec8f8bb51f4434d6ae86887cf742f2883a9b7bef
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4004804
Reviewed-by: Adam Klein <adamk@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.8@{#34}
Cr-Branched-From: f1bc03fd6b4c201abd9f0fd9d51fb989150f97b9-refs/heads/10.8.168@{#1}
Cr-Branched-From: 237de893e1c0a0628a57d0f5797483d3add7f005-refs/heads/main@{#83672}
diff --git a/include/v8-version.h b/include/v8-version.h
index 7baa3bf9b725652ddaac1a3d39dd96a3520b9f26..fb1097518be399c6665d53c2be79ec81a210de71 100644
--- a/include/v8-version.h
+++ b/include/v8-version.h
@@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 10
#define V8_MINOR_VERSION 4
#define V8_BUILD_NUMBER 132
-#define V8_PATCH_LEVEL 24
+#define V8_PATCH_LEVEL 25
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/builtins/promise-any.tq b/src/builtins/promise-any.tq
index ffb285a06a83557d8657aef6c04acc5c65513a62..7e707e649f11bc946a6d1173180d7293fe94d8ce 100644
--- a/src/builtins/promise-any.tq
+++ b/src/builtins/promise-any.tq
@@ -119,7 +119,19 @@ PromiseAnyRejectElementClosure(
kPromiseAnyRejectElementRemainingSlot);
// 9. Set errors[index] to x.
- const newCapacity = IntPtrMax(SmiUntag(remainingElementsCount), index + 1);
+
+ // The max computation below is an optimization to avoid excessive allocations
+ // in the case of input promises being asynchronously rejected in ascending
+ // index order.
+ //
+ // Note that subtracting 1 from remainingElementsCount is intentional. The
+ // value of remainingElementsCount is 1 larger than the actual value during
+ // iteration. So in the case of synchronous rejection, newCapacity is the
+ // correct size by subtracting 1. In the case of asynchronous rejection this
+ // is 1 smaller than the correct size, but is not incorrect as it is maxed
+ // with index + 1.
+ const newCapacity =
+ IntPtrMax(SmiUntag(remainingElementsCount) - 1, index + 1);
if (newCapacity > errors.length_intptr) deferred {
errors = ExtractFixedArray(errors, 0, errors.length_intptr, newCapacity);
*ContextSlot(
@@ -306,6 +318,7 @@ Reject(JSAny) {
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementErrorsSlot);
+ check(errors.length == index - 1);
const error = ConstructAggregateError(errors);
// 3. Return ThrowCompletion(error).
goto Reject(error);
diff --git a/tools/v8heapconst.py b/tools/v8heapconst.py
index 993785ec032917ba4004bc96366e55230dd60dbb..578388b5bb44672b000b95cdc89f573cbda72a00 100644
--- a/tools/v8heapconst.py
+++ b/tools/v8heapconst.py
@@ -537,30 +537,30 @@ KNOWN_OBJECTS = {
("old_space", 0x04b35): "StringSplitCache",
("old_space", 0x04f3d): "RegExpMultipleCache",
("old_space", 0x05345): "BuiltinsConstantsTable",
- ("old_space", 0x05781): "AsyncFunctionAwaitRejectSharedFun",
- ("old_space", 0x057a5): "AsyncFunctionAwaitResolveSharedFun",
- ("old_space", 0x057c9): "AsyncGeneratorAwaitRejectSharedFun",
- ("old_space", 0x057ed): "AsyncGeneratorAwaitResolveSharedFun",
- ("old_space", 0x05811): "AsyncGeneratorYieldResolveSharedFun",
- ("old_space", 0x05835): "AsyncGeneratorReturnResolveSharedFun",
- ("old_space", 0x05859): "AsyncGeneratorReturnClosedRejectSharedFun",
- ("old_space", 0x0587d): "AsyncGeneratorReturnClosedResolveSharedFun",
- ("old_space", 0x058a1): "AsyncIteratorValueUnwrapSharedFun",
- ("old_space", 0x058c5): "PromiseAllResolveElementSharedFun",
- ("old_space", 0x058e9): "PromiseAllSettledResolveElementSharedFun",
- ("old_space", 0x0590d): "PromiseAllSettledRejectElementSharedFun",
- ("old_space", 0x05931): "PromiseAnyRejectElementSharedFun",
- ("old_space", 0x05955): "PromiseCapabilityDefaultRejectSharedFun",
- ("old_space", 0x05979): "PromiseCapabilityDefaultResolveSharedFun",
- ("old_space", 0x0599d): "PromiseCatchFinallySharedFun",
- ("old_space", 0x059c1): "PromiseGetCapabilitiesExecutorSharedFun",
- ("old_space", 0x059e5): "PromiseThenFinallySharedFun",
- ("old_space", 0x05a09): "PromiseThrowerFinallySharedFun",
- ("old_space", 0x05a2d): "PromiseValueThunkFinallySharedFun",
- ("old_space", 0x05a51): "ProxyRevokeSharedFun",
- ("old_space", 0x05a75): "ShadowRealmImportValueFulfilledSFI",
- ("old_space", 0x05a99): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
- ("old_space", 0x05abd): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
+ ("old_space", 0x05785): "AsyncFunctionAwaitRejectSharedFun",
+ ("old_space", 0x057a9): "AsyncFunctionAwaitResolveSharedFun",
+ ("old_space", 0x057cd): "AsyncGeneratorAwaitRejectSharedFun",
+ ("old_space", 0x057f1): "AsyncGeneratorAwaitResolveSharedFun",
+ ("old_space", 0x05815): "AsyncGeneratorYieldResolveSharedFun",
+ ("old_space", 0x05839): "AsyncGeneratorReturnResolveSharedFun",
+ ("old_space", 0x0585d): "AsyncGeneratorReturnClosedRejectSharedFun",
+ ("old_space", 0x05881): "AsyncGeneratorReturnClosedResolveSharedFun",
+ ("old_space", 0x058a5): "AsyncIteratorValueUnwrapSharedFun",
+ ("old_space", 0x058c9): "PromiseAllResolveElementSharedFun",
+ ("old_space", 0x058ed): "PromiseAllSettledResolveElementSharedFun",
+ ("old_space", 0x05911): "PromiseAllSettledRejectElementSharedFun",
+ ("old_space", 0x05935): "PromiseAnyRejectElementSharedFun",
+ ("old_space", 0x05959): "PromiseCapabilityDefaultRejectSharedFun",
+ ("old_space", 0x0597d): "PromiseCapabilityDefaultResolveSharedFun",
+ ("old_space", 0x059a1): "PromiseCatchFinallySharedFun",
+ ("old_space", 0x059c5): "PromiseGetCapabilitiesExecutorSharedFun",
+ ("old_space", 0x059e9): "PromiseThenFinallySharedFun",
+ ("old_space", 0x05a0d): "PromiseThrowerFinallySharedFun",
+ ("old_space", 0x05a31): "PromiseValueThunkFinallySharedFun",
+ ("old_space", 0x05a55): "ProxyRevokeSharedFun",
+ ("old_space", 0x05a79): "ShadowRealmImportValueFulfilledSFI",
+ ("old_space", 0x05a9d): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
+ ("old_space", 0x05ac1): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
}
# Lower 32 bits of first page addresses for various heap spaces.

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 307bf44cf42381ec820221806fbbc5705d71de3c..237734929f3e71e05312981506bb0735631b9451 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

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