Compare commits

..

119 Commits

Author SHA1 Message Date
Pedro Pontes
5b0665f4ae chore: cherry-pick aeec1ba5893d from chromium (#37482)
* chore: [21-x-y] cherry-pick aeec1ba5893d 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-03-08 21:42:26 -05:00
Pedro Pontes
48247343c5 chore: cherry-pick 218b56e51638 from webrtc (#37486)
* chore: cherry-pick 218b56e51638 from webrtc

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-03-07 21:35:58 +01:00
Pedro Pontes
d0edcc25e3 chore: cherry-pick 06851790480e from chromium (#37484)
* chore: cherry-pick 06851790480e 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-03-07 21:35:44 +01:00
Pedro Pontes
7ef42017e1 chore: cherry-pick e79b89b47dac from chromium (#37480)
* chore: [21-x-y] cherry-pick e79b89b47dac 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-03-06 16:47:24 +01:00
Pedro Pontes
fbedad73ce chore: cherry-pick 999cc7185e93 and 0f0b3a54c53c from chromium (#37478)
* chore: [21-x-y] cherry-pick 999cc7185e93 and 0f0b3a54c53c from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-03-06 14:33:13 +01:00
trop[bot]
73cd1a880b fix: nodeIntegrationInWorker fails to boot in AudioWorklets (#37103)
* fix: nodeIntegrationInWorker in AudioWorklets

Co-authored-by: Jeremy Rose <jeremya@chromium.org>

* fix: typescript version issue

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-02-21 11:45:14 +01:00
Keeley Hammond
334627ce74 chore: cherry-pick e0efbd45ea74 from webrtc (#37299)
* chore: cherry-pick e0efbd45ea74 from webrtc

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-02-20 13:12:58 +01:00
trop[bot]
e7791771ca chore: update https://cs.chromium.org/ links to https://source.chromium.org/ (#37235)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-02-13 16:33:05 +09:00
John Kleinschmidt
2223b295df ci: update appveyor image (21-x-y) (#37230)
ci:update appveyor image

 (cherry picked from commit 454dc6a)
2023-02-11 19:21:05 -05:00
Keeley Hammond
90d51ea331 chore: cherry-pick d652130c4bc2 from chromium (#37170)
* chore: cherry-pick d652130c4bc2 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-02-08 15:27:03 +01:00
Milan Burda
2a9691fd3f fix: expose native bindings by process type (#36141)
fix: expose native bindings by process type (#35949)
2023-02-08 14:57:29 +01:00
trop[bot]
40cbdd340d fix: enable basic a11y when voice control is active (#37144)
* fix: enable basic a11y when voice control is active

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

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

* Update shell/browser/mac/electron_application.mm

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Robo <hop2deep@gmail.com>
2023-02-07 16:07:54 -05:00
trop[bot]
156a0cd12f docs: remove invalid appcache value from storages in clearStorageData() (#37106)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-02-03 09:47:38 +01:00
Keeley Hammond
27856acfdd chore: cherry-pick ca2b108a0f1f from chromium (#37057)
* chore: [21-x-y] cherry-pick ca2b108a0f1f from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-02-02 20:53:44 +09:00
trop[bot]
cb5d93e9a7 feat: enable whole-program optimization native modules by default (#37048)
* feat: enable whole-program optimization

Enable whole-program optimization in electron native modules by default.

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

* pass --with-ltcg to configure.py instead of setting variable

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

* enable ltcg only on windows

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Kyrylo Hrechykhin <khrechykhin@microsoft.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-01-31 18:02:29 -08:00
trop[bot]
751fc04502 ci: ensure correct ninja is used (#37070)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-01-31 17:13:37 -05:00
Keeley Hammond
ee5b2523f7 chore: cherry-pick 57c54ae221d6 from chromium (#37023)
chore: [21-x-y] cherry-pick 57c54ae221d6 from chromium
2023-01-26 17:27:39 +09:00
Pedro Pontes
820bc2a499 chore: cherry-pick 0d4862e31aca and c4e7fe2f2e1b from chromium (#36586)
* chore: [21-x-y] cherry-pick 0d4862e31aca and 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>
2023-01-24 09:00:52 +01:00
trop[bot]
b110a19358 fix: handle null/undefined options for fs.readdir (#36846)
* fix: handle null/undefined options for fs.readdir (#34764)

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

* chore: remove optional chaining

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-01-23 16:22:52 +09:00
trop[bot]
418605e0fb fix: webview background color on reload (#36939)
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>
2023-01-19 09:55:17 +01:00
trop[bot]
a571cfdf8c feat: add label property to Display objects (#36931)
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-19 15:59:05 +09:00
John Kleinschmidt
19e35495ee ci: run WOA tests on AppVeyor (21-x-y) (#36928)
ci: run WOA tests on AppVeyor
2023-01-18 12:12:32 +01:00
trop[bot]
cfac858d65 docs: add missing window-placement permission value to setPermissionRequestHandler() (#36905)
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:25:23 -05:00
trop[bot]
545fd1c287 fix: Cmd+Tab not working when exiting kiosk mode (#36919)
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>
2023-01-17 20:37:19 +09:00
Pedro Pontes
c73577ca99 chore: cherry-pick 43637378b14e from chromium (#36885)
* chore: cherry-pick 43637378b14e from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-01-13 19:11:34 +09:00
trop[bot]
82ff0acb11 fix: use the process cache to reduce the memory for asar file (#36663)
* fix: use the process cache to reduce the memory for asar file

Co-authored-by: webster.xu <webster.xu@ringcentral.com>

* Update shell/common/api/electron_api_asar.cc

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: webster.xu <webster.xu@ringcentral.com>
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2023-01-13 19:10:59 +09:00
Keeley Hammond
5d530d31f4 ci: bake appveyor images automatically, run sync on depshash change (#36484)
* 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: install VSC++ tools on bake, pin Node 16

* use newest baked image

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-01-12 17:51:56 -05:00
Pedro Pontes
e9b5cd7d2e chore: cherry-pick 0f481c9ddf2a from v8 (#36882)
* chore: cherry-pick 0f481c9ddf2a from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-01-12 15:18:29 +01:00
Pedro Pontes
61af436d78 chore: cherry-pick 28b9c1c04e78 from v8 (#36879)
* chore: cherry-pick 28b9c1c04e78 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-01-12 11:58:36 +01:00
trop[bot]
d1e9dfdb75 build: migrate patch-up to use app creds (#36868)
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>
2023-01-11 20:22:38 +01:00
trop[bot]
54c11f7b10 fix: RTL WindowButtonsProxy buttons (#36852)
* fix: RTL WindowButtonsProxy buttons

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

* chore: address review feedback

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>
2023-01-11 11:55:59 +01:00
Pedro Pontes
5698beef8f chore: [21-x-y] reland cherry-pick c79148742421 from v8 (#36821)
chore: [21-x-y] cherry-pick c79148742421 from v8
2023-01-10 14:26:50 +01:00
trop[bot]
846d6570ee docs: fix loadExtension example (#36498)
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>
2023-01-10 12:16:08 +01:00
trop[bot]
023b4bb51f docs: fix link in breaking-changes.md (#36837)
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>
2023-01-10 09:37:24 +09:00
Pedro Pontes
bd78e092d4 revert: chore: cherry-pick c79148742421 from v8 (#36769)
Revert "chore: cherry-pick c79148742421 from v8 (#36580)"

This reverts commit 5abed6e890.
2023-01-05 13:22:06 -05:00
trop[bot]
fa77a9da46 fix: rename WebSwapCGLLayer to WebSwapCGLLayerChromium (#36798) 2023-01-05 13:33:11 +01:00
trop[bot]
067c4c4dc6 fix: focus rings with multiple buttons in showMessageBox (#36801)
fix: focus rings with multiple buttons in messageBox

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>
2023-01-05 13:32:39 +01:00
Pedro Pontes
8a150a2a3f chore: cherry-pick 77208afba04d from chromium (#36681)
* chore: [21-x-y] cherry-pick 77208afba04d from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2023-01-04 10:50:07 -05:00
Pedro Pontes
fdf96debe1 chore: cherry-pick 65ad70274d4b from chromium (#36578)
* chore: [21-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>
2022-12-20 10:17:26 -08:00
Pedro Pontes
ed8c8334f4 chore: cherry-pick 819d876e1bb8 from chromium (#36687) 2022-12-20 10:08:40 -08:00
Pedro Pontes
570c146fe3 chore: cherry-pick 65d46507a0c9 from chromium (#36584)
* chore: [21-x-y] cherry-pick 65d46507a0c9 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-19 13:28:03 -08:00
Pedro Pontes
5828a25dc6 chore: cherry-pick 9b3d0e2f1aab from chromium (#36685)
* 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:00 -08:00
Pedro Pontes
88146b4140 chore: cherry-pick eed5a4de2c40 from chromium (#36679)
* chore: [21-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:17 -08:00
Pedro Pontes
a0701fd622 chore: cherry-pick fcf671adc2f3 from libaom (#36683) 2022-12-19 11:08:20 -08:00
Pedro Pontes
44e0345320 chore: cherry-pick d1d654d73222 from chromium (#36677) 2022-12-19 10:55:58 -08:00
Pedro Pontes
d77c0f2e23 chore: cherry-pick 136ef25acbf7 from webrtc (#36675) 2022-12-19 10:55:23 -08:00
trop[bot]
86af860c29 fix: strip branded binaries (#36655)
When creating branded release builds and using scripts/strip-binaries.py
on Linux, the final artifacts end up unstripped due to the static set of
binaries considered for stripping.
With this patch the name of the electron binary is taken from the
BRANDING.json `project_name` key.

Signed-off-by: Robert Günzler <r@gnzler.io>

Co-authored-by: Robert Günzler <r@gnzler.io>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Robert Günzler <r@gnzler.io>
2022-12-14 12:45:04 -05:00
Pedro Pontes
4615e4afda chore: cherry-pick 176c526846cb from chromium (#36582)
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2022-12-13 10:51:32 -08:00
Samuel Attard
4c2f91198b chore: cherry-pick 09ae62b from node (#36625)
* chore: cherry-pick 09ae62b from node

* chore: fixup patch

Co-authored-by: VerteDinde <vertedinde@electronjs.org>
2022-12-13 12:45:40 -05:00
Pedro Pontes
ef73a91f02 chore: cherry-pick f46db6aac3e9 from chromium (#36589)
* 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>
2022-12-12 12:17:00 -08:00
Pedro Pontes
0d7537772d chore: cherry-pick 42e15c2055c4 from chromium (#36576)
* chore: [21-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-11 01:22:10 -08:00
Pedro Pontes
c9e67c38b7 chore: cherry-pick 2ef09109c0ec from chromium (#36591)
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2022-12-09 03:27:30 -08:00
Pedro Pontes
5abed6e890 chore: cherry-pick c79148742421 from v8 (#36580)
chore: [21-x-y] cherry-pick c79148742421 from v8
2022-12-09 03:25:39 -08:00
trop[bot]
5f37729c17 docs: add mdn link to web-request-filter.md (#36618)
* Add MDN link to web-request-filter.md

When I was using the Electron docs I wanted to know how to use [webRequest.onBeforeSendHeaders](https://www.electronjs.org/docs/latest/api/web-request#webrequestonbeforesendheadersfilter-listener) but I was unable to correctly guess the correct format for the `WebRequestFilter` URL strings, and there was no explanation in the Electron docs. Eventually I googled it and found the MDN article which helped me.

Co-authored-by: Hugh Davey <9026053+hughjdavey@users.noreply.github.com>

* Update docs/api/structures/web-request-filter.md

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

Co-authored-by: Hugh Davey <9026053+hughjdavey@users.noreply.github.com>

* Update docs/api/structures/web-request-filter.md

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

Co-authored-by: Hugh Davey <9026053+hughjdavey@users.noreply.github.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Hugh Davey <9026053+hughjdavey@users.noreply.github.com>
2022-12-08 14:56:02 -08:00
Pedro Pontes
f6e9ab2234 chore: cherry-pick f98adc846aad from chromium (#36593)
* chore: cherry-pick f98adc846aad from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-12-08 11:23:01 -05:00
ad0p
5312995148 chore: cherry-pick 27fa951ae4a3 from v8 (#36553)
* chore: cherry-pick 27fa951ae4a3 from v8

* chore: cherry-pick 27fa951ae4a3 from v8

Co-authored-by: Adam Prasil <adamprasil@microsoft.com>
2022-12-05 20:49:46 -05:00
trop[bot]
c9590a7c3a fix: handle Notification requireInteraction option (#36503)
Co-authored-by: Jeremy Spiegel <jeremy.spiegel@frontapp.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Spiegel <jeremy.spiegel@frontapp.com>
2022-12-05 12:08:27 -05:00
trop[bot]
6ea76082de fix: treat maxWidth/Height<=0 as unlimited (#36510)
fix: treat maxWidth/Height<=0 as unlimited (#36487)

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-12-05 12:05:13 -05:00
trop[bot]
6b571240ad docs: document outlivesOpener option in window open handler (#36507)
* docs: document outlivesOpener option in window open handler

Co-authored-by: Jeremy Rose <jeremya@chromium.org>

* outlivesOpener is optional

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-30 17:08:54 -08:00
trop[bot]
ba93dc3c83 fix: remove unneeded --turbo-profiling-input arg from mksnapshot_args… (#36495)
fix: remove unneeded --turbo-profiling-input arg from mksnapshot_args (#36378)

fix: remove unneeded --turbo-profiling-input args from mksnapshot_args
(cherry picked from commit 7529ebfe0e)

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-11-30 13:20:43 -05:00
electron-roller[bot]
039a1852a2 chore: bump chromium to 106.0.5249.199 (21-x-y) (#36448)
* chore: bump chromium in DEPS to 106.0.5249.199

* Trigger Build

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2022-11-30 13:14:31 -05:00
trop[bot]
12df0267eb build(deps): bump minimatch from 3.0.4 to 3.0.8 (#36469)
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 10:34:25 -05:00
trop[bot]
f1500363dc chore: fix dangling promise in npm install (#36399)
* 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:36 +01:00
Michaela Laurencin
4435461885 docs: add EOL dates to timeline doc (#36389) 2022-11-17 18:11:39 -05:00
trop[bot]
dcdfe231fc chore: compile addons with --gnu++17 (#36383)
* 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 22:23:50 +01:00
trop[bot]
bc2c39e668 build: remove out cache (#36359)
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:03:58 -08:00
trop[bot]
95d1cf0670 build: make src cache smaller (#36351)
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:15:23 -05:00
trop[bot]
423cdb02a7 docs: update README.md to use correct twitter handle (#36347)
doc: update README.md to use correct twitter handle

Co-authored-by: Tierney Cyren <bnb@electronjs.org>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Tierney Cyren <bnb@electronjs.org>
2022-11-15 00:30:38 -08:00
Samuel Attard
cc8d02db5d build: provide moduleVersion to docs-parser directly (#36336)
build: provide moduleVersion to docs-parser directly (#36329)
2022-11-14 16:28:11 -05:00
Samuel Attard
3afea231ca build: fix filenames.auto (#36338) 2022-11-14 10:03:18 -08:00
trop[bot]
49b624ef1f docs: update tutorials for Forge 6 (#36321)
docs: update tutorials for Forge 6 (#36313)

docs: update tutorial for Forge 6

Co-authored-by: Erick Zhao <erick@hotmail.ca>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Erick Zhao <erick@hotmail.ca>
2022-11-13 23:45:46 -08:00
trop[bot]
d8a1298eaf feat: add app.getPreferredSystemLanguages() API (#36290)
feat: add app.getPreferredSystemLanguages() API (#36035)

* feat: add app.getSystemLanguage() API

* Change the API to getPreferredSystemLanguages

* Fix test

* Clarify docs and add Linux impl

* Remove USE_GLIB

* Don't add C to list

* Remove examples since there's a lot of edge cases

* Fix lint

* Add examples

* Fix compile error

* Apply PR feedback

* Update the example

Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>
2022-11-09 17:21:12 -05:00
electron-roller[bot]
3026615784 chore: bump chromium to 106.0.5249.181 (21-x-y) (#36288)
* chore: bump chromium in DEPS to 106.0.5249.181

* chore: update patches

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-09 17:05:58 -05:00
trop[bot]
23a81e6e59 fix: app.dock.setIcon() crash before app ready (#36294)
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 14:59:45 -05:00
Pedro Pontes
801cbe2ab3 revert: cherry-pick eef098d1c7d5 from webrtc (#36264)
Revert "chore: cherry-pick eef098d1c7d5 from webrtc (#36216)"

This reverts commit 2212933858.
2022-11-09 10:51:33 -05:00
trop[bot]
e857073d65 docs: fix driverId -> deviceId typo (#36270)
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-11-08 11:30:58 +01:00
Pedro Pontes
86a1ee1e89 chore: cherry-pick 67c9cbc784d6 from chromium (#36219)
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2022-11-02 13:13:40 -04:00
Pedro Pontes
2212933858 chore: cherry-pick eef098d1c7d5 from webrtc (#36216)
* chore: cherry-pick eef098d1c7d5 from webrtc

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-02 11:48:42 -04:00
Pedro Pontes
c5346bde08 chore: cherry-pick 933cc81c6bad from chromium (#36222)
* chore: cherry-pick 933cc81c6bad from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-11-02 09:18:45 -04:00
trop[bot]
c678f7b872 docs: Fixed outdated documentation (uploading to App Store) (#36212)
* 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:39:27 -07:00
electron-roller[bot]
3aac61e60c chore: bump chromium to 106.0.5249.168 (21-x-y) (#36185)
chore: bump chromium in DEPS to 106.0.5249.168

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2022-11-01 11:10:23 -04:00
Milan Burda
e91dba1730 build: fix building with enable_plugins = false (#36202)
build: fix building with enable_plugins = false (#36193)

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

Co-authored-by: Milan Burda <miburda@microsoft.com>
2022-11-01 11:09:55 -04:00
Keeley Hammond
019c05b924 build: determine electron version from tags not files (#36135)
* 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: MarshallOfSound <marshallofsound@electronjs.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-10-28 13:13:03 -07:00
trop[bot]
0fe2a73f83 build: prefix version in uploader script (#36173)
build: prefix v in uploader script

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

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
2022-10-27 17:47:26 -07:00
trop[bot]
69cb9c1581 test: fixup HID test for ARM CI (#36172)
(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:47:54 -04:00
trop[bot]
b176c95226 fix: resolve loadURL properly for in-page navigations (#36150)
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 16:19:44 -04:00
trop[bot]
fa9ffa77b8 refactor: handle uncaught promise error (#36158)
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:25:43 -04:00
electron-roller[bot]
9870a31225 chore: bump chromium to 106.0.5249.165 (21-x-y) (#36162)
* chore: bump chromium in DEPS to 106.0.5249.165

* chore: update patches

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-10-27 14:20:54 -04:00
trop[bot]
0ee70e9431 docs: correcting main example in WebRequest documentation (#36160)
docs: correcting main example in WebRequest documentation (#36113)

Correcting main example

The entry `*://electron.github.io` is invalid and produces an exception. i.e.

> UnhandledPromiseRejectionWarning: TypeError: Invalid url pattern *://electron.github.io: Empty path.

Setting a valid path to resolve this issue

Co-authored-by: Shane Gannon <sgannon200@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shane Gannon <sgannon200@gmail.com>
2022-10-27 14:17:15 -04:00
trop[bot]
47bc841d6c test: fix flake in will-navigate test (#36166)
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:07:07 -04:00
trop[bot]
a75e369e9c docs: document that when invoke rejects, it gives a different Error (#36147)
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:19 -07:00
electron-roller[bot]
bec207c931 chore: bump chromium to 106.0.5249.120 (21-x-y) (#36145)
chore: bump chromium in DEPS to 106.0.5249.120

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2022-10-26 15:24:02 -04:00
trop[bot]
28b9856094 build: use python3 for appveyor commands (#36132)
Co-authored-by: Samuel Attard <sattard@salesforce.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-10-25 20:28:32 -07:00
trop[bot]
ed999f5456 docs: fixed MenuItem documentation to use the same formatting for all role options (#36119)
docs: fixed MenuItem documentation to use the same formatting for all role options (#36112)

Fixed MenuItem documentation

Some of the items in the list of possible roles were formatted differently, which made it harder to read.
Sorry if this was intended, but I found it easier to read with them all formatted the same.

Co-authored-by: flynow10 <37031514+flynow10@users.noreply.github.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: flynow10 <37031514+flynow10@users.noreply.github.com>
2022-10-25 20:45:26 +09:00
trop[bot]
67363441a5 test: exit properly when node-spec-runner validates specs (#36103)
test: exit properly when node spec runner validates specs

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-24 16:29:01 +02:00
George Xu
47dd47d8c4 refactor: migrate from asar to @electron/asar (#36070) (#36087)
* refactor: migrate from asar to @electron/asar (#36070)

* refactor: migrate from asar to @electron/asar

* fix: update asar require calls

* kick ci

Co-authored-by: Samuel Attard <sam@electronjs.org>
2022-10-21 11:14:36 +02:00
trop[bot]
0a34be3e55 test: disable flaky linux arm/arm64 crash test case (#36098)
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-21 11:13:32 +02:00
trop[bot]
72eea879e7 fix: printToPDF default margins (#36072)
fix: printToPDF default margins (#36060)

printToPDF default margins

The document printToPDF has a 1cm margin and this default value has been added in the code.

Co-authored-by: Yusoo <Yusoo@users.noreply.github.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Yusoo <Yusoo@users.noreply.github.com>
2022-10-20 16:34:16 -04:00
trop[bot]
bcfafc4386 fix: headless job tracking in printToPDF (#36064)
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-20 14:28:21 -04:00
Sudowoodo Release Bot
c8c335874a Bump v21.2.0 2022-10-19 08:31:10 -07:00
trop[bot]
de9889e78a docs: update VS Code debugger types to remove "pwa-" prefix (#36053)
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:17:48 -04:00
trop[bot]
27944d805b fix: override app's desktop name and v8 flags in default-app (#36050)
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 13:35:26 +02:00
trop[bot]
8dcdf5c26d fix: remove extra dot in extension (#36027)
* fix: remove extra period of extension

Co-authored-by: mlaurencin <mlaurencin@electronjs.org>

* update comment

Co-authored-by: mlaurencin <mlaurencin@electronjs.org>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: mlaurencin <mlaurencin@electronjs.org>
Co-authored-by: Michaela Laurencin <35157522+mlaurencin@users.noreply.github.com>
2022-10-17 09:51:15 +02:00
trop[bot]
cef7f6f99b test: re-enable power monitor tests on arm64 (#36022)
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-17 15:25:54 +09:00
Keeley Hammond
17d8889e41 ci: use AppVeyor workflows (#36028)
* ci: use AppVeyor workflows (#35377)

* ci: use AppVeyor workflows

* fixup for skipping test on pr jobs

* ci: clean up appveyor.yml to match main

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-10-16 16:20:41 -07:00
trop[bot]
a86510b30c fix: disable nodeIntegrationInWorker for certain Worker types (#36009)
fix: disable nodeIntegrationInWorker for certain Worker types

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-13 17:06:06 -04:00
trop[bot]
0874e61e4f build: fix building with enable_ppapi = false (#36006)
Co-authored-by: Milan Burda <milan.burda@gmail.com>

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2022-10-12 14:00:29 -04:00
electron-roller[bot]
1cb0a98f6c chore: bump chromium to 106.0.5249.119 (21-x-y) (#36001)
chore: bump chromium in DEPS to 106.0.5249.119

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2022-10-12 13:10:16 -04:00
Sudowoodo Release Bot
16a3a456a6 Bump v21.1.1 2022-10-12 08:31:33 -07:00
trop[bot]
7727b7ecba fix: drag and drop should copy on macOS (#35977)
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 11:15:33 -04:00
trop[bot]
595ed3e128 fix: webContents.printToPDF option plumbing (#35992)
fix: contents.printToPDF option plumbing

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:05:10 -04:00
trop[bot]
fd52089635 docs: remove references to Widevine (#35990)
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 10:02:39 -04:00
trop[bot]
77bc03e051 fix: on-screen-keyboard hides on input blurred in webview (#35982)
* 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-11 23:20:11 +02:00
Raymond Zhao
9f99f4ed0e chore: cherry-pick 30a32e6 from chromium (#35370) (#35970)
chore: apply chromium commit 30a32e6 (#35370)

chore: Apply Chromium commit 30a32e6
2022-10-11 14:55:31 -04:00
trop[bot]
bc27dc4597 fix: expose the built-in electron module via the ESM loader (#35958)
* 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 12:32:49 -04:00
trop[bot]
9048de7cab fix: override content::ContentMainDelegate::CreateContentClient() (#35965)
* fix: override content::ContentMainDelegate::CreateContentClient()

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

* chore: remove extra call

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-11 02:37:18 -07:00
electron-roller[bot]
cef4f6a8e7 chore: bump chromium to 106.0.5249.103 (21-x-y) (#35933)
chore: bump chromium in DEPS to 106.0.5249.103

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2022-10-06 14:56:20 -04:00
Samuel Attard
80a4ea2601 chore: cherry-pick c83640db21b5 from chromium (#35925)
* chore: cherry-pick c83640db21b5 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-10-06 04:28:52 -07:00
Samuel Attard
0b733793c3 build: fix filesystem permissions from bad trop commits
Ref: 572a9b16a1
Ref: 38955998f5
Ref: 63beca3002
2022-10-05 12:11:06 -07:00
165 changed files with 8603 additions and 1310 deletions

View File

@@ -235,6 +235,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 +459,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
@@ -483,7 +488,9 @@ step-fix-sync: &step-fix-sync
run:
name: Fix Sync
command: |
SEDOPTION="-i"
if [ "`uname`" == "Darwin" ]; then
SEDOPTION="-i ''"
# Fix Clang Install (wrong binary)
rm -rf src/third_party/llvm-build
python3 src/tools/clang/scripts/update.py
@@ -568,6 +575,13 @@ step-electron-build: &step-electron-build
ninja -C out/Default electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
ninja -C out/Default tools/v8_context_snapshot -j $NUMBER_OF_NINJA_PROCESSES
gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
# Remove unused args from mksnapshot_args
SEDOPTION=
if [ "`uname`" == "Darwin" ]; then
SEDOPTION="-i ''"
fi
sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
(cd out/Default; zip mksnapshot.zip mksnapshot_args clang_x64_v8_arm64/gen/v8/embedded.S)
rm -rf out/Default/clang_x64_v8_arm64/gen
rm -rf out/Default/clang_x64_v8_arm64/obj
@@ -758,6 +772,13 @@ step-mksnapshot-build: &step-mksnapshot-build
if [ "$USE_PREBUILT_V8_CONTEXT_SNAPSHOT" != "1" ]; then
ninja -C out/Default electron:electron_mksnapshot -j $NUMBER_OF_NINJA_PROCESSES
gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
# Remove unused args from mksnapshot_args
SEDOPTION=
if [ "`uname`" == "Darwin" ]; then
SEDOPTION="-i ''"
fi
sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
fi
if [ "`uname`" != "Darwin" ]; then
if [ "$TARGET_ARCH" == "arm" ]; then
@@ -813,7 +834,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
@@ -873,12 +894,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
@@ -893,14 +914,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
@@ -918,13 +931,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
@@ -954,13 +960,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:
@@ -970,7 +979,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:
@@ -1302,9 +1311,6 @@ commands:
build:
type: boolean
default: true
use-out-cache:
type: boolean
default: true
restore-src-cache:
type: boolean
default: true
@@ -1427,10 +1433,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
@@ -1473,22 +1475,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
@@ -1642,7 +1628,6 @@ jobs:
persist: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-x64-testing-asan:
executor:
@@ -1659,7 +1644,6 @@ jobs:
- electron-build:
persist: true
checkout: true
use-out-cache: false
build-nonproprietary-ffmpeg: false
linux-x64-testing-no-run-as-node:
@@ -1676,7 +1660,6 @@ jobs:
- electron-build:
persist: false
checkout: true
use-out-cache: false
linux-x64-testing-gn-check:
executor:
@@ -1727,7 +1710,6 @@ jobs:
persist: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-arm-publish:
executor:
@@ -1770,7 +1752,6 @@ jobs:
persist: true
checkout: false
checkout-and-assume-cache: true
use-out-cache: false
linux-arm64-testing-gn-check:
executor:
@@ -2234,3 +2215,5 @@ workflows:
lint:
jobs:
- lint
# VS Code Extension Version: 1.5.1

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"
@@ -404,9 +442,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",
@@ -620,11 +655,21 @@ source_set("electron_lib") {
if (enable_plugins) {
deps += [ "chromium_src:plugins" ]
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",
]
}
if (enable_ppapi) {
deps += [
"//ppapi/host",
"//ppapi/proxy",
"//ppapi/shared_impl",
]
}
if (enable_run_as_node) {
sources += [
"shell/app/node_main.cc",
@@ -750,7 +795,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" ]
@@ -1191,6 +1235,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",
@@ -1224,8 +1269,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",
]
@@ -1407,15 +1451,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) {

2
DEPS
View File

@@ -2,7 +2,7 @@ gclient_gn_args_from = 'src'
vars = {
'chromium_version':
'106.0.5249.91',
'106.0.5249.199',
'node_version':
'v16.16.0',
'nan_version':

View File

@@ -1 +0,0 @@
21.1.0

2
README.md Executable file → Normal file
View File

@@ -12,7 +12,7 @@ using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) an
[Chromium](https://www.chromium.org) and is used by the [Atom
editor](https://github.com/atom/atom) and many other [apps](https://electronjs.org/apps).
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
Follow [@electronjs](https://twitter.com/electronjs) on Twitter for important
announcements.
This project adheres to the Contributor Covenant

107
appveyor-bake.yml Normal file
View File

@@ -0,0 +1,107 @@
# 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: e-111.0.5560.0-2
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
# The following lines are needed when baking from a completely new image (eg MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest via image: base-windows-server2019)
# init:
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
# - appveyor version
# - ps: $ErrorActionPreference = 'Stop'
# - ps: 'Write-Host "OS Build: $((Get-CimInstance Win32_OperatingSystem).BuildNumber)"'
# clone_folder: '%USERPROFILE%\image-bake-scripts'
# clone_script:
# - ps: Invoke-WebRequest "https://github.com/appveyor/build-images/archive/1f90d94e74c8243c909a09b994e527584dfcb838.zip" -OutFile "$env:temp\scripts.zip"
# - ps: Expand-Archive -Path "$env:temp\scripts.zip" -DestinationPath "$env:temp\scripts" -Force
# - ps: Copy-Item -Path "$env:temp\scripts\build-images-1f90d94e74c8243c909a09b994e527584dfcb838\scripts\Windows\*" -Destination $env:APPVEYOR_BUILD_FOLDER -Recurse
build_script:
# The following lines are needed when baking from a completely new image (eg MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest via image: base-windows-server2019)
# - ps: .\init_server.ps1
# - ps: .\extend_system_volume.ps1
# # Restart VM
# - ps: Start-Sleep -s 5; Restart-Computer
# - ps: Start-Sleep -s 5
# - appveyor version
# - ps: .\install_path_utils.ps1
# - ps: .\install_powershell_core.ps1
# - ps: .\install_powershell_get.ps1
# - ps: .\install_7zip.ps1
# - ps: .\install_chocolatey.ps1
# - ps: .\install_webpi.ps1
# - ps: .\install_nuget.ps1
# - ps: .\install_pstools.ps1
# - ps: .\install_git.ps1
# - ps: .\install_git_lfs.ps1
# # Restart VM
# - ps: Start-Sleep -s 5; Restart-Computer
# - ps: Start-Sleep -s 5
# END LINES FOR COMPLETELY NEW IMAGE
- git config --global core.longpaths true
- ps: >-
if (-not (Test-Path -Path C:\projects\src)) {
New-Item -Path C:\projects\src -ItemType Directory
}
- cd C:\projects\
- git clone -q --branch=%APPVEYOR_REPO_BRANCH% https://github.com/electron/electron.git C:\projects\src\electron
- 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
# Uncomment the following line if windows deps change
# - 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"
# The following lines are needed when baking from a completely new image (eg MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest via image: base-windows-server2019)
# # Restart VM
# - ps: Start-Sleep -s 5; Restart-Computer
# - ps: Start-Sleep -s 5
# - cd %USERPROFILE%\image-bake-scripts
# - appveyor version
# - ps: .\optimize_dotnet_runtime.ps1
# - ps: .\disable_windows_background_services.ps1
# - ps: .\enforce_windows_firewall.ps1
# - ps: .\cleanup_windows.ps1
# END LINES FOR COMPLETELY NEW IMAGE
on_image_bake:
- ps: >-
echo "Baking image: $env:APPVEYOR_BAKE_IMAGE at dir $PWD"
- ps: Remove-Item -Recurse -Force C:\projects\depot_tools
- ps: Remove-Item -Recurse -Force C:\projects\src\electron
# Uncomment these lines and set APPVEYOR_RDP_PASSWORD in project settings to enable RDP after bake is done
# # on_finish:
# - ps: >-
# $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-2
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
}
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: |
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,3 +1,7 @@
# 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,
@@ -24,223 +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-106.0.5249.199-2
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
}
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: |
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
- 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 )
- if "%RUN_TESTS%"=="true" ( echo Running remote test suite & node script/yarn test -- --trace-uncaught --runners=remote --runTestFilesSeparately --enable-logging=file --log-file=%cd%\electron.log )
- 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 )
- 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

@@ -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 21,1,0,0
PRODUCTVERSION 21,1,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", "21.1.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", "21.1.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")
@@ -372,15 +373,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_ppapi) {
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

@@ -717,6 +717,8 @@ To set the locale, you'll want to use a command line switch at app startup, whic
**Note:** This API must be called after the `ready` event is emitted.
**Note:** To see example return values of this API compared to other locale and language APIs, see [`app.getPreferredSystemLanguages()`](#appgetpreferredsystemlanguages).
### `app.getLocaleCountryCode()`
Returns `string` - User operating system's locale two-letter [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) country code. The value is taken from native OS APIs.
@@ -725,10 +727,42 @@ Returns `string` - User operating system's locale two-letter [ISO 3166](https://
### `app.getSystemLocale()`
Returns `string` - The current system locale. On Windows and Linux, it is fetched using Chromium's `i18n` library. On macOS, the `NSLocale` object is used instead.
Returns `string` - The current system locale. On Windows and Linux, it is fetched using Chromium's `i18n` library. On macOS, `[NSLocale currentLocale]` is used instead. To get the user's current system language, which is not always the same as the locale, it is better to use [`app.getPreferredSystemLanguages()`](#appgetpreferredsystemlanguages).
Different operating systems also use the regional data differently:
* Windows 11 uses the regional format for numbers, dates, and times.
* macOS Monterey uses the region for formatting numbers, dates, times, and for selecting the currency symbol to use.
Therefore, this API can be used for purposes such as choosing a format for rendering dates and times in a calendar app, especially when the developer wants the format to be consistent with the OS.
**Note:** This API must be called after the `ready` event is emitted.
**Note:** To see example return values of this API compared to other locale and language APIs, see [`app.getPreferredSystemLanguages()`](#appgetpreferredsystemlanguages).
### `app.getPreferredSystemLanguages()`
Returns `string[]` - The user's preferred system languages from most preferred to least preferred, including the country codes if applicable. A user can modify and add to this list on Windows or macOS through the Language and Region settings.
The API uses `GlobalizationPreferences` (with a fallback to `GetSystemPreferredUILanguages`) on Windows, `\[NSLocale preferredLanguages\]` on macOS, and `g_get_language_names` on Linux.
This API can be used for purposes such as deciding what language to present the application in.
Here are some examples of return values of the various language and locale APIs with different configurations:
* For Windows, where the application locale is German, the regional format is Finnish (Finland), and the preferred system languages from most to least preferred are French (Canada), English (US), Simplified Chinese (China), Finnish, and Spanish (Latin America):
* `app.getLocale()` returns `'de'`
* `app.getSystemLocale()` returns `'fi-FI'`
* `app.getPreferredSystemLanguages()` returns `['fr-CA', 'en-US', 'zh-Hans-CN', 'fi', 'es-419']`
* On macOS, where the application locale is German, the region is Finland, and the preferred system languages from most to least preferred are French (Canada), English (US), Simplified Chinese, and Spanish (Latin America):
* `app.getLocale()` returns `'de'`
* `app.getSystemLocale()` returns `'fr-FI'`
* `app.getPreferredSystemLanguages()` returns `['fr-CA', 'en-US', 'zh-Hans-FI', 'es-419']`
Both the available languages and regions and the possible return values differ between the two operating systems.
As can be seen with the example above, on Windows, it is possible that a preferred system language has no country code, and that one of the preferred system languages corresponds with the language used for the regional format. On macOS, the region serves more as a default country code: the user doesn't need to have Finnish as a preferred language to use Finland as the region,and the country code `FI` is used as the country code for preferred system languages that do not have associated countries in the language name.
### `app.addRecentDocument(path)` _macOS_ _Windows_
* `path` string
@@ -1203,7 +1237,7 @@ For `infoType` equal to `basic`:
}
```
Using `basic` should be preferred if only basic information like `vendorId` or `driverId` is needed.
Using `basic` should be preferred if only basic information like `vendorId` or `deviceId` is needed.
### `app.setBadgeCount([count])` _Linux_ _macOS_

View File

@@ -1869,7 +1869,7 @@ removed in future Electron releases.
On a Window with Window Controls Overlay already enabled, this method updates
the style of the title bar overlay.
[runtime-enabled-features]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70
[runtime-enabled-features]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5
[page-visibility-api]: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
[quick-look]: https://en.wikipedia.org/wiki/Quick_Look
[vibrancy-docs]: https://developer.apple.com/documentation/appkit/nsvisualeffectview?preferredLanguage=objc

View File

@@ -20,7 +20,7 @@ work). Extensions are installed per-`session`. To load an extension, call
```js
const { session } = require('electron')
session.loadExtension('path/to/unpacked/extension').then(({ id }) => {
session.defaultSession.loadExtension('path/to/unpacked/extension').then(({ id }) => {
// ...
})
```

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

@@ -14,7 +14,7 @@ See [`Menu`](menu.md) for examples.
* `menuItem` MenuItem
* `browserWindow` [BrowserWindow](browser-window.md) | undefined - This will not be defined if no window is open.
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `role` string (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `toggleSpellChecker`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, 'showSubstitutions', 'toggleSmartQuotes', 'toggleSmartDashes', 'toggleTextReplacement', `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `shareMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
* `role` string (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `toggleSpellChecker`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `showSubstitutions`, `toggleSmartQuotes`, `toggleSmartDashes`, `toggleTextReplacement`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `shareMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
`click` property will be ignored. See [roles](#roles).
* `type` string (optional) - Can be `normal`, `separator`, `submenu`, `checkbox` or
`radio`.

View File

@@ -405,7 +405,7 @@ Clears the sessions HTTP cache.
* `origin` string (optional) - Should follow `window.location.origin`s representation
`scheme://host:port`.
* `storages` string[] (optional) - The types of storages to clear, can contain:
`appcache`, `cookies`, `filesystem`, `indexdb`, `localstorage`,
`cookies`, `filesystem`, `indexdb`, `localstorage`,
`shadercache`, `websql`, `serviceworkers`, `cachestorage`. If not
specified, clear all storage types.
* `quotas` string[] (optional) - The types of quotas to clear, can contain:
@@ -638,6 +638,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
* `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

@@ -1,6 +1,7 @@
# Display Object
* `id` number - Unique identifier associated with the display.
* `label` string - User-friendly label, determined by the platform.
* `rotation` number - Can be 0, 90, 180, 270, represents screen rotation in
clock-wise degrees.
* `scaleFactor` number - Output device's pixel scale factor.

View File

@@ -1,3 +1,3 @@
# WebRequestFilter Object
* `urls` string[] - Array of URL patterns that will be used to filter out the requests that do not match the URL patterns.
* `urls` string[] - Array of [URL patterns](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns) that will be used to filter out the requests that do not match the URL patterns.

View File

@@ -1180,7 +1180,7 @@ Ignore application menu shortcuts while this web contents is focused.
#### `contents.setWindowOpenHandler(handler)`
* `handler` Function<{action: 'deny'} | {action: 'allow', overrideBrowserWindowOptions?: BrowserWindowConstructorOptions}>
* `handler` Function<{action: 'deny'} | {action: 'allow', outlivesOpener?: boolean, overrideBrowserWindowOptions?: BrowserWindowConstructorOptions}>
* `details` Object
* `url` string - The _resolved_ version of the URL passed to `window.open()`. e.g. opening a window with `window.open('foo')` will yield something like `https://the-origin/the/current/path/foo`.
* `frameName` string - Name of the window provided in `window.open()`
@@ -1195,8 +1195,11 @@ Ignore application menu shortcuts while this web contents is focused.
be set. If no post data is to be sent, the value will be `null`. Only defined
when the window is being created by a form that set `target=_blank`.
Returns `{action: 'deny'} | {action: 'allow', overrideBrowserWindowOptions?: BrowserWindowConstructorOptions}` - `deny` cancels the creation of the new
Returns `{action: 'deny'} | {action: 'allow', outlivesOpener?: boolean, overrideBrowserWindowOptions?: BrowserWindowConstructorOptions}` - `deny` cancels the creation of the new
window. `allow` will allow the new window to be created. Specifying `overrideBrowserWindowOptions` allows customization of the created window.
By default, child windows are closed when their opener is closed. This can be
changed by specifying `outlivesOpener: true`, in which case the opened window
will not be closed when its opener is closed.
Returning an unrecognized value such as a null, undefined, or an object
without a recognized 'action' value will result in a console error and have
the same effect as returning `{action: 'deny'}`.

View File

@@ -28,7 +28,7 @@ const { session } = require('electron')
// Modify the user agent for all requests to the following urls.
const filter = {
urls: ['https://*.github.com/*', '*://electron.github.io']
urls: ['https://*.github.com/*', '*://electron.github.io/*']
}
session.defaultSession.webRequest.onBeforeSendHeaders(filter, (details, callback) => {

View File

@@ -1020,7 +1020,7 @@ Emitted when DevTools is closed.
Emitted when DevTools is focused / opened.
[runtime-enabled-features]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70
[runtime-enabled-features]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5
[chrome-webview]: https://developer.chrome.com/docs/extensions/reference/webviewTag/
### Event: 'context-menu'

View File

@@ -100,7 +100,7 @@ requires unsafe mode), so Electron is unable to support this feature on Linux.
The handler invoked when `session.setDevicePermissionHandler(handler)` is used
has a change to its arguments. This handler no longer is passed a frame
`[WebFrameMain](api/web-frame-main.md)`, but instead is passed the `origin`, which
[`WebFrameMain`](api/web-frame-main.md), but instead is passed the `origin`, which
is the origin that is checking for device permission.
## Planned Breaking API Changes (19.0)

View File

@@ -18,8 +18,8 @@ See also [V8 Development](v8-development.md)
### Code Resources
- [Code Search](https://cs.chromium.org/) - Indexed and searchable source code for Chromium and associated projects.
- [Source Code](https://cs.chromium.org/chromium/src/) - The source code for Chromium itself.
- [Code Search](https://source.chromium.org/chromium) - Indexed and searchable source code for Chromium and associated projects.
- [Source Code](https://source.chromium.org/chromium/chromium/src) - The source code for Chromium itself.
- [Chromium Review](https://chromium-review.googlesource.com) - The searchable code host which facilitates code reviews for Chromium and related projects.
### Informational Resources

View File

@@ -144,7 +144,7 @@ NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_{api_name},Initialize)
In your [`shell/common/node_bindings.cc`](https://github.com/electron/electron/blob/main/shell/common/node_bindings.cc) file, add your node binding name to Electron's built-in modules.
```cpp title='shell/common/node_bindings.cc'
#define ELECTRON_BUILTIN_MODULES(V) \
#define ELECTRON_BROWSER_MODULES(V) \
V(electron_browser_{api_name})
```

0
docs/fiddles/features/web-bluetooth/preload.js Executable file → Normal file
View File

View File

@@ -52,15 +52,17 @@ ways to get your application signed and notarized.
If you're using Electron's favorite build tool, getting your application signed
and notarized requires a few additions to your configuration. [Forge](https://electronforge.io) is a
collection of the official Electron tools, using [`electron-packager`],
[`electron-osx-sign`], and [`electron-notarize`] under the hood.
[`@electron/osx-sign`], and [`@electron/notarize`] under the hood.
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).
Detailed instructions on how to configure your application can be found in the
[Signing macOS Apps](https://www.electronforge.io/guides/code-signing/code-signing-macos) guide in
the Electron Forge docs.
### Using Electron Packager
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`].
are likely using [`electron-packager`], which includes [`@electron/osx-sign`] and
[`@electron/notarize`].
If you're using Packager's API, you can pass [in configuration that both signs
and notarizes your application](https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html).
@@ -70,13 +72,7 @@ const packager = require('electron-packager')
packager({
dir: '/path/to/my/app',
osxSign: {
identity: 'Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)',
'hardened-runtime': true,
entitlements: 'entitlements.plist',
'entitlements-inherit': 'entitlements.plist',
'signature-flags': 'library'
},
osxSign: {},
osxNotarize: {
appleId: 'felix@felix.fun',
appleIdPassword: 'my-apple-id-password'
@@ -84,26 +80,6 @@ packager({
})
```
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>
```
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.
### Signing Mac App Store applications
See the [Mac App Store Guide].
@@ -213,15 +189,14 @@ can find [its documentation here](https://www.electron.build/code-signing).
See the [Windows Store Guide].
[apple developer program]: https://developer.apple.com/programs/
[`electron-builder`]: https://github.com/electron-userland/electron-builder
[`electron-forge`]: https://github.com/electron-userland/electron-forge
[`electron-osx-sign`]: https://github.com/electron-userland/electron-osx-sign
[`electron-forge`]: https://github.com/electron/forge
[`@electron/osx-sign`]: https://github.com/electron/osx-sign
[`electron-packager`]: https://github.com/electron/electron-packager
[`electron-notarize`]: https://github.com/electron/electron-notarize
[`@electron/notarize`]: https://github.com/electron/notarize
[`electron-winstaller`]: https://github.com/electron/windows-installer
[`electron-wix-msi`]: https://github.com/felixrieseberg/electron-wix-msi
[`electron-wix-msi`]: https://github.com/electron-userland/electron-wix-msi
[xcode]: https://developer.apple.com/xcode
[signing certificates]: https://github.com/electron/electron-osx-sign/wiki/1.-Getting-Started#certificates
[signing certificates]: https://developer.apple.com/support/certificates/
[mac app store guide]: ./mac-app-store-submission-guide.md
[windows store guide]: ./windows-store-guide.md
[maker-squirrel]: https://www.electronforge.io/config/makers/squirrel.windows

View File

@@ -7,28 +7,29 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
## Timeline
| Electron | Alpha | Beta | Stable | Chrome | Node | Supported |
| ------- | ----- | ------- | ------ | ------ | ---- | ---- |
| 2.0.0 | -- | 2018-Feb-21 | 2018-May-01 | M61 | v8.9 | 🚫 |
| 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | M66 | v10.2 | 🚫 |
| 4.0.0 | -- | 2018-Oct-11 | 2018-Dec-20 | M69 | v10.11 | 🚫 |
| 5.0.0 | -- | 2019-Jan-22 | 2019-Apr-24 | M73 | v12.0 | 🚫 |
| 6.0.0 | -- | 2019-May-01 | 2019-Jul-30 | M76 | v12.4 | 🚫 |
| 7.0.0 | -- | 2019-Aug-01 | 2019-Oct-22 | M78 | v12.8 | 🚫 |
| 8.0.0 | -- | 2019-Oct-24 | 2020-Feb-04 | M80 | v12.13 | 🚫 |
| 9.0.0 | -- | 2020-Feb-06 | 2020-May-19 | M83 | v12.14 | 🚫 |
| 10.0.0 | -- | 2020-May-21 | 2020-Aug-25 | M85 | v12.16 | 🚫 |
| 11.0.0 | -- | 2020-Aug-27 | 2020-Nov-17 | M87 | v12.18 | 🚫 |
| 12.0.0 | -- | 2020-Nov-19 | 2021-Mar-02 | M89 | v14.16 | 🚫 |
| 13.0.0 | -- | 2021-Mar-04 | 2021-May-25 | M91 | v14.16 | 🚫 |
| 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | M93 | v14.17 | 🚫 |
| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | M94 | v16.5 | 🚫 |
| 16.0.0 | 2021-Sep-23 | 2021-Oct-20 | 2021-Nov-16 | M96 | v16.9 | 🚫 |
| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | M98 | v16.13 | 🚫 |
| 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | M100 | v16.13 | |
| 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | M102 | v16.14 | |
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | M104 | v16.15 | |
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | M106 | TBD | |
| Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported |
| ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- |
| 22.0.0 | 2022-Sep-29 | 2022-Oct-25 | 2022-Nov-29 | TBD | M108 | TBD | |
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | TBD | M106 | v16.17 | |
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | TBD | M104 | v16.15 | |
| 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | TBD | M102 | v16.14 | |
| 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | 2022-Sep-27 | M100 | v16.13 | 🚫 |
| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | 2022-Aug-02 | M98 | v16.13 | 🚫 |
| 16.0.0 | 2021-Sep-23 | 2021-Oct-20 | 2021-Nov-16 | 2022-May-24 | M96 | v16.9 | 🚫 |
| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | 2022-May-24 | M94 | v16.5 | 🚫 |
| 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | 2022-Mar-29 | M93 | v14.17 | 🚫 |
| 13.0.0 | -- | 2021-Mar-04 | 2021-May-25 | 2022-Feb-01 | M91 | v14.16 | 🚫 |
| 12.0.0 | -- | 2020-Nov-19 | 2021-Mar-02 | 2021-Nov-16 | M89 | v14.16 | 🚫 |
| 11.0.0 | -- | 2020-Aug-27 | 2020-Nov-17 | 2021-Aug-31 | M87 | v12.18 | 🚫 |
| 10.0.0 | -- | 2020-May-21 | 2020-Aug-25 | 2021-May-25 | M85 | v12.16 | 🚫 |
| 9.0.0 | -- | 2020-Feb-06 | 2020-May-19 | 2021-Mar-02 | M83 | v12.14 | 🚫 |
| 8.0.0 | -- | 2019-Oct-24 | 2020-Feb-04 | 2020-Nov-17 | M80 | v12.13 | 🚫 |
| 7.0.0 | -- | 2019-Aug-01 | 2019-Oct-22 | 2020-Aug-25 | M78 | v12.8 | 🚫 |
| 6.0.0 | -- | 2019-Apr-25 | 2019-Jul-30 | 2020-May-19 | M76 | v12.14.0 | 🚫 |
| 5.0.0 | -- | 2019-Jan-22 | 2019-Apr-23 | 2020-Feb-04 | M73 | v12.0 | 🚫 |
| 4.0.0 | -- | 2018-Oct-11 | 2018-Dec-20 | 2019-Oct-22 | M69 | v10.11 | 🚫 |
| 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | 2019-Jul-30 | M66 | v10.2 | 🚫 |
| 2.0.0 | -- | 2018-Feb-21 | 2018-May-01 | 2019-Apr-23 | M61 | v8.9 | 🚫 |
**Notes:**

View File

@@ -11,7 +11,7 @@ This guide provides information on:
To sign Electron apps, the following tools must be installed first:
* Xcode 11 or above.
* The [electron-osx-sign][electron-osx-sign] npm module.
* The [@electron/osx-sign] npm module.
You also have to register an Apple Developer account and join the
[Apple Developer Program][developer-program].
@@ -103,7 +103,7 @@ Apps submitted to the Mac App Store must run under Apple's
the App Sandbox. The standard darwin build of Electron will fail to launch
when run under App Sandbox.
When signing the app with `electron-osx-sign`, it will automatically add the
When signing the app with `@electron/osx-sign`, it will automatically add the
necessary entitlements to your app's entitlements, but if you are using custom
entitlements, you must ensure App Sandbox capacity is added:
@@ -120,7 +120,7 @@ entitlements, you must ensure App Sandbox capacity is added:
#### Extra steps without `electron-osx-sign`
If you are signing your app without using `electron-osx-sign`, you must ensure
If you are signing your app without using `@electron/osx-sign`, you must ensure
the app bundle's entitlements have at least following keys:
```xml
@@ -170,22 +170,22 @@ your Apple Developer account's Team ID as its value:
</plist>
```
When using `electron-osx-sign` the `ElectronTeamID` key will be added
When using `@electron/osx-sign` the `ElectronTeamID` key will be added
automatically by extracting the Team ID from the certificate's name. You may
need to manually add this key if `electron-osx-sign` could not find the correct
need to manually add this key if `@electron/osx-sign` could not find the correct
Team ID.
### Sign apps for development
To sign an app that can run on your development machine, you must sign it with
the "Apple Development" certificate and pass the provisioning profile to
`electron-osx-sign`.
`@electron/osx-sign`.
```bash
electron-osx-sign YourApp.app --identity='Apple Development' --provisioning-profile=/path/to/yourapp.provisionprofile
```
If you are signing without `electron-osx-sign`, you must place the provisioning
If you are signing without `@electron/osx-sign`, you must place the provisioning
profile to `YourApp.app/Contents/embedded.provisionprofile`.
The signed app can only run on the machines that registered by the provisioning
@@ -213,7 +213,7 @@ use App Sandbox.
electron-osx-sign YourApp.app --identity='Developer ID Application' --no-gatekeeper-assess
```
By passing `--no-gatekeeper-assess`, the `electron-osx-sign` will skip the macOS
By passing `--no-gatekeeper-assess`, `@electron/osx-sign` will skip the macOS
GateKeeper check as your app usually has not been notarized yet by this step.
<!-- TODO(zcbenz): Add a chapter about App Notarization -->
@@ -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.
@@ -341,11 +341,12 @@ Electron uses following cryptographic algorithms:
* RIPEMD - [ISO/IEC 10118-3](https://webstore.ansi.org/RecordDetail.aspx?sku=ISO%2FIEC%2010118-3:2004)
[developer-program]: https://developer.apple.com/support/compare-memberships/
[electron-osx-sign]: https://github.com/electron/electron-osx-sign
[@electron/osx-sign]: https://github.com/electron/electron-osx-sign
[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

@@ -20,6 +20,8 @@ const win = new BrowserWindow({
The `nodeIntegrationInWorker` can be used independent of `nodeIntegration`, but
`sandbox` must not be set to `true`.
**Note:** This option is not available in [`SharedWorker`s](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker) or [`Service Worker`s](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker) owing to incompatibilities in sandboxing policies.
## Available APIs
All built-in modules of Node.js are supported in Web Workers, and `asar`

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

@@ -26,6 +26,15 @@ work on Windows, macOS, and Linux with a single JavaScript codebase.
This tutorial will guide you through the process of developing a desktop
application with Electron and distributing it to end users.
## Goals
This tutorial starts by guiding you through the process of piecing together
a minimal Electron application from scratch, then teaches you how to
package and distribute it to users using Electron Forge.
If you prefer to get a project started with a single-command boilerplate, we recommend you start
with Electron Forge's [`create-electron-app`](https://www.electronforge.io/) command.
## Assumptions
Electron is a native wrapper layer for web apps and is run in a Node.js environment.

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

@@ -70,10 +70,9 @@ the [Electron Forge CLI documentation].
:::
You should also notice that your package.json now has a few more packages installed
under your `devDependencies`, and contains an added `config.forge` field with an array
of makers configured. **Makers** are Forge plugins that create distributables from
your source code. You should see multiple makers in the pre-populated configuration,
one for each target platform.
under `devDependencies`, and a new `forge.config.js` file that exports a configuration
object. You should see multiple makers (packages that generate distributable app bundles) in the
pre-populated configuration, one for each target platform.
### Creating a distributable
@@ -111,13 +110,14 @@ Electron Forge can be configured to create distributables in different OS-specif
:::
:::tip Creating and Adding Application Icons
:::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.
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
:::info Packaging without Electron Forge
If you want to manually package your code, or if you're just interested understanding the
mechanics behind packaging an Electron app, check out the full [Application Packaging]
@@ -136,64 +136,51 @@ Code signing is a security technology that you use to certify that a desktop app
created by a known source. Windows and macOS have their own OS-specific code signing
systems that will make it difficult for users to download or launch unsigned applications.
If you already have code signing certificates for Windows and macOS, you can set your
credentials in your Forge configuration. Otherwise, please refer to the full
[Code Signing] documentation to learn how to purchase a certificate and for more information
on the desktop app code signing process.
On macOS, code signing is done at the app packaging level. On Windows, distributable installers
are signed instead.
are signed instead. If you already have code signing certificates for Windows and macOS, you can set
your credentials in your Forge configuration.
:::info
For more information on code signing, check out the
[Signing macOS Apps](https://www.electronforge.io/guides/code-signing) guide in the Forge docs.
:::
<Tabs>
<TabItem value="macos" label="macOS" default>
```json title='package.json' {6-18}
{
//...
"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": "this-is-a-secret"
}
}
//...
```js title='forge.config.js'
module.exports = {
packagerConfig: {
osxSign: {},
//...
osxNotarize: {
tool: 'notarytool',
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_PASSWORD,
teamId: process.env.APPLE_TEAM_ID,
}
//...
}
//...
}
```
</TabItem>
<TabItem value="windows" label="Windows">
```json title='package.json' {6-14}
{
```js title='forge.config.js'
module.exports = {
//...
"config": {
"forge": {
//...
"makers": [
{
"name": "@electron-forge/maker-squirrel",
"config": {
"certificateFile": "./cert.pfx",
"certificatePassword": "this-is-a-secret"
}
}
]
//...
}
}
makers: [
{
name: '@electron-forge/maker-squirrel',
config: {
certificateFile: './cert.pfx',
certificatePassword: process.env.CERTIFICATE_PASSWORD,
},
},
],
//...
}
```
@@ -214,13 +201,12 @@ information.
[`@electron/osx-sign`]: https://github.com/electron/osx-sign
[application packaging]: ./application-distribution.md
[code signing]: ./code-signing.md
[`electron-packager`]: https://github.com/electron/electron-packager
[`electron-winstaller`]: https://github.com/electron/windows-installer
[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
[forge's icon tutorial]: https://www.electronforge.io/guides/create-and-add-icons
<!-- Tutorial links -->

View File

@@ -78,27 +78,21 @@ Once you have it installed, you need to set it up in your Forge
configuration. A full list of options is documented in the Forge's
[`PublisherGitHubConfig`] API docs.
```json title='package.json' {6-16}
{
//...
"config": {
"forge": {
"publishers": [
{
"name": "@electron-forge/publisher-github",
"config": {
"repository": {
"owner": "github-user-name",
"name": "github-repo-name"
},
"prerelease": false,
"draft": true
}
}
]
}
}
//...
```js title='forge.config.js'
module.exports = {
publishers: [
{
name: '@electron-forge/publisher-github',
config: {
repository: {
owner: 'github-user-name',
name: 'github-repo-name',
},
prerelease: false,
draft: true,
},
},
],
}
```

View File

@@ -142,7 +142,6 @@ auto_filenames = {
"lib/common/define-properties.ts",
"lib/common/ipc-messages.ts",
"lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts",
"lib/renderer/api/context-bridge.ts",
"lib/renderer/api/crash-reporter.ts",
"lib/renderer/api/ipc-renderer.ts",

View File

@@ -671,8 +671,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

@@ -623,11 +623,11 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
};
const { readdir } = fs;
fs.readdir = function (pathArgument: string, options: { encoding?: string | null; withFileTypes?: boolean } = {}, callback?: Function) {
fs.readdir = function (pathArgument: string, options?: { encoding?: string | null; withFileTypes?: boolean } | null, callback?: Function) {
const pathInfo = splitPath(pathArgument);
if (typeof options === 'function') {
callback = options;
options = {};
options = undefined;
}
if (!pathInfo.isAsar) return readdir.apply(this, arguments);
const { asarPath, filePath } = pathInfo;
@@ -646,7 +646,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
return;
}
if (options.withFileTypes) {
if (options && options.withFileTypes) {
const dirents = [];
for (const file of files) {
const childPath = path.join(filePath, file);

View File

@@ -173,13 +173,13 @@ WebContents.prototype.printToPDF = async function (options) {
headerTemplate: '',
footerTemplate: '',
printBackground: false,
scale: 1,
scale: 1.0,
paperWidth: 8.5,
paperHeight: 11,
marginTop: 0,
marginBottom: 0,
marginLeft: 0,
marginRight: 0,
paperHeight: 11.0,
marginTop: 0.4,
marginBottom: 0.4,
marginLeft: 0.4,
marginRight: 0.4,
pageRanges: '',
preferCSSPageSize: false
};
@@ -209,7 +209,7 @@ WebContents.prototype.printToPDF = async function (options) {
if (typeof options.scale !== 'number') {
return Promise.reject(new Error('scale must be a Number'));
}
printSettings.scaleFactor = options.scale;
printSettings.scale = options.scale;
}
const { pageSize } = options;
@@ -449,12 +449,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

@@ -21,8 +21,9 @@ global.module = new Module('electron/js2c/worker_init');
global.require = makeRequireFunction(global.module);
// Set the __filename to the path of html file if it is file: protocol.
if (self.location.protocol === 'file:') {
const pathname = process.platform === 'win32' && self.location.pathname[0] === '/' ? self.location.pathname.substr(1) : self.location.pathname;
// NB. 'self' isn't defined in an AudioWorklet.
if (typeof self !== 'undefined' && self.location.protocol === 'file:') {
const pathname = process.platform === 'win32' && self.location && self.location.pathname[0] === '/' ? self.location.pathname.substr(1) : self.location.pathname;
global.__filename = path.normalize(decodeURIComponent(pathname));
global.__dirname = path.dirname(global.__filename);

View File

@@ -70,29 +70,21 @@ function isInstalled () {
// unzips and makes path.txt point at the correct executable
function extractFile (zipPath) {
return new Promise((resolve, reject) => {
const distPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || path.join(__dirname, 'dist');
const distPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || path.join(__dirname, 'dist');
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);
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) {
try {
fs.renameSync(srcTypeDefPath, targetTypeDefPath);
} catch (err) {
reject(err);
}
}
if (hasTypeDefinitions) {
fs.renameSync(srcTypeDefPath, targetTypeDefPath);
}
// Write a "path.txt" file.
return fs.promises.writeFile(path.join(__dirname, 'path.txt'), platformPath);
})
.catch((err) => reject(err));
// Write a "path.txt" file.
return fs.promises.writeFile(path.join(__dirname, 'path.txt'), platformPath);
});
}

View File

@@ -1,13 +1,14 @@
{
"name": "electron",
"version": "21.1.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",
"@octokit/auth-app": "^2.10.0",
"@electron/asar": "^3.2.1",
"@electron/docs-parser": "^1.0.0",
"@electron/github-app-auth": "^1.5.0",
"@electron/typescript-definitions": "^8.10.0",
"@octokit/rest": "^18.0.3",
"@primer/octicons": "^10.0.0",
"@types/basic-auth": "^1.1.3",
@@ -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 @@
fix_rename_webswapcgllayer_to_webswapcgllayerchromium.patch

View File

@@ -0,0 +1,66 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Milan Burda <milan.burda@gmail.com>
Date: Mon, 10 Oct 2022 15:11:08 +0400
Subject: fix: rename WebSwapCGLLayer to WebSwapCGLLayerChromium
Class WebSwapCGLLayer is implemented in both /System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/WebCore.framework/Versions/A/Frameworks/libANGLE-shared.dylib (0x23c589b50)
and src/out/testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib (0x1123f8488).
One of the two will be used. Which one is undefined.
diff --git a/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h b/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h
index 783a3dff46f04ed07934e516a3c39b061402cc84..056b242ab72eba87b036fc3e56c38a89800f1cdd 100644
--- a/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h
+++ b/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h
@@ -18,7 +18,7 @@ struct __IOSurface;
typedef __IOSurface *IOSurfaceRef;
// WebKit's build process requires that every Objective-C class name has the prefix "Web".
-@class WebSwapCGLLayer;
+@class WebSwapCGLLayerChromium;
namespace rx
{
@@ -87,7 +87,7 @@ class WindowSurfaceCGL : public SurfaceGL
const gl::FramebufferState &state) override;
private:
- WebSwapCGLLayer *mSwapLayer;
+ WebSwapCGLLayerChromium *mSwapLayer;
SharedSwapState mSwapState;
uint64_t mCurrentSwapId;
diff --git a/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm b/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm
index 21894682d4a16f6c4133c4919aba8631f022d1ea..4a4be7f38abbe8242756a6abf810da80e98763c2 100644
--- a/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm
+++ b/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm
@@ -24,7 +24,7 @@
# include "libANGLE/renderer/gl/StateManagerGL.h"
# include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
-@interface WebSwapCGLLayer : CAOpenGLLayer {
+@interface WebSwapCGLLayerChromium : CAOpenGLLayer {
CGLContextObj mDisplayContext;
bool initialized;
@@ -38,7 +38,7 @@ - (id)initWithSharedState:(rx::SharedSwapState *)swapState
withFunctions:(const rx::FunctionsGL *)functions;
@end
-@implementation WebSwapCGLLayer
+@implementation WebSwapCGLLayerChromium
- (id)initWithSharedState:(rx::SharedSwapState *)swapState
withContext:(CGLContextObj)displayContext
withFunctions:(const rx::FunctionsGL *)functions
@@ -213,9 +213,9 @@ - (void)drawInCGLContext:(CGLContextObj)glContext
mSwapState.lastRendered = &mSwapState.textures[1];
mSwapState.beingPresented = &mSwapState.textures[2];
- mSwapLayer = [[WebSwapCGLLayer alloc] initWithSharedState:&mSwapState
- withContext:mContext
- withFunctions:mFunctions];
+ mSwapLayer = [[WebSwapCGLLayerChromium alloc] initWithSharedState:&mSwapState
+ withContext:mContext
+ withFunctions:mFunctions];
[mLayer addSublayer:mSwapLayer];
[mSwapLayer setContentsScale:[mLayer contentsScale]];

View File

@@ -123,3 +123,31 @@ disable_optimization_guide_for_preconnect_feature.patch
fix_the_gn_gen_for_components_segmentation_platform.patch
fix_crash_loading_non-standard_schemes_in_iframes.patch
create_browser_v8_snapshot_file_name_fuse.patch
cherry-pick-c83640db21b5.patch
fix_on-screen-keyboard_hides_on_input_blur_in_webview.patch
build_allow_electron_to_use_exec_script.patch
cherry-pick-67c9cbc784d6.patch
cherry-pick-933cc81c6bad.patch
cherry-pick-65d46507a0c9.patch
cherry-pick-176c526846cb.patch
cherry-pick-f46db6aac3e9.patch
cherry-pick-9b3d0e2f1aab.patch
cherry-pick-42e15c2055c4.patch
cherry-pick-2ef09109c0ec.patch
cherry-pick-f98adc846aad.patch
cherry-pick-eed5a4de2c40.patch
cherry-pick-d1d654d73222.patch
cherry-pick-77208afba04d.patch
cherry-pick-65ad70274d4b.patch
cherry-pick-819d876e1bb8.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-43637378b14e.patch
cherry-pick-57c54ae221d6.patch
cherry-pick-ca2b108a0f1f.patch
cherry-pick-d652130c4bc2.patch
fix_uaf_problem_in_anglevulkanimagebacking.patch
cherry-pick-06851790480e.patch
cherry-pick-e79b89b47dac.patch
m108-lts_simplify_webmediaplayermscompositor_destruction.patch
m108-lts_further_simplify_webmediaplayermscompositor_lifetime.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 7b9768eb315ef8a4d8d61bcf07d43c70f3ea9582..0857ee17a35dabc19c2a04f6a5dd7d631e4b7ee8 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,91 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Tommy C. Li" <tommycli@chromium.org>
Date: Tue, 21 Feb 2023 18:55:00 +0000
Subject: Exclude Policy and Play API engines from Sync merging
There's a security bug in which the call to ResetTemplateURLGUID can
cause a policy-created engine to be deleted. This means that after
the call, either the current `conflicting_turl` pointer, or future
iterations in the loop may point to an already-freed TemplateURL,
causing the use-after free bug.
This CL addresses that by forbidding Policy-created and Play API
engines from being merged into Synced engines.
Although Play API engines aren't directly affected, they seem to also
not be something that should be merged to Synced engines.
(cherry picked from commit 315632458eb795ef9d9dce3fd1062f9e6f2c2077)
Bug: 1414224
Change-Id: Ide43d71e9844e04a7ffe2e7ad2a522b6ca1535a3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4250623
Reviewed-by: Matthew Denton <mpdenton@chromium.org>
Reviewed-by: Mikel Astiz <mastiz@chromium.org>
Commit-Queue: Tommy Li <tommycli@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1106249}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4274984
Reviewed-by: Tommy Li <tommycli@chromium.org>
Commit-Queue: Krishna Govind <govind@chromium.org>
Cr-Commit-Position: refs/branch-heads/5481@{#1238}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/chrome/browser/search_engines/template_url_service_sync_unittest.cc b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
index cc36b62044b14b07b08a176d36d606b96147526b..fb56b5cee060972e17d945d84d26247746277256 100644
--- a/chrome/browser/search_engines/template_url_service_sync_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
@@ -732,6 +732,34 @@ TEST_F(TemplateURLServiceSyncTest, MergeAddFromNewerSyncData) {
processor()->change_for_guid("localguid3").change_type());
}
+TEST_F(TemplateURLServiceSyncTest, MergeIgnoresPolicyAndPlayAPIEngines) {
+ // Add a policy-created engine.
+ model()->Add(CreateTestTemplateURL(u"key1", "http://key1.com", "localguid1",
+ base::Time::FromTimeT(100),
+ /*safe_for_autoreplace=*/false,
+ /*created_by_policy=*/true));
+
+ {
+ auto play_api_engine = CreateTestTemplateURL(
+ u"key2", "http://key2.com", "localguid2", base::Time::FromTimeT(100));
+ TemplateURLData data(play_api_engine->data());
+ data.created_from_play_api = true;
+ play_api_engine = std::make_unique<TemplateURL>(data);
+ model()->Add(std::move(play_api_engine));
+ }
+
+ ASSERT_EQ(1U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
+ MergeAndExpectNotify(CreateInitialSyncData(), 1);
+
+ // The policy engine should be ignored when it comes to conflict resolution.
+ EXPECT_TRUE(model()->GetTemplateURLForGUID("guid1"));
+ EXPECT_TRUE(model()->GetTemplateURLForGUID("localguid1"));
+
+ // The Play API engine should be ignored when it comes to conflict resolution.
+ EXPECT_TRUE(model()->GetTemplateURLForGUID("guid2"));
+ EXPECT_TRUE(model()->GetTemplateURLForGUID("localguid2"));
+}
+
TEST_F(TemplateURLServiceSyncTest, ProcessChangesEmptyModel) {
// We initially have no data.
MergeAndExpectNotify({}, 0);
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc
index 9d84529033d3883ad007025fe766d4b9571b1439..4f2dbf6d2b2e5b51d967eec29b2e59c163bb46fa 100644
--- a/components/search_engines/template_url_service.cc
+++ b/components/search_engines/template_url_service.cc
@@ -2143,7 +2143,14 @@ void TemplateURLService::MergeInSyncTemplateURL(
keyword_to_turl_and_length_.equal_range(sync_turl->keyword());
for (auto it = match_range.first; it != match_range.second; ++it) {
TemplateURL* local_turl = it->second.first;
- if (local_turl->type() == TemplateURL::NORMAL) {
+ // The conflict resolution code below sometimes resets the TemplateURL's
+ // GUID, which can trigger deleting any Policy-created engines. Avoid this
+ // use-after-free bug by excluding any Policy-created engines. Also exclude
+ // Play API created engines, as those also seem local-only and should not
+ // be merged into Synced engines. crbug.com/1414224.
+ if (local_turl->type() == TemplateURL::NORMAL &&
+ !local_turl->created_by_policy() &&
+ !local_turl->created_from_play_api()) {
local_duplicates.push_back(local_turl);
}
}

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 ce813f3d66a3d6841b4b04a625d8fd1a816b4a3e..344336b86d7ebb2df7be50db2d2f737320378342 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" {
@@ -182,7 +183,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);
@@ -222,7 +226,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();
@@ -330,7 +338,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_) {
@@ -357,7 +365,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());
@@ -452,7 +461,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);
@@ -674,7 +684,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));
@@ -716,17 +726,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 3842426dbf494615628d47f9d9d563a631d117ad..2f5c95d79450021a1cbe4b9289f658ba84813453 100644
--- a/mojo/core/channel_unittest.cc
+++ b/mojo/core/channel_unittest.cc
@@ -714,6 +714,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,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 0a978ee553cd3bf4b15b923fbf8b93789c441774..1a79fa26c069d10e9e03390f161d70d2adb7b07e 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
@@ -200,34 +200,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();
@@ -235,6 +210,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 c4be7a96144ac53be856fbf52dff8e990aa736aa..12183222040fd9ab3e202a510cc71f2ccbf2e4c4 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -418,6 +418,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 7091b979bed2c3ee375453ebc68aa83102745f35..b485bb1a08bc58bc1738c97c0311dc2d47d233e2 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"
@@ -215,6 +216,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 4786257911cd9cb01222ef375698e0ae669d8ccb..94e04ff48d7a395cd673a9ececd598d00e735ff5 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -537,19 +537,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 7e73ad64a9b28396473adefaefd6430f81e61011..118ca880ffba6cc96a51b7b083119bd41f990e15 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 cd5f11083e268cdf0fca94c9fd9f8d56433b299b..38e0babfb9425d8611df97f8f6a325d6fca513fd 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
@@ -86,6 +86,8 @@ ValidationMessageOverlayDelegate::~ValidationMessageOverlayDelegate() {
EventDispatchForbiddenScope::AllowUserAgentEvents allow_events;
page_->WillBeDestroyed();
}
+ if (destroyed_ptr_)
+ *destroyed_ptr_ = true;
}
LocalFrameView& ValidationMessageOverlayDelegate::FrameView() const {
@@ -176,7 +178,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 105011c25861fe00cc8e72fe8f310ee5118725c3..86535284fedeb875b4958322fdddaa52507cfbaa 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -561,11 +561,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,97 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Victor Vasiliev <vasilvv@chromium.org>
Date: Wed, 21 Dec 2022 17:26:42 +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.
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-Commit-Position: refs/heads/main@{#1085965}
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,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 f2380053969cbb5292eaec3b4b01e7358788ef54..898d66ce5d9ce43ff55b426dca933014918c9339 100644
--- a/media/capture/video/win/video_capture_device_win.cc
+++ b/media/capture/video/win/video_capture_device_win.cc
@@ -872,34 +872,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 98fc82b48ff020c49fdeab1adae947a84873f6b2..dad6051bc712e6b923ec26b0abc56625d8dcbed5 100644
--- a/services/audio/stream_factory.cc
+++ b/services/audio/stream_factory.cc
@@ -184,8 +184,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();
@@ -257,9 +258,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
@@ -268,13 +270,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,680 @@
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 0bbdc8c38a99986d5b8f70f5582f78c7f8be3fa0..7f8ed5f1e0eef6db0504ad3e075d76738bc07243 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"
@@ -45,6 +46,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 {
// ExtensionFrameHostInterceptor is a helper for:
@@ -280,6 +285,10 @@ class ExtensionSecurityExploitBrowserTest : public ExtensionBrowserTest {
InstallTestExtensions();
}
+ 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,
@@ -293,36 +302,63 @@ class ExtensionSecurityExploitBrowserTest : public ExtensionBrowserTest {
browser()->profile(), extension_id, background_script);
}
+ const Extension& active_extension() { return *active_extension_; }
const ExtensionId& active_extension_id() { return active_extension_->id(); }
const ExtensionId& spoofed_extension_id() { return spoofed_extension_->id(); }
private:
+ // Installs an `active_extension` and a separate, but otherwise identical
+ // `spoofed_extension` (the only difference will be the extension id).
void InstallTestExtensions() {
- // Install an `active_extension` and a separate, but otherwise identical
- // `spoofed_extension` (the only difference will be the extension id).
- auto install_extension = [this](TestExtensionDir& dir) -> const Extension* {
+ auto install_extension =
+ [this](TestExtensionDir& dir,
+ const char* extra_manifest_bits) -> const Extension* {
const char kManifestTemplate[] = R"(
{
+ %s
"name": "ContentScriptTrackerBrowserTest - Programmatic",
"version": "1.0",
"manifest_version": 2,
- "permissions": [ "tabs", "<all_urls>", "storage" ],
+ "permissions": [
+ "tabs",
+ "<all_urls>",
+ "nativeMessaging",
+ "storage"
+ ],
"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());
}
+ TestExtensionDir active_dir_;
+ TestExtensionDir spoofed_dir_;
raw_ptr<const Extension> active_extension_ = nullptr;
raw_ptr<const Extension> spoofed_extension_ = nullptr;
};
@@ -333,48 +369,35 @@ class OpenChannelToExtensionExploitTest
public:
OpenChannelToExtensionExploitTest() = default;
+ using OpenChannelMessageWaiter =
+ ExtensionMessageWaiter<ExtensionHostMsg_OpenChannelToExtension>;
void SetUpOnMainThread() override {
ExtensionSecurityExploitBrowserTest::SetUpOnMainThread();
- GURL test_page_url =
- embedded_test_server()->GetURL("foo.com", "/title1.html");
- ipc_message_waiter_ = StartInterceptingIpcs(test_page_url);
- }
-
- // Waits for ExtensionHostMsg_OpenChannelToExtension IPC and returns its
- // payload.
- ExtensionHostMsg_OpenChannelToExtension::Param WaitForMessage() {
- return ipc_message_waiter_->WaitForMessage();
- }
-
- private:
- 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.
ExtensionId 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) {
@@ -391,14 +414,16 @@ class OpenChannelToExtensionExploitTest
return true;
}));
+ }
- return ipc_message_waiter;
+ // Waits for ExtensionHostMsg_OpenChannelToExtension IPC and returns its
+ // payload.
+ ExtensionHostMsg_OpenChannelToExtension::Param WaitForMessage() {
+ return ipc_message_waiter_->WaitForMessage();
}
+ private:
std::unique_ptr<OpenChannelMessageWaiter> ipc_message_waiter_;
-
- raw_ptr<const Extension> active_extension_ = nullptr;
- raw_ptr<const Extension> spoofed_extension_ = nullptr;
};
IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
@@ -412,24 +437,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(),
@@ -443,24 +466,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(),
@@ -473,24 +494,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(),
@@ -504,25 +523,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(),
@@ -536,18 +553,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,
@@ -556,7 +571,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(),
@@ -566,21 +581,115 @@ IN_PROC_BROWSER_TEST_F(OpenChannelToExtensionExploitTest,
kill_waiter.Wait());
}
+// Native messaging is not available on Fuchsia (i.e.
+// //chrome/browser/extensions/BUILD.gn excludes
+// api/messaging/native_messaging_test_util.h on Fuchsia).
+#if !(BUILDFLAG(IS_FUCHSIA))
+
+// Test suite for covering ExtensionHostMsg_OpenChannelToNativeApp IPC.
+class OpenChannelToNativeAppExploitTest
+ : public ExtensionSecurityExploitBrowserTest {
+ public:
+ OpenChannelToNativeAppExploitTest() = default;
+
+ using OpenChannelMessageWaiter =
+ ExtensionMessageWaiter<ExtensionHostMsg_OpenChannelToNativeApp>;
+ void SetUpOnMainThread() override {
+ // Set up ExtensionMessageWaiter *before* installing the extensions (i.e.
+ // *before* the corresponding RenderProcessHost objects are created).
+ ipc_message_waiter_ = std::make_unique<OpenChannelMessageWaiter>();
+
+ // SetUpOnMainThread in the base class will install the test extensions.
+ ExtensionSecurityExploitBrowserTest::SetUpOnMainThread();
+
+ // Register a (fake, test-only) native messaging host.
+ test_native_messaging_host_.RegisterTestHost(/* user_level= */ false);
+
+ // Navigate the test tab to an extension page.
+ GURL test_page_url = active_extension().GetResourceURL("page.html");
+ EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url));
+
+ // Only intercept messages from the test process.
+ int matching_process_id =
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
+ ipc_message_waiter_->SetIpcMatcher(base::BindLambdaForTesting(
+ [matching_process_id](
+ int captured_render_process_id,
+ const ExtensionHostMsg_OpenChannelToNativeApp::Param& param) {
+ if (captured_render_process_id != matching_process_id)
+ return false;
+
+ return true;
+ }));
+ }
+
+ // Waits for ExtensionHostMsg_OpenChannelToNativeApp IPC and returns its
+ // payload.
+ ExtensionHostMsg_OpenChannelToNativeApp::Param WaitForMessage() {
+ return ipc_message_waiter_->WaitForMessage();
+ }
+
+ private:
+ ScopedTestNativeMessagingHost test_native_messaging_host_;
+ std::unique_ptr<OpenChannelMessageWaiter> ipc_message_waiter_;
+};
+
+IN_PROC_BROWSER_TEST_F(OpenChannelToNativeAppExploitTest,
+ SourceContextWithSpoofedExtensionId) {
+ // Trigger sending of a valid ExtensionHostMsg_OpenChannelToNativeApp IPC
+ // from a frame of an `active_extension`.
+ const char kScript[] = R"(
+ var message = {text: 'Hello!'};
+ var host = $1;
+ chrome.runtime.sendNativeMessage(host, message);
+ )";
+ ASSERT_EQ(
+ active_extension().origin(),
+ active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
+ ASSERT_TRUE(content::ExecuteScript(
+ active_web_contents(),
+ content::JsReplace(kScript, ScopedTestNativeMessagingHost::kHostName)));
+
+ // Capture the IPC.
+ auto [source_context, native_app_name, port_id] = WaitForMessage();
+ EXPECT_EQ(native_app_name, ScopedTestNativeMessagingHost::kHostName);
+ EXPECT_TRUE(source_context.is_for_render_frame());
+
+ // Mutate the IPC payload.
+ source_context = PortContext::ForWorker(123, // thread_id
+ 456, // version_id
+ spoofed_extension_id());
+
+ // Inject the malformed/mutated IPC and verify that the renderer is terminated
+ // as expected.
+ content::RenderProcessHost* main_frame_process =
+ active_web_contents()->GetPrimaryMainFrame()->GetProcess();
+ RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
+ IPC::IpcSecurityTestUtil::PwnMessageReceived(
+ main_frame_process->GetChannel(),
+ ExtensionHostMsg_OpenChannelToNativeApp(source_context, native_app_name,
+ port_id));
+ EXPECT_EQ(bad_message::EMF_INVALID_EXTENSION_ID_FOR_WORKER_CONTEXT,
+ kill_waiter.Wait());
+}
+
+#endif // !(BUILDFLAG(IS_FUCHSIA)) - native messaging is available
+
IN_PROC_BROWSER_TEST_F(ExtensionSecurityExploitBrowserTest,
SpoofedExtensionId_ExtensionFunctionDispatcher) {
// Navigate to a test page.
GURL test_page_url =
embedded_test_server()->GetURL("foo.com", "/title1.html");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url));
- content::WebContents* web_contents =
- browser()->tab_strip_model()->GetActiveWebContents();
- content::RenderFrameHost* main_frame = web_contents->GetPrimaryMainFrame();
+ content::RenderFrameHost* main_frame =
+ active_web_contents()->GetPrimaryMainFrame();
// Verify the test setup by checking if the non-intercepted `chrome.storage`
// API call will succeed.
{
ExtensionTestMessageListener listener("Got chrome.storage response");
- ExecuteProgrammaticContentScript(web_contents, active_extension_id(), R"(
+ ExecuteProgrammaticContentScript(active_web_contents(),
+ active_extension_id(), R"(
chrome.storage.local.set(
{ test_key: 'test value'},
() => {
@@ -607,7 +716,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionSecurityExploitBrowserTest,
// terminating the misbehaving renderer process.
content::RenderProcessHostBadMojoMessageWaiter kill_waiter(
main_frame->GetProcess());
- ExecuteProgrammaticContentScript(web_contents, active_extension_id(), R"(
+ ExecuteProgrammaticContentScript(active_web_contents(), active_extension_id(),
+ R"(
chrome.storage.local.set({ test_key: 'test value2'}, () => {}); )");
EXPECT_EQ(
"Received bad user message: LocalFrameHost::Request: renderer never "
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 25af213a4c02d7994eddb4dcb29a37871accd807..faf61a3b2bcb531934b8522b95b64930fff463dd 100644
--- a/extensions/browser/api/messaging/messaging_api_message_filter.cc
+++ b/extensions/browser/api/messaging/messaging_api_message_filter.cc
@@ -146,6 +146,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;
}
@@ -217,6 +227,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) {
@@ -262,19 +284,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;
@@ -293,7 +310,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,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 115f0e5774a3adde821bd34e5fac6645989e400e..4255884857a8d869a7a1e4f262f0f487dde16e24 100644
--- a/third_party/blink/renderer/platform/widget/widget_base.cc
+++ b/third_party/blink/renderer/platform/widget/widget_base.cc
@@ -893,8 +893,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,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 5aa120cd2e9fab1492f5d0993adbb2f80a4aa732..2acd2216331bd9be56eb9705f0e9c0d3bceb9e93 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 8183cb7e6547f42b27afc323fe136e2157e4dd03..dbdf244571956645c6494c4cdab514dd42dbb6c2 100644
--- a/content/test/content_browser_test_utils_internal.cc
+++ b/content/test/content_browser_test_utils_internal.cc
@@ -447,9 +447,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;
@@ -457,16 +462,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 6ae5e8f81a189702d5ed9bef003696f34c525dd3..3bf1bb93e15b0a5270262837802e140ad72a9231 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,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 43577925d2ef9cd79970d8307104e0abc1756583..0819d4cc1b17f216eae8c1a562b0301ba6298d57 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.
@@ -103,11 +108,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]
@@ -116,6 +123,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 6da9e3f038869f204074aabfd8ec8a0dbc659ab6..ec4b8985b5fb072ea98f4c36a3d0b341000d96ad 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -741,10 +741,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 8166a6fa6c9aff9d724200cbbfac189d3f887735..ee694f5820b4947dc5815a5dd2f41ecfd1c9cb4c 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
@@ -806,6 +806,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),
@@ -1160,6 +1162,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;
@@ -1198,8 +1202,8 @@ bool RTCPeerConnectionHandler::Initialize(
peer_connection_tracker_->RegisterPeerConnection(this, configuration_,
frame_);
}
-
- return true;
+ // Gratuitous usage of client_on_stack to prevent compiler errors.
+ return !!client_on_stack;
}
bool RTCPeerConnectionHandler::InitializeForTest(
@@ -2259,9 +2263,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,
@@ -2573,8 +2579,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_) {
@@ -2594,7 +2604,7 @@ void RTCPeerConnectionHandler::OnIceCandidate(const String& sdp,
}
}
if (!is_closed_)
- client_->DidGenerateICECandidate(platform_candidate);
+ client_on_stack->DidGenerateICECandidate(platform_candidate);
}
void RTCPeerConnectionHandler::OnIceCandidateError(
@@ -2606,7 +2616,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,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,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,58 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Vasiliy Telezhnikov <vasilyt@chromium.org>
Date: Fri, 10 Feb 2023 17:36:57 +0000
Subject: CHECK that YUV readback finished synchronously
DoReadbackYUVImagePixelsINTERNAL is implemented using skia asynchronous
readback and to make it synchronous we use sync cpu and gpu. In some
edge cases on linux we saw that doesn't happen if readback triggered
vulkan device lost.
To avoid use after free, CHECK that callback was actually called. In
case of device-lost gpu process will restart anyway, so while this is
not proper fix of the problem, it doesn't result in worse user visible
behaviour.
(cherry picked from commit 081df1e7d3712131bcaa575bda2e37ec7f6aa83d)
Bug: 1399742
Change-Id: Ie2172539bb907b9696ef62c70d398aca3967177c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4143606
Reviewed-by: Peng Huang <penghuang@chromium.org>
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1093064}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4239960
Cr-Commit-Position: refs/branch-heads/5481@{#1084}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc
index 23260eb92a8f09159dadb1167d8f2a90a6fd21c6..ecfbf5d92a8aa738aea5d26af82d3c1d2e7c04be 100644
--- a/gpu/command_buffer/service/raster_decoder.cc
+++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -2680,6 +2680,7 @@ void RasterDecoderImpl::DoReadbackARGBImagePixelsINTERNAL(
namespace {
struct YUVReadbackResult {
std::unique_ptr<const SkImage::AsyncReadResult> async_result;
+ bool finished = false;
};
void OnReadYUVImagePixelsDone(
@@ -2687,6 +2688,7 @@ void OnReadYUVImagePixelsDone(
std::unique_ptr<const SkImage::AsyncReadResult> async_result) {
YUVReadbackResult* context = reinterpret_cast<YUVReadbackResult*>(raw_ctx);
context->async_result = std::move(async_result);
+ context->finished = true;
}
} // namespace
@@ -2884,6 +2886,10 @@ void RasterDecoderImpl::DoReadbackYUVImagePixelsINTERNAL(
// asynchronous by removing this flush and implementing a query that can
// signal back to client process.
gr_context()->flushAndSubmit(true);
+
+ // The call above will sync up gpu and CPU, resulting in callback being run
+ // during flushAndSubmit. To prevent UAF make sure it indeed happened.
+ CHECK(yuv_result.finished);
if (!yuv_result.async_result) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadbackYUVImagePixels",
"Failed to read pixels from SkImage");

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 351bee9cfcc31dc6ca06f1fc502b70617105191a..d98e590beccfb19730528d598e32df4b4d00942b 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -365,6 +365,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();
}
@@ -1461,7 +1462,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) {
@@ -1482,24 +1483,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);
}
@@ -1510,10 +1510,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();
@@ -1523,7 +1524,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()) {
@@ -1534,13 +1534,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 2acd2216331bd9be56eb9705f0e9c0d3bceb9e93..d988e221688ee19493e43c0b5f736fa432843cd0 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 dbdf244571956645c6494c4cdab514dd42dbb6c2..70166cf3470595c928b202325f56f17abd0a61ac 100644
--- a/content/test/content_browser_test_utils_internal.cc
+++ b/content/test/content_browser_test_utils_internal.cc
@@ -448,12 +448,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;
@@ -462,6 +466,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_) {
@@ -469,7 +476,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 3bf1bb93e15b0a5270262837802e140ad72a9231..6bd95d55add1c0da850be6078d02c3eae479ea62 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,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 4e6d62be68d59c8a49159fda4d1e68f101a6f0a3..cfd5a01ea84a1f454a5172da3e96e66a50c82939 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
@@ -992,6 +992,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 70b151bcb8e3b1964d316bf2e169dbe0f28f24c7..c3857298974a0c2761efcd3924587607997e3117 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
@@ -181,6 +181,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 74993d461cbd0885a709cf8b663b9c69650aa3cf..940045d9bbb62676811f55f5d30a93a352f43ede 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -7928,7 +7928,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,85 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peng Huang <penghuang@chromium.org>
Date: Mon, 13 Feb 2023 22:10:44 +0000
Subject: Fix UAF problem in AngleVulkanImageBacking
Right now, we use vulkan fence helper to release the backing.
It is right, if the last usage of the backing is by skia.
If the last usage is by gl, the fence helper(skia) isn't aware of
the submitted work from ANGLE, skia may call flush finish callback
to release the backing while the backing is still being referenced
by works in ANGLE. Fix the problem by calling glFinish() if the last
usage is GL.
Know issue: the finish callback of skia flush() is not always called
in order. So in edge cases, the UAF problem can still happen.
(cherry picked from commit d5143b14a00807b40eada4dfb0bce610ffc1477a)
Bug: 1309035
Change-Id: I3562043650dd2b27bde3a370bef45b1226cdd48c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4232858
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1102905}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4245959
Cr-Commit-Position: refs/branch-heads/5481@{#1119}
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.cc
index 84a64950db48dfa43f55793033dcf26af3b4a725..bfe2080e5ab844f3f9a7ccad8cfe7b4336ed68f1 100644
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.cc
@@ -80,6 +80,11 @@ class AngleVulkanImageBacking : public ClearTrackingSharedImageBacking,
passthrough_texture_.reset();
egl_image_.reset();
+
+ if (need_gl_finish_before_destroy_ && have_context()) {
+ gl::GLApi* api = gl::g_current_gl_context;
+ api->glFinishFn();
+ }
}
if (vulkan_image_) {
auto* fence_helper = context_state_->vk_context_provider()
@@ -266,8 +271,9 @@ class AngleVulkanImageBacking : public ClearTrackingSharedImageBacking,
--gl_reads_in_process_;
// For the last GL read access, release texture from ANGLE.
- if (gl_reads_in_process_ == 0)
+ if (gl_reads_in_process_ == 0) {
ReleaseTextureANGLE();
+ }
return;
}
@@ -299,6 +305,9 @@ class AngleVulkanImageBacking : public ClearTrackingSharedImageBacking,
GLuint texture = passthrough_texture_->service_id();
// Release the texture from ANGLE, so it can be used elsewhere.
api->glReleaseTexturesANGLEFn(1, &texture, &layout_);
+ // Releasing the texture will submit all related works to queue, so to be
+ // safe, glFinish() should be called before releasing the VkImage.
+ need_gl_finish_before_destroy_ = true;
}
void PrepareBackendTexture() {
@@ -383,6 +392,11 @@ class AngleVulkanImageBacking : public ClearTrackingSharedImageBacking,
return;
}
+ // The backing is used by skia, so skia should submit related work to the
+ // queue, and we can use vulkan fence helper to release the VkImage.
+ // glFinish() is not necessary anymore.
+ need_gl_finish_before_destroy_ = false;
+
SyncImageLayoutFromBackendTexture();
if (gl_reads_in_process_ > 0) {
@@ -449,6 +463,7 @@ class AngleVulkanImageBacking : public ClearTrackingSharedImageBacking,
bool is_gl_write_in_process_ = false;
int skia_reads_in_process_ = 0;
int gl_reads_in_process_ = 0;
+ bool need_gl_finish_before_destroy_ = false;
};
class AngleVulkanImageBacking::SkiaAngleVulkanImageRepresentation

View File

@@ -0,0 +1,381 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Mon, 20 Feb 2023 13:16:32 +0000
Subject: Further simplify WebMediaPlayerMSCompositor lifetime.
M108 merge issues:
third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc:
- video_task_runner_ is named io_task_runner_ in 108
third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc:
- video_task_runner_ is named io_task_runner_ in 108 (conflict in ReplaceCurrentFrameWithACopy)
Due to the raw pointer held by VideoFrameSubmitter, there may be
tasks pending on the compositor task runner after the RefCounted
traits have "destructed" WebMediaPlayerMSCompositor. Through this
raw pointer VFS was invoking OnContextLost which attempts to use
the zero ref count compositor.
The solution here is again similar to VideoFrameCompositor, its
destruction should be explicit instead of a tangle of RefCounted
owners.
(cherry picked from commit 1622bffc6534a0cc4f53d07c43e0cd8f49975d10)
Fixed: 1407701, 1411601
Change-Id: Ic77294d1113d54ab83bc0f5b625a997edf57bf7c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4210508
Commit-Queue: Tony Herre <toprice@chromium.org>
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1099726}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4225393
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Reviewed-by: Oleh Lamzin <lamzin@google.com>
Owners-Override: Oleh Lamzin <lamzin@google.com>
Cr-Commit-Position: refs/branch-heads/5359@{#1392}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
index e67725f91f57ffbdf17e5830bd12c38010a9625c..0e8908e847a956f5e3a99f232e8db1131294b856 100644
--- a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
+++ b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
@@ -207,6 +207,8 @@ class BLINK_MODULES_EXPORT WebMediaPlayerMS
static const gfx::Size kUseGpuMemoryBufferVideoFramesMinResolution;
#endif // BUILDFLAG(IS_WIN)
+ void ReplaceCurrentFrameWithACopy();
+
bool IsInPictureInPicture() const;
// Switch to SurfaceLayer, either initially or from VideoLayer.
@@ -309,7 +311,7 @@ class BLINK_MODULES_EXPORT WebMediaPlayerMS
// Used for DCHECKs to ensure methods calls executed in the correct thread.
THREAD_CHECKER(thread_checker_);
- scoped_refptr<WebMediaPlayerMSCompositor> compositor_;
+ std::unique_ptr<WebMediaPlayerMSCompositor> compositor_;
const WebString initial_audio_output_device_id_;
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
index 5b075cc0acecf71097549b0cbfb044fa4766e851..9dd6d360831647f9da3e04a54c7fc7828d6b5bbd 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -399,8 +399,9 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
SendLogMessage(
String::Format("%s() [delegate_id=%d]", __func__, delegate_id_));
- if (!web_stream_.IsNull())
+ if (!web_stream_.IsNull()) {
web_stream_.RemoveObserver(this);
+ }
// Destruct compositor resources in the proper order.
get_client()->SetCcLayer(nullptr);
@@ -409,14 +410,35 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
video_layer_->StopUsingProvider();
}
- if (frame_deliverer_)
- io_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release());
+ if (frame_deliverer_) {
+ io_task_runner_->DeleteSoon(FROM_HERE, std::move(frame_deliverer_));
+ }
- if (video_frame_provider_)
+ if (video_frame_provider_) {
video_frame_provider_->Stop();
+ }
- if (audio_renderer_)
+ // This must be destroyed before `compositor_` since it will grab a couple of
+ // final metrics during destruction.
+ watch_time_reporter_.reset();
+
+ if (compositor_) {
+ // `compositor_` receives frames on `io_task_runner_` from
+ // `frame_deliverer_` and operates on the `compositor_task_runner_`, so
+ // must trampoline through both to ensure a safe destruction.
+ PostCrossThreadTask(
+ *io_task_runner_, FROM_HERE,
+ WTF::CrossThreadBindOnce(
+ [](scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ std::unique_ptr<WebMediaPlayerMSCompositor> compositor) {
+ task_runner->DeleteSoon(FROM_HERE, std::move(compositor));
+ },
+ compositor_task_runner_, std::move(compositor_)));
+ }
+
+ if (audio_renderer_) {
audio_renderer_->Stop();
+ }
media_log_->AddEvent<media::MediaLogEvent::kWebMediaPlayerDestroyed>();
@@ -457,7 +479,7 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
watch_time_reporter_.reset();
- compositor_ = base::MakeRefCounted<WebMediaPlayerMSCompositor>(
+ compositor_ = std::make_unique<WebMediaPlayerMSCompositor>(
compositor_task_runner_, io_task_runner_, web_stream_,
std::move(submitter_), use_surface_layer_, weak_this_);
@@ -480,7 +502,7 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
frame_deliverer_ = std::make_unique<WebMediaPlayerMS::FrameDeliverer>(
weak_this_,
CrossThreadBindRepeating(&WebMediaPlayerMSCompositor::EnqueueFrame,
- compositor_),
+ CrossThreadUnretained(compositor_.get())),
media_task_runner_, worker_task_runner_, gpu_factories_);
video_frame_provider_ = renderer_factory_->GetVideoRenderer(
web_stream_,
@@ -823,7 +845,19 @@ void WebMediaPlayerMS::Pause() {
video_frame_provider_->Pause();
compositor_->StopRendering();
- compositor_->ReplaceCurrentFrameWithACopy();
+
+ // Bounce this call off of video task runner to since there might still be
+ // frames passed on video task runner.
+ PostCrossThreadTask(
+ *io_task_runner_, FROM_HERE,
+ WTF::CrossThreadBindOnce(
+ [](scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ WTF::CrossThreadOnceClosure copy_cb) {
+ PostCrossThreadTask(*task_runner, FROM_HERE, std::move(copy_cb));
+ },
+ main_render_task_runner_,
+ WTF::CrossThreadBindOnce(
+ &WebMediaPlayerMS::ReplaceCurrentFrameWithACopy, weak_this_)));
if (audio_renderer_)
audio_renderer_->Pause();
@@ -838,6 +872,11 @@ void WebMediaPlayerMS::Pause() {
paused_ = true;
}
+void WebMediaPlayerMS::ReplaceCurrentFrameWithACopy() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ compositor_->ReplaceCurrentFrameWithACopy();
+}
+
void WebMediaPlayerMS::Seek(double seconds) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}
@@ -1184,7 +1223,8 @@ void WebMediaPlayerMS::ActivateSurfaceLayerForVideo(
PostCrossThreadTask(
*compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::EnableSubmission,
- compositor_, bridge_->GetSurfaceId(), video_transform,
+ CrossThreadUnretained(compositor_.get()),
+ bridge_->GetSurfaceId(), video_transform,
IsInPictureInPicture()));
// If the element is already in Picture-in-Picture mode, it means that it
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
index 2be89c9104c493d2672436fb8d36d6f10e4f6939..51b5c56a7acc31643290f5a92cd416c81c0c507c 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
@@ -195,18 +195,18 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
dropped_frame_count_(0),
stopped_(true),
render_started_(!stopped_) {
+ weak_this_ = weak_ptr_factory_.GetWeakPtr();
if (use_surface_layer) {
submitter_ = std::move(submitter);
PostCrossThreadTask(
*video_frame_compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::InitializeSubmitter,
- weak_ptr_factory_.GetWeakPtr()));
+ weak_this_));
update_submission_state_callback_ = base::BindPostTask(
video_frame_compositor_task_runner_,
ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
- &WebMediaPlayerMSCompositor::SetIsSurfaceVisible,
- weak_ptr_factory_.GetWeakPtr())));
+ &WebMediaPlayerMSCompositor::SetIsSurfaceVisible, weak_this_)));
}
HeapVector<Member<MediaStreamComponent>> video_components;
@@ -234,27 +234,12 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
}
WebMediaPlayerMSCompositor::~WebMediaPlayerMSCompositor() {
- // Ensured by destructor traits.
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
if (video_frame_provider_client_) {
video_frame_provider_client_->StopUsingProvider();
}
}
-// static
-void WebMediaPlayerMSCompositorTraits::Destruct(
- const WebMediaPlayerMSCompositor* compositor) {
- if (!compositor->video_frame_compositor_task_runner_
- ->BelongsToCurrentThread()) {
- PostCrossThreadTask(
- *compositor->video_frame_compositor_task_runner_, FROM_HERE,
- CrossThreadBindOnce(&WebMediaPlayerMSCompositorTraits::Destruct,
- CrossThreadUnretained(compositor)));
- return;
- }
- delete compositor;
-}
-
void WebMediaPlayerMSCompositor::InitializeSubmitter() {
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
submitter_->Initialize(this, /*is_media_stream=*/true);
@@ -300,7 +285,7 @@ void WebMediaPlayerMSCompositor::SetForceBeginFrames(bool enable) {
PostCrossThreadTask(
*video_frame_compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::SetForceBeginFrames,
- weak_ptr_factory_.GetWeakPtr(), enable));
+ weak_this_, enable));
return;
}
@@ -602,7 +587,7 @@ void WebMediaPlayerMSCompositor::StartRendering() {
PostCrossThreadTask(
*video_frame_compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::StartRenderingInternal,
- WrapRefCounted(this)));
+ weak_this_));
}
void WebMediaPlayerMSCompositor::StopRendering() {
@@ -610,18 +595,7 @@ void WebMediaPlayerMSCompositor::StopRendering() {
PostCrossThreadTask(
*video_frame_compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::StopRenderingInternal,
- WrapRefCounted(this)));
-}
-
-void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- // Bounce this call off of IO thread to since there might still be frames
- // passed on IO thread.
- io_task_runner_->PostTask(
- FROM_HERE,
- media::BindToCurrentLoop(WTF::Bind(
- &WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal,
- WrapRefCounted(this))));
+ weak_this_));
}
bool WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks(
@@ -691,7 +665,7 @@ void WebMediaPlayerMSCompositor::RenderWithoutAlgorithm(
*video_frame_compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(
&WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor,
- WrapRefCounted(this), std::move(frame), is_copy));
+ weak_this_, std::move(frame), is_copy));
}
void WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor(
@@ -791,9 +765,8 @@ void WebMediaPlayerMSCompositor::SetCurrentFrame(
PostCrossThreadTask(
*video_frame_compositor_task_runner_, FROM_HERE,
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::CheckForFrameChanges,
- WrapRefCounted(this), is_first_frame,
- has_frame_size_changed, std::move(new_transform),
- std::move(new_opacity)));
+ weak_this_, is_first_frame, has_frame_size_changed,
+ std::move(new_transform), std::move(new_opacity)));
}
void WebMediaPlayerMSCompositor::CheckForFrameChanges(
@@ -860,7 +833,7 @@ void WebMediaPlayerMSCompositor::StopRenderingInternal() {
video_frame_provider_client_->StopRendering();
}
-void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal() {
+void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
scoped_refptr<media::VideoFrame> current_frame_ref;
{
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
index a8565180d57a80f596bbd28690c7c6ceefe6474b..915933b75dc957ab84643ac1b5d1db2f3296d767 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
@@ -24,7 +24,6 @@
#include "third_party/blink/renderer/modules/mediastream/video_renderer_algorithm_wrapper.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
namespace base {
class SingleThreadTaskRunner;
@@ -46,7 +45,6 @@ class SurfaceId;
namespace blink {
class MediaStreamDescriptor;
class WebMediaPlayerMS;
-struct WebMediaPlayerMSCompositorTraits;
// This class is designed to handle the work load on compositor thread for
// WebMediaPlayerMS. It will be instantiated on the main thread, but destroyed
@@ -58,9 +56,7 @@ struct WebMediaPlayerMSCompositorTraits;
// Otherwise, WebMediaPlayerMSCompositor will simply store the most recent
// frame, and submit it whenever asked by the compositor.
class MODULES_EXPORT WebMediaPlayerMSCompositor
- : public cc::VideoFrameProvider,
- public WTF::ThreadSafeRefCounted<WebMediaPlayerMSCompositor,
- WebMediaPlayerMSCompositorTraits> {
+ : public cc::VideoFrameProvider {
public:
using OnNewFramePresentedCB = base::OnceClosure;
@@ -76,6 +72,7 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
std::unique_ptr<WebVideoFrameSubmitter> submitter,
bool use_surface_layer,
const base::WeakPtr<WebMediaPlayerMS>& player);
+ ~WebMediaPlayerMSCompositor() override;
WebMediaPlayerMSCompositor(const WebMediaPlayerMSCompositor&) = delete;
WebMediaPlayerMSCompositor& operator=(const WebMediaPlayerMSCompositor&) =
@@ -143,10 +140,7 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
Metadata GetMetadata();
private:
- friend class WTF::ThreadSafeRefCounted<WebMediaPlayerMSCompositor,
- WebMediaPlayerMSCompositorTraits>;
friend class WebMediaPlayerMSTest;
- friend struct WebMediaPlayerMSCompositorTraits;
// Struct used to keep information about frames pending in
// |rendering_frame_buffer_|.
@@ -157,8 +151,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
bool is_copy;
};
- ~WebMediaPlayerMSCompositor() override;
-
// Ran on the |video_frame_compositor_task_runner_| to initialize
// |submitter_|
void InitializeSubmitter();
@@ -204,7 +196,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
void StartRenderingInternal();
void StopRenderingInternal();
- void ReplaceCurrentFrameWithACopyInternal();
void SetAlgorithmEnabledForTesting(bool algorithm_enabled);
void RecordFrameDisplayedStats(base::TimeTicks frame_displayed_time);
@@ -314,15 +305,10 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
// |dropped_frame_count_|, |current_metadata_| and |render_started_|.
base::Lock current_frame_lock_;
+ base::WeakPtr<WebMediaPlayerMSCompositor> weak_this_;
base::WeakPtrFactory<WebMediaPlayerMSCompositor> weak_ptr_factory_{this};
};
-struct WebMediaPlayerMSCompositorTraits {
- // Ensure destruction occurs on main thread so that "Web" and other resources
- // are destroyed on the correct thread.
- static void Destruct(const WebMediaPlayerMSCompositor* player);
-};
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_WEBMEDIAPLAYER_MS_COMPOSITOR_H_

View File

@@ -0,0 +1,124 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Mon, 20 Feb 2023 10:08:49 +0000
Subject: Simplify WebMediaPlayerMSCompositor destruction.
The code was only sometimes calling StopUsingProvider() and posted
the submitter destruction unnecessarily.
Destruction now works the same as in VideoFrameCompositor, where the
class itself is responsible for calling StopUsingProvider() during
its own destruction.
(cherry picked from commit cbd238e85903b7d94910bd2c6362ff9abf9908cc)
Fixed: 1407701
Disallow-Recycled-Builds: test-failures
Change-Id: Ia649cb5532519468eea34e12745ed9c990580d82
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4195824
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Commit-Queue: Tony Herre <toprice@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1098505}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4225498
Reviewed-by: Oleh Lamzin <lamzin@google.com>
Owners-Override: Oleh Lamzin <lamzin@google.com>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/5359@{#1391}
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
index 6079ca1dd6248654e3cdf7aa52bcd39c9f15ed08..5b075cc0acecf71097549b0cbfb044fa4766e851 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -412,9 +412,6 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
if (frame_deliverer_)
io_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release());
- if (compositor_)
- compositor_->StopUsingProvider();
-
if (video_frame_provider_)
video_frame_provider_->Stop();
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
index 146613e57db9a5747e45b686336eae3a8b2f7978..2be89c9104c493d2672436fb8d36d6f10e4f6939 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
@@ -236,13 +236,8 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
WebMediaPlayerMSCompositor::~WebMediaPlayerMSCompositor() {
// Ensured by destructor traits.
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
-
- if (submitter_) {
- video_frame_compositor_task_runner_->DeleteSoon(FROM_HERE,
- std::move(submitter_));
- } else {
- DCHECK(!video_frame_provider_client_)
- << "Must call StopUsingProvider() before dtor!";
+ if (video_frame_provider_client_) {
+ video_frame_provider_client_->StopUsingProvider();
}
}
@@ -262,7 +257,7 @@ void WebMediaPlayerMSCompositorTraits::Destruct(
void WebMediaPlayerMSCompositor::InitializeSubmitter() {
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
- submitter_->Initialize(this, /* is_media_stream = */ true);
+ submitter_->Initialize(this, /*is_media_stream=*/true);
}
void WebMediaPlayerMSCompositor::SetIsSurfaceVisible(
@@ -629,15 +624,6 @@ void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() {
WrapRefCounted(this))));
}
-void WebMediaPlayerMSCompositor::StopUsingProvider() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- PostCrossThreadTask(
- *video_frame_compositor_task_runner_, FROM_HERE,
- CrossThreadBindOnce(
- &WebMediaPlayerMSCompositor::StopUsingProviderInternal,
- WrapRefCounted(this)));
-}
-
bool WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks(
const std::vector<base::TimeDelta>& timestamps,
std::vector<base::TimeTicks>* wall_clock_times) {
@@ -874,13 +860,6 @@ void WebMediaPlayerMSCompositor::StopRenderingInternal() {
video_frame_provider_client_->StopRendering();
}
-void WebMediaPlayerMSCompositor::StopUsingProviderInternal() {
- DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
- if (video_frame_provider_client_)
- video_frame_provider_client_->StopUsingProvider();
- video_frame_provider_client_ = nullptr;
-}
-
void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
scoped_refptr<media::VideoFrame> current_frame_ref;
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
index 603f9c50cc8383dcba68b522231dfa493c0d179e..a8565180d57a80f596bbd28690c7c6ceefe6474b 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
@@ -119,10 +119,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
void StopRendering();
void ReplaceCurrentFrameWithACopy();
- // Tell |video_frame_provider_client_| to stop using this instance in
- // preparation for dtor.
- void StopUsingProvider();
-
// Sets a hook to be notified when a new frame is presented, to fulfill a
// prending video.requestAnimationFrame() request.
// Can be called from any thread.
@@ -208,7 +204,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
void StartRenderingInternal();
void StopRenderingInternal();
- void StopUsingProviderInternal();
void ReplaceCurrentFrameWithACopyInternal();
void SetAlgorithmEnabledForTesting(bool algorithm_enabled);

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 a3e5764a1920c8a6bf1ce21e02d0ac743b027a40..ce8b70cc792b2ae45624840e0f71270f85f00836 100644
--- a/content/app/content_main_runner_impl.cc
+++ b/content/app/content_main_runner_impl.cc
@@ -93,6 +93,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"
@@ -1083,6 +1084,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 ContentMainDelegate::InvokedInBrowserProcess invoked_in_browser{
.is_running_test = !main_params.ui_task.is_null()};
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 1830df7354d7dfa007cca97ddc346db0165098b7..c4ddc89cd9d0894814d64856179539f0d757a388 100644
--- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
+++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -389,7 +389,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(
@@ -627,7 +629,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,946 @@
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 8731b179fecfa212c3c802fb5e57189e97d782e6..220c0355a45362bdb018e335a1cb0e8e4a4abd96 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::MessageToMethodInfo_,
Interface::MessageToMethodName_);
} else {
diff --git a/mojo/public/cpp/bindings/interface_endpoint_client.h b/mojo/public/cpp/bindings/interface_endpoint_client.h
index cd79a5edb3f939623b874db36542ee651113c164..d746b1473d95a367f47e309049e85241bdba095b 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 0be4148158a0d779770cba9c6cc2204d957e753d..5a23491320fbcf28db67511309dde641c4439837 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, method_info_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 5ac4091604df3054f5f678f97c39c1fb133346d3..67cc5b07c18375ea7f58cda223766b9fe8c5e4e0 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 a25df8c6127e0c0f2fd398bb5e7dafe4be23aa94..c450ef2d9d0e66ba0ce66458c29d1ce616c5740e 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, method_info_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 227727f170964cc761a358323272bb1e3123951d..e0c926b04d10364815f270a4f0e1dc542fa8370a 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,
MessageToMethodInfoCallback method_info_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,
method_info_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 1b33aa78a952dcfeb39c466ecd47f840896c41c4..cf1f3f377e5e6662d86720fbd7121ed69e6c9b42 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,
MessageToMethodInfoCallback method_info_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::MessageToMethodInfo_,
- Interface::MessageToMethodName_);
+ Interface::PassesAssociatedKinds_,
+ SyncMethodTraits<Interface>::GetOrdinals(), &stub_, Interface::Version_,
+ Interface::MessageToMethodInfo_, 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 c4ddc89cd9d0894814d64856179539f0d757a388..1a2799f11b987b17994aa4c85bd77af571cf73e9 100644
--- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
+++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -441,13 +441,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,
MessageToMethodInfoCallback method_info_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_),
@@ -857,7 +857,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 66bfb042c8c67644c2b94dd2dc7759aaf91088c6..1a9e45fd825c8ae867f36e03698176a15600ca0d 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, method_info_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 3e4a5f87422f40143c631123153b7b1138cdfb8f..b3921a464b96aa33d2a7d98309c9745008b4aae1 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::MessageToMethodInfo_,
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 173c6c801853fc9b19ca123d8cd1f580894d3e8e..383072ead95d459f62c2adf2a937edfc81681597 100644
--- a/mojo/public/cpp/bindings/tests/bindings_perftest.cc
+++ b/mojo/public/cpp/bindings/tests/bindings_perftest.cc
@@ -212,12 +212,12 @@ TEST_F(MojoBindingsPerftest, MultiplexRouterPingPong) {
InterfaceEndpointClient client0(
router0->CreateLocalEndpointHandle(kPrimaryInterfaceId), &paddle0,
- nullptr, false, base::ThreadTaskRunnerHandle::Get(), 0u,
- kTestInterfaceName, MessageToMethodInfo, MessageToMethodName);
+ nullptr, {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ MessageToMethodInfo, MessageToMethodName);
InterfaceEndpointClient client1(
router1->CreateLocalEndpointHandle(kPrimaryInterfaceId), &paddle1,
- nullptr, false, base::ThreadTaskRunnerHandle::Get(), 0u,
- kTestInterfaceName, MessageToMethodInfo, MessageToMethodName);
+ nullptr, {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ MessageToMethodInfo, MessageToMethodName);
paddle0.set_sender(&client0);
paddle1.set_sender(&client1);
@@ -264,8 +264,8 @@ TEST_F(MojoBindingsPerftest, MultiplexRouterDispatchCost) {
CounterReceiver receiver;
InterfaceEndpointClient client(
router->CreateLocalEndpointHandle(kPrimaryInterfaceId), &receiver,
- nullptr, false, base::ThreadTaskRunnerHandle::Get(), 0u,
- kTestInterfaceName, MessageToMethodInfo, MessageToMethodName);
+ nullptr, {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ MessageToMethodInfo, 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 c04c3867a9629c28ec45c5d376c5688760c463c9..e340a28a0ea1536187386e3764fe019119e53f12 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,
MessageToMethodInfo, MessageToMethodName);
ResponseGenerator generator;
InterfaceEndpointClient client1(
std::move(endpoint1_), &generator, std::make_unique<PassThroughFilter>(),
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
MessageToMethodInfo, 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,
MessageToMethodInfo, MessageToMethodName);
ResponseGenerator generator;
InterfaceEndpointClient client1(
std::move(endpoint1_), &generator, std::make_unique<PassThroughFilter>(),
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
MessageToMethodInfo, MessageToMethodName);
Message request;
@@ -173,14 +173,14 @@ 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,
MessageToMethodInfo, 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, MessageToMethodInfo,
+ base::WrapUnique(new PassThroughFilter()), {},
+ base::ThreadTaskRunnerHandle::Get(), 0u,
+ kTestInterfaceName, MessageToMethodInfo,
MessageToMethodName);
Message 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,
MessageToMethodInfo, MessageToMethodName);
bool error_handler_called0 = false;
client0.set_connection_error_handler(base::BindOnce(
@@ -256,9 +256,9 @@ 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, MessageToMethodInfo,
+ base::WrapUnique(new PassThroughFilter()), {},
+ base::ThreadTaskRunnerHandle::Get(), 0u,
+ kTestInterfaceName, MessageToMethodInfo,
MessageToMethodName);
bool error_handler_called1 = false;
client1.set_connection_error_handler(base::BindOnce(
@@ -306,12 +306,12 @@ TEST_F(MultiplexRouterTest, LateResponse) {
{
InterfaceEndpointClient client0(
std::move(endpoint0_), nullptr, std::make_unique<PassThroughFilter>(),
- false, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
+ {}, base::ThreadTaskRunnerHandle::Get(), 0u, kTestInterfaceName,
MessageToMethodInfo, MessageToMethodName);
InterfaceEndpointClient client1(std::move(endpoint1_), &generator,
- std::make_unique<PassThroughFilter>(),
- false, base::ThreadTaskRunnerHandle::Get(),
- 0u, kTestInterfaceName, MessageToMethodInfo,
+ std::make_unique<PassThroughFilter>(), {},
+ base::ThreadTaskRunnerHandle::Get(), 0u,
+ kTestInterfaceName, MessageToMethodInfo,
MessageToMethodName);
Message 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 c53d4eac2ee4c0c0134f25b3f7a1c2275c545f55..6e02107bd623def01aed76b85d58e932f92ef03f 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
@@ -32,7 +32,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 eff9376b78b20dfa39efc60f7548a965a38700f1..b952ada97535aa2da8a29bc6275f738dfb0c70db 100644
--- a/mojo/public/tools/mojom/mojom/generate/module.py
+++ b/mojo/public/tools/mojom/mojom/generate/module.py
@@ -1729,11 +1729,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

@@ -67,12 +67,12 @@ index ad34b6230f57ad906bae515aa73ea2aaf1bfeede..b5cff1fee2d14c02f2d67cf012b7ba24
const WebSecurityOrigin& script_origin) {
return false;
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc
index 20d674166c78e316751bfa3ec7aed74656eea9b4..d289cfca8d8a9b093d8d30427e594c46b2f56c79 100644
index 156d8d8184c4a69a9d8b8603027d7b398e2790bf..98fa13b35b0328eb436f2d146a8cda87438e6519 100644
--- a/third_party/blink/renderer/core/workers/worker_thread.cc
+++ b/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -744,6 +744,12 @@ void WorkerThread::PrepareForShutdownOnWorkerThread() {
nested_runner_->QuitNow();
@@ -746,6 +746,12 @@ void WorkerThread::PrepareForShutdownOnWorkerThread() {
}
pause_handle_.reset();
+ {
+ v8::HandleScope handle_scope(GetIsolate());

View File

@@ -1,6 +1,8 @@
{
"src/electron/patches/chromium": "src",
"src/electron/patches/angle": "src/third_party/angle",
"src/electron/patches/boringssl": "src/third_party/boringssl/src",
"src/electron/patches/devtools_frontend": "src/third_party/devtools-frontend/src",
@@ -21,5 +23,7 @@
"src/electron/patches/Mantle": "src/third_party/squirrel.mac/vendor/Mantle",
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC"
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
"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 3e6939c5e1a5fbb1c52069a03c0317fa3e05aaf2..3c9498b8889bf0352aa0b640a82556daf36c62cc 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -2136,6 +2136,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 =
@@ -2152,6 +2155,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,
@@ -3096,8 +3101,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 486fda38036226d0e92c0bb69a029b196f44b6c9..f9e9b8b0a506970f79bf1799d50f45abf9ecb684 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -253,6 +253,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

@@ -49,3 +49,6 @@ fix_override_createjob_in_node_platform.patch
buffer_fix_atob_input_validation.patch
v8_api_advance_api_deprecation.patch
enable_-wunqualified-std-cast-call.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 c68cf1eb0f9cdd2a8fe314237c1e790fe3690272..b5f33411c68d56ae2a582b0defaa55bf10a830e0 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);

View File

@@ -9,3 +9,7 @@ fix_disable_implies_dcheck_for_node_stream_array_buffers.patch
revert_fix_cppgc_removed_deleted_cstors_in_cppheapcreateparams.patch
revert_runtime_dhceck_terminating_exception_in_microtasks.patch
chore_disable_is_execution_terminating_dcheck.patch
cherry-pick-27fa951ae4a3.patch
cherry-pick-c79148742421.patch
cherry-pick-0f481c9ddf2a.patch
cherry-pick-28b9c1c04e78.patch

View File

@@ -9,7 +9,7 @@ necessary for native modules to load.
Also, some fixes relating to mksnapshot on ARM.
diff --git a/BUILD.gn b/BUILD.gn
index 83082271b8b76179b41e943190303e31fa639a95..0a23171a391606bb3408dcf8a488d075a148443a 100644
index 7b41a7500e55a5dbbef512dd8bfcc7dbc65e982c..8039c91f8800b516a64b84a1d7a9701932decae2 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -663,7 +663,7 @@ config("internal_config") {
@@ -21,7 +21,7 @@ index 83082271b8b76179b41e943190303e31fa639a95..0a23171a391606bb3408dcf8a488d075
defines += [ "BUILDING_V8_SHARED" ]
}
@@ -6166,7 +6166,7 @@ if (current_toolchain == v8_generator_toolchain) {
@@ -6169,7 +6169,7 @@ if (current_toolchain == v8_generator_toolchain) {
"src/interpreter/bytecodes.h",
]

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 3a882f8c7938820b787d0a59c1208ea9517dde15..87ac836d59a1901a5513cb14dc0c0d2e25922be3 100644
--- a/src/compiler/backend/x64/code-generator-x64.cc
+++ b/src/compiler/backend/x64/code-generator-x64.cc
@@ -5215,7 +5215,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 31a06d5a138ac610b10f5eea6b338d44eac3373a..ca8394e5055889c81b57892c4efed53cc6bfa3bc 100644
--- a/src/wasm/graph-builder-interface.cc
+++ b/src/wasm/graph-builder-interface.cc
@@ -2060,7 +2060,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,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 8d52d0792bcfc108141fc5d2016b5942ce93df07..7bf3bcc7796d60319c604e03d61a6c8a2b762581 100644
--- a/src/ast/scopes.cc
+++ b/src/ast/scopes.cc
@@ -885,9 +885,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());
@@ -912,12 +911,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());
@@ -929,16 +927,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) {
@@ -2576,6 +2568,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 32e16b80b261fbeffc1d4710f8a2119044cbf28e..3d062685643ad7bc31d9a45b92fa9dd924f83425 100644
--- a/src/ast/scopes.h
+++ b/src/ast/scopes.h
@@ -110,12 +110,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.
@@ -123,45 +117,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 };
@@ -907,8 +887,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.
@@ -942,7 +922,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 {
@@ -1367,7 +1346,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).
@@ -1380,14 +1361,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,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 40515772ef03946510aee70bb5f2d5cca4c74818..aa72539443e9ad05f56bfe10002632e621a09b43 100644
--- a/include/v8-version.h
+++ b/include/v8-version.h
@@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 10
#define V8_MINOR_VERSION 6
#define V8_BUILD_NUMBER 194
-#define V8_PATCH_LEVEL 26
+#define V8_PATCH_LEVEL 27
// 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 925c866c9ac5c9377f8ee75a312ce2710eb88f1c..2764c00a5ce1563a30f5927f722b36b91901036c 100644
--- a/tools/v8heapconst.py
+++ b/tools/v8heapconst.py
@@ -544,30 +544,30 @@ KNOWN_OBJECTS = {
("old_space", 0x04625): "StringSplitCache",
("old_space", 0x04a2d): "RegExpMultipleCache",
("old_space", 0x04e35): "BuiltinsConstantsTable",
- ("old_space", 0x05285): "AsyncFunctionAwaitRejectSharedFun",
- ("old_space", 0x052a9): "AsyncFunctionAwaitResolveSharedFun",
- ("old_space", 0x052cd): "AsyncGeneratorAwaitRejectSharedFun",
- ("old_space", 0x052f1): "AsyncGeneratorAwaitResolveSharedFun",
- ("old_space", 0x05315): "AsyncGeneratorYieldResolveSharedFun",
- ("old_space", 0x05339): "AsyncGeneratorReturnResolveSharedFun",
- ("old_space", 0x0535d): "AsyncGeneratorReturnClosedRejectSharedFun",
- ("old_space", 0x05381): "AsyncGeneratorReturnClosedResolveSharedFun",
- ("old_space", 0x053a5): "AsyncIteratorValueUnwrapSharedFun",
- ("old_space", 0x053c9): "PromiseAllResolveElementSharedFun",
- ("old_space", 0x053ed): "PromiseAllSettledResolveElementSharedFun",
- ("old_space", 0x05411): "PromiseAllSettledRejectElementSharedFun",
- ("old_space", 0x05435): "PromiseAnyRejectElementSharedFun",
- ("old_space", 0x05459): "PromiseCapabilityDefaultRejectSharedFun",
- ("old_space", 0x0547d): "PromiseCapabilityDefaultResolveSharedFun",
- ("old_space", 0x054a1): "PromiseCatchFinallySharedFun",
- ("old_space", 0x054c5): "PromiseGetCapabilitiesExecutorSharedFun",
- ("old_space", 0x054e9): "PromiseThenFinallySharedFun",
- ("old_space", 0x0550d): "PromiseThrowerFinallySharedFun",
- ("old_space", 0x05531): "PromiseValueThunkFinallySharedFun",
- ("old_space", 0x05555): "ProxyRevokeSharedFun",
- ("old_space", 0x05579): "ShadowRealmImportValueFulfilledSFI",
- ("old_space", 0x0559d): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
- ("old_space", 0x055c1): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
+ ("old_space", 0x05289): "AsyncFunctionAwaitRejectSharedFun",
+ ("old_space", 0x052ad): "AsyncFunctionAwaitResolveSharedFun",
+ ("old_space", 0x052d1): "AsyncGeneratorAwaitRejectSharedFun",
+ ("old_space", 0x052f5): "AsyncGeneratorAwaitResolveSharedFun",
+ ("old_space", 0x05319): "AsyncGeneratorYieldResolveSharedFun",
+ ("old_space", 0x0533d): "AsyncGeneratorReturnResolveSharedFun",
+ ("old_space", 0x05361): "AsyncGeneratorReturnClosedRejectSharedFun",
+ ("old_space", 0x05385): "AsyncGeneratorReturnClosedResolveSharedFun",
+ ("old_space", 0x053a9): "AsyncIteratorValueUnwrapSharedFun",
+ ("old_space", 0x053cd): "PromiseAllResolveElementSharedFun",
+ ("old_space", 0x053f1): "PromiseAllSettledResolveElementSharedFun",
+ ("old_space", 0x05415): "PromiseAllSettledRejectElementSharedFun",
+ ("old_space", 0x05439): "PromiseAnyRejectElementSharedFun",
+ ("old_space", 0x0545d): "PromiseCapabilityDefaultRejectSharedFun",
+ ("old_space", 0x05481): "PromiseCapabilityDefaultResolveSharedFun",
+ ("old_space", 0x054a5): "PromiseCatchFinallySharedFun",
+ ("old_space", 0x054c9): "PromiseGetCapabilitiesExecutorSharedFun",
+ ("old_space", 0x054ed): "PromiseThenFinallySharedFun",
+ ("old_space", 0x05511): "PromiseThrowerFinallySharedFun",
+ ("old_space", 0x05535): "PromiseValueThunkFinallySharedFun",
+ ("old_space", 0x05559): "ProxyRevokeSharedFun",
+ ("old_space", 0x0557d): "ShadowRealmImportValueFulfilledSFI",
+ ("old_space", 0x055a1): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
+ ("old_space", 0x055c5): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
}
# Lower 32 bits of first page addresses for various heap spaces.

View File

@@ -12,7 +12,7 @@ This patch can be safely removed if, when it is removed, `node.lib` does not
contain any standard C++ library exports (e.g. `std::ostringstream`).
diff --git a/BUILD.gn b/BUILD.gn
index b0c6d08bf50a3443e2589f09b6f1f5b7734c000c..7728123805054064d5acecacf6cbf8d1fe4a56c1 100644
index 8b98f871341fed2186d0bc2de42912e76bbc04e1..6d3b542d781ad1a71c4b966aa05d5f51b1b3d45e 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -663,6 +663,10 @@ config("internal_config") {

View File

@@ -6,10 +6,10 @@ Subject: expose_mksnapshot.patch
Needed in order to target mksnapshot for mksnapshot zip.
diff --git a/BUILD.gn b/BUILD.gn
index 0a23171a391606bb3408dcf8a488d075a148443a..b0c6d08bf50a3443e2589f09b6f1f5b7734c000c 100644
index 8039c91f8800b516a64b84a1d7a9701932decae2..8b98f871341fed2186d0bc2de42912e76bbc04e1 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -6178,7 +6178,6 @@ if (current_toolchain == v8_generator_toolchain) {
@@ -6181,7 +6181,6 @@ if (current_toolchain == v8_generator_toolchain) {
if (current_toolchain == v8_snapshot_toolchain) {
v8_executable("mksnapshot") {

View File

@@ -1 +1,4 @@
add_thread_local_to_x_error_trap_cc.patch
cherry-pick-136ef25acbf7.patch
cherry-pick-e0efbd45ea74.patch
cherry-pick-218b56e51638.patch

View File

@@ -0,0 +1,59 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jakob Ivarsson <jakobi@webrtc.org>
Date: Fri, 23 Sep 2022 22:03:09 +0200
Subject: Fix crash when appending empty array to AudioMultiVector.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bug: webrtc:14442,chromium:1367993
Change-Id: I9453e300a6d3d78571d08cc65770787e13d43885
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/276620
Commit-Queue: Jakob Ivarsson <jakobi@webrtc.org>
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38208}
diff --git a/modules/audio_coding/neteq/audio_multi_vector.cc b/modules/audio_coding/neteq/audio_multi_vector.cc
index 220d5a17d7d1d4e1ed7577d4a044af29f358f88b..14ae94649b52278656eb73d91b1e73cb5307a92d 100644
--- a/modules/audio_coding/neteq/audio_multi_vector.cc
+++ b/modules/audio_coding/neteq/audio_multi_vector.cc
@@ -69,6 +69,9 @@ void AudioMultiVector::CopyTo(AudioMultiVector* copy_to) const {
void AudioMultiVector::PushBackInterleaved(
rtc::ArrayView<const int16_t> append_this) {
RTC_DCHECK_EQ(append_this.size() % num_channels_, 0);
+ if (append_this.empty()) {
+ return;
+ }
if (num_channels_ == 1) {
// Special case to avoid extra allocation and data shuffling.
channels_[0]->PushBack(append_this.data(), append_this.size());
@@ -78,11 +81,8 @@ void AudioMultiVector::PushBackInterleaved(
int16_t* temp_array = new int16_t[length_per_channel]; // Temporary storage.
for (size_t channel = 0; channel < num_channels_; ++channel) {
// Copy elements to `temp_array`.
- // Set `source_ptr` to first element of this channel.
- const int16_t* source_ptr = &append_this[channel];
for (size_t i = 0; i < length_per_channel; ++i) {
- temp_array[i] = *source_ptr;
- source_ptr += num_channels_; // Jump to next element of this channel.
+ temp_array[i] = append_this[channel + i * num_channels_];
}
channels_[channel]->PushBack(temp_array, length_per_channel);
}
diff --git a/modules/audio_coding/neteq/audio_multi_vector_unittest.cc b/modules/audio_coding/neteq/audio_multi_vector_unittest.cc
index 329377a18edc2259dfc24dbaf82218ff69180916..386c3d48a398521730afad6642df355e29550d79 100644
--- a/modules/audio_coding/neteq/audio_multi_vector_unittest.cc
+++ b/modules/audio_coding/neteq/audio_multi_vector_unittest.cc
@@ -309,6 +309,12 @@ TEST_P(AudioMultiVectorTest, CopyChannel) {
}
}
+TEST_P(AudioMultiVectorTest, PushBackEmptyArray) {
+ AudioMultiVector vec(num_channels_);
+ vec.PushBackInterleaved({});
+ EXPECT_TRUE(vec.Empty());
+}
+
INSTANTIATE_TEST_SUITE_P(TestNumChannels,
AudioMultiVectorTest,
::testing::Values(static_cast<size_t>(1),

View File

@@ -0,0 +1,59 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Cooper <alcooper@chromium.org>
Date: Wed, 8 Feb 2023 14:16:01 -0800
Subject: Fix Destruction inside WGC Callback
If we are notified of the destruction of the window before a
CaptureFrame call can fail, then we may end up attempting to destroy the
underlying WGC object inside it's own event handler. This can be
problematic, as the class itself may want to run other code. Instead,
we just unsubscribe and signal that any future CaptureFrame calls should
reject.
This also removes setting "is_capture_started_=false" in the item closed
handler, as all that served to do is cause the WgcCapturerWin code to
attempt to restart the capturer, and somewhat muddies up our metrics.
(cherry picked from commit 318cf28945d80a0ac6f09382e507c95e649cc4c1)
Bug: chromium:1413005
No-Try: True
Change-Id: Ibccb7a2e7ce531ba80b4b331b9bc2cda0ff75f4e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/292762
Auto-Submit: Alexander Cooper <alcooper@chromium.org>
Reviewed-by: Mark Foltz <mfoltz@chromium.org>
Commit-Queue: Mark Foltz <mfoltz@chromium.org>
Commit-Queue: Alexander Cooper <alcooper@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#39275}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/293246
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5481@{#5}
Cr-Branched-From: 2e1a9a4ae0234d4b1ea7a6fd4188afa1fb20379d-refs/heads/main@{#38901}
diff --git a/modules/desktop_capture/win/wgc_capture_session.cc b/modules/desktop_capture/win/wgc_capture_session.cc
index 0ff2db27c7c82a59265eed16c672fe5afe57f501..68400415cec228c7a3c50be497e6aa6b437b5ace 100644
--- a/modules/desktop_capture/win/wgc_capture_session.cc
+++ b/modules/desktop_capture/win/wgc_capture_session.cc
@@ -388,17 +388,14 @@ HRESULT WgcCaptureSession::OnItemClosed(WGC::IGraphicsCaptureItem* sender,
RTC_LOG(LS_INFO) << "Capture target has been closed.";
item_closed_ = true;
- is_capture_started_ = false;
RemoveEventHandlers();
- mapped_texture_ = nullptr;
- session_ = nullptr;
- frame_pool_ = nullptr;
- direct3d_device_ = nullptr;
- item_ = nullptr;
- d3d11_device_ = nullptr;
-
+ // Do not attempt to free resources in the OnItemClosed handler, as this
+ // causes a race where we try to delete the item that is calling us. Removing
+ // the event handlers and setting `item_closed_` above is sufficient to ensure
+ // that the resources are no longer used, and the next time the capturer tries
+ // to get a frame, we will report a permanent failure and be destroyed.
return S_OK;
}

View File

@@ -0,0 +1,60 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Bostr=C3=B6m?= <hbos@webrtc.org>
Date: Fri, 20 Jan 2023 10:48:31 +0100
Subject: =?UTF-8?q?=C2=A0[Stats]=20Handle=20the=20case=20of=20missing=20ce?=
=?UTF-8?q?rtificates.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Certificates being missing is a sign of a bug (e.g. webrtc:14844, to be
fixed separately) which is why we have a DCHECK. But this DCHECK does
not protect against accessing the invalid iterator if it is a release
build. This CL makes that safe.
# Mobile bots not running properly
NOTRY=True
(cherry picked from commit 124d7c3fe5bdc79a355c9df02d07f25331631a68)
Bug: chromium:1408392
Change-Id: I97a82786028e41c58ef8ef15002c3f959bbec7f1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291109
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Original-Commit-Position: refs/heads/main@{#39159}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291380
Cr-Commit-Position: refs/branch-heads/5481@{#2}
Cr-Branched-From: 2e1a9a4ae0234d4b1ea7a6fd4188afa1fb20379d-refs/heads/main@{#38901}
diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc
index be6c23e8430cb2b19839c5b2cb7eebaa576a92cb..0c0bb1c5540c1196dc45cd4e2e2c91941a9a16ac 100644
--- a/pc/rtc_stats_collector.cc
+++ b/pc/rtc_stats_collector.cc
@@ -2106,16 +2106,17 @@ void RTCStatsCollector::ProduceTransportStats_n(
// exist.
const auto& certificate_stats_it =
transport_cert_stats.find(transport_name);
+ std::string local_certificate_id, remote_certificate_id;
RTC_DCHECK(certificate_stats_it != transport_cert_stats.cend());
- std::string local_certificate_id;
- if (certificate_stats_it->second.local) {
- local_certificate_id = RTCCertificateIDFromFingerprint(
- certificate_stats_it->second.local->fingerprint);
- }
- std::string remote_certificate_id;
- if (certificate_stats_it->second.remote) {
- remote_certificate_id = RTCCertificateIDFromFingerprint(
- certificate_stats_it->second.remote->fingerprint);
+ if (certificate_stats_it != transport_cert_stats.cend()) {
+ if (certificate_stats_it->second.local) {
+ local_certificate_id = RTCCertificateIDFromFingerprint(
+ certificate_stats_it->second.local->fingerprint);
+ }
+ if (certificate_stats_it->second.remote) {
+ remote_certificate_id = RTCCertificateIDFromFingerprint(
+ certificate_stats_it->second.remote->fingerprint);
+ }
}
// There is one transport stats for each channel.

View File

@@ -4,11 +4,11 @@ import argparse
import os
import sys
from lib.config import LINUX_BINARIES, PLATFORM
from lib.util import execute, get_out_dir
from lib.config import PLATFORM
from lib.util import execute, get_linux_binaries, get_out_dir
def add_debug_link_into_binaries(directory, target_cpu, debug_dir):
for binary in LINUX_BINARIES:
for binary in get_linux_binaries():
binary_path = os.path.join(directory, binary)
if os.path.isfile(binary_path):
add_debug_link_into_binary(binary_path, target_cpu, debug_dir)

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