Compare commits

..

64 Commits

Author SHA1 Message Date
Samuel Attard
543f7c3fdb chore: cherry-pick 3fbd1dca6a4d from libvpx (#40025)
* chore: cherry-pick 3fbd1dca6a4d from libvpx

* build: update patches config

* chore: update patches

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-09-28 03:34:22 -07:00
Athul Iddya
e51dee4e81 fix: use generic capturer to list both screens and windows when possible (#39711)
Screensharing with PipeWire via XDG Desktop Portal requires explicit
user permission via permission dialogs. Chromium has separate tabs for
screens and windows and thus its portal implementation requests
permissions separately for each. However, the screencast portal has no
such limitation and supports both screens and windows in a single
request.

WebRTC now supports this type of capture in a new method called
called `CreateGenericCapturer`. The `desktopCapturer` implementation has
been modified to use it. Additionally, Chromium has been patched to use
same generic capturer to ensure that the source IDs remain valid for
`getUserMedia`.
2023-09-25 14:17:45 -04:00
trop[bot]
384f44d042 ci: fix linux builds of forks (#39942)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-09-21 10:04:03 -04:00
Samuel Attard
edb117a239 build: use afs on aks instead of circle cache (#39913)
* build: use afs on aks instead of circle cache (#39881)

* build: use afs on aks instead of circle cache

* build: do not use aks logic on linux hosts checking out for macOS

* build: fix gn-check could-be-aks

* build: sigh

* build: no ls mnt

* build: keep build alive while debugging

* build: make debuggable

---------

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

* build: also update node build

---------

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-09-19 15:13:32 +02:00
trop[bot]
3f864b28a0 build: fixup autoninja (#39901)
chore: set GOMA_DIR for autoninja

(cherry picked from commit 94f24bde4d)
(cherry picked from commit 90c1f6e1cb8d22d94dd01791dc4b9c3e0a7e86fc)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-09-18 20:36:38 -04:00
trop[bot]
97bf8c8325 build: run on circle hosts for forks (#39864)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2023-09-14 14:42:51 -04:00
Samuel Attard
4a9b36703b build: use aks backed runners for linux builds (#39837)
* build: use aks backed runners for linux builds (#39403)

* build: test aks runner

* build: stress test

* build: use super-large nodes for publish jobs

* build: try using aks for everything...

* build: shared host not great

* build: clean up

* build: apparently tests dont run in kube infra?

* build: do not change test size

* ci: fixup known hosts for linux publish (#39437)

* ci: fixup known hosts for linux publish

* build: use 2023 known hosts

* build: use rebuilt docker image

* Revert "build: use rebuilt docker image"

This reverts commit f9506a9cc0.

---------

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

---------

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-09-12 16:52:24 -07:00
Samuel Attard
0508e25549 chore: cherry-pick b2eab7500a18 from chromium (#39826)
* chore: cherry-pick b2eab7500a18 from chromium

* chore: update patches

---------

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-09-12 11:44:16 -07:00
trop[bot]
0641412e98 fix: ensure app load is limited to real asar files when appropriate (#39810)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-09-11 14:12:21 -07:00
Pedro Pontes
c574fedc84 chore: cherry-pick 3 changes from Release-3-M116 (#39757)
* chore: [24-x-y] cherry-pick 3 changes from Release-3-M116

* 74a2eb9c8cb2 from chromium
* 038530c94a06 from v8
* 26175b0903d8 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-09-11 09:37:27 +02:00
trop[bot]
3cb87f49ad build: fix depot_tools patch application (#39752)
build: fix depot_tools patch application (cherry picked from commit 34b79c15c2)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-09-06 20:10:17 -04:00
Pedro Pontes
94586037cd chore: cherry-pick 1 changes from Release-2-M116 (#39688)
* chore: [24-x-y] cherry-pick 1 changes from Release-2-M116

* 35c06406a658 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-08-30 10:09:28 -04:00
trop[bot]
d6cea5fc0c fix: assert module in the renderer process (#39621)
* fix: assert module in the renderer process

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

* chore: update patches after trop

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-08-28 13:13:02 -04:00
Pedro Pontes
0284dfb2a9 chore: cherry-pick 3 changes from Release-1-M116 (#39647)
* chore: [24-x-y] cherry-pick 2 changes from Release-1-M116

* 1939f7b78eda from chromium
* e4669a74888d from angle

* chore: [24-x-y] cherry-pick missing changes from Release-1-M116

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-08-28 15:19:05 +09:00
trop[bot]
2c07dab03a fix: ensure windows respect fullscreenability with different resizability values (#39643)
* fix: ensure child windows respect fullscreenability/resizability when parent is fullscreen

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

* test: add an extra resize test

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-08-28 11:05:25 +09:00
trop[bot]
b3912c65ff ci: explicitly use python3 to start goma (#39655)
ci: explicitly use python3 to start goma (#39650)

* ci: explicitly use python3 to start goma

* ci: explicitly use python3 for goma

(cherry picked from commit 83760bd5c6)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-08-25 14:59:06 +02:00
trop[bot]
0641a85498 fix: dangling raw_ptr in ElectronBrowserMainParts dtor (#39591)
* fix: dangling raw_ptr in ElectronBrowserMainParts dtor

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

* fixup! fix: dangling raw_ptr in ElectronBrowserMainParts dtor

Browser::WhenReady() holds a reference to JsEnv isolate so must come after

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-08-21 13:49:54 +02:00
trop[bot]
cec0e9c871 fix: use tiled edges to calculate frame inset sizes in Linux (#39567)
Adapt to the window frame size calculation changes in CL 3970920 by
setting the inset sizes to 0 for tiled edges.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Athul Iddya <athul@iddya.com>
2023-08-21 17:03:30 +09:00
trop[bot]
63883adbe0 fix: explorer restart does not recreated thumbnail toolbar buttons (#39585)
fix: explorer restart does not recreated thumbnail toolbar buttons.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: harada <harada@thinkridge.com>
2023-08-21 17:03:08 +09:00
Pedro Pontes
f22a5b80eb chore: cherry-pick 5 changes from Release-0-M116 (#39558)
* chore: [24-x-y] cherry-pick 3 changes from Release-0-M116

* 8ff63d378f2c from v8
* 5486190be556 from angle
* d671b099a57d from v8

* chore: update patches

* chore: cherry-pick missing changes

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-08-21 09:39:53 +09:00
trop[bot]
6e36eba667 docs: note macOS bounds Tray offset (#39553)
* docs: note macOS bounds Tray offset

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

* Update docs/api/browser-window.md

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

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-08-17 11:29:31 +02:00
trop[bot]
693c9d7484 docs: add missing webview render-process-gone event (#39544)
docs: add mising webview 'render-process-gone' event

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-08-17 10:33:04 +02:00
trop[bot]
f08d5f1e02 fix: crash when calling BrowserWindow.moveTop() on modal children (#39526)
fix: crash when calling moveTop() on modal children

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-08-16 14:12:08 -04:00
trop[bot]
ec4c609e4f refactor: clean up Node.js cli arg parsing (#39509)
* refactor: clean up Node.js arg parsing

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

* chore: feedback from review

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-08-16 09:45:30 +02:00
trop[bot]
89d57368d8 fix: macOS tray button selection with VoiceOver (#39447)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-08-14 10:35:51 +02:00
Shelley Vohr
e0b1723dd1 fix: update chrome.i18n for Manifest v3 (#39442)
* fix: update `chrome.i18n` for Manifest v3

* chore: remove i18n JSON spec (#39391)
2023-08-11 14:46:31 +02:00
trop[bot]
7698575651 feat: allow more Node.js cli flags in main process (#39372)
* feat: allow more Node.js cli flags in main process

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

* docs: update cli switch documentation

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-08-10 09:41:56 +02:00
Shelley Vohr
baf3081e1d docs: correct powerSaveBlocker.stop(id) return type (#39443) 2023-08-09 21:41:39 +02:00
trop[bot]
d49364fa53 fix: avoid package.json check on built-in modules (#39423)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-08-09 14:45:59 +02:00
trop[bot]
04af0337bc fix: removeBrowserView draggable region removal (#39407)
fix: removeBrowserView draggable region removal

Closes https://github.com/electron/electron/issues/39377.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-08-08 12:10:10 +02:00
trop[bot]
08dd28204b ci: fix hang when validating AppVeyor artifacts (#39399)
ci: fix hang when validating AppVeyor artifacts (#39362)

(cherry picked from commit 1eb6e45a36)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-08-07 18:12:58 -04:00
trop[bot]
09bb5eef2a test: add some environment variables for controlling tests (#39364)
chore: add some environment variables for controlling tests

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2023-08-04 08:39:13 +09:00
trop[bot]
faae88d0fe docs: clean up removed systemPreferences methods (#39350)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-08-03 15:52:13 +02:00
Keeley Hammond
3484a5606e chore: cherry-pick 4 changes from Release-0-M115 (#39267)
* chore: [24-x-y] cherry-pick 4 changes from Release-0-M115

* 90c9a89aa794 from chromium
* 933b9fad3a53 from chromium
* b03973561862 from chromium
* c60a1ab717c7 from chromium

* chore: update patches, remove redundent patches

* 4373801: Use rtc::scoped_refptr for webrtc::DataChannel objects

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

* 4564316: Remove SiteInstanceDeleting from content/public API.

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

---------

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-08-02 15:09:53 +02:00
Athul Iddya
0cc1893c8c chore: cherry-pick 2 changes from webrtc (#39273) 2023-08-01 16:57:51 +02:00
trop[bot]
88604f2fb8 fix: reparenting after BrowserWindow.destroy() (#39307)
fix: reparenting after BrowserWindow.destroy()

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-08-01 15:25:42 +02:00
trop[bot]
144a70b1d1 fix: skip artifact validation for doc-only PRs (#39303)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-07-31 13:47:48 -04:00
trop[bot]
e2d17db85b feat: add senderIsMainFrame to messages sent via ipcRenderer.sendTo() (#39207)
* feat: add `senderIsMainFrame` to messages sent via `ipcRenderer.sendTo()` (#38868)

* feat: add isMainFrame to events emitted via ipcRenderer.sendTo()

* chore: rename isMainFrame to senderIsMainFrame

Co-authored-by: Milan Burda <milan.burda@gmail.com>

* once -> emittedOnce

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-07-27 22:59:32 +02:00
trop[bot]
ae9593d0e4 fix: do not resolve electron entrypoints on disk (#39250)
* fix: do not resolve electron entrypoints on disk

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

* chore: update .patches file after trop

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-07-27 12:55:28 -07:00
trop[bot]
e239cf9ac5 fix: traffic lights not working when child windows are restored via parent window (#39243)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-07-26 14:12:20 +02:00
Milan Burda
ccca1cf5ab fix: asar integration for require('node:child_process') (#39236)
fix: asar integration for require('node:child_process') (#38742)
2023-07-26 10:13:51 +02:00
trop[bot]
348243e7e5 fix: resizable: false should disable fullscreen button at start (#39230)
fix: resizable should disable fullscreen button at start

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-07-25 20:34:02 +02:00
trop[bot]
bcffbb1c7e ci: fail appveyor build if artifacts are missing (#39217)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-07-25 12:04:43 -04:00
trop[bot]
a5fc0c139d docs: document idleDetector permissions (#39212)
doc: document idleDetector permissions

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-07-25 11:36:56 +02:00
trop[bot]
491358e18e build: fix Appveyor test workflow checkout (#39169)
* build: fix Appveyor test workflow checkout

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

* fix: +refs/pull/num/merge -> +refs/pull/num/head

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

* chore: add to appveyor-woa as well

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-07-20 13:22:37 +02:00
trop[bot]
115e4976da build: fixup Codespaces build-tools setup (#39143)
* build: fixup Codespaces build-tools setup

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

* oops evm.testing1.json -> evm.testing.json

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-07-19 10:56:32 +02:00
Shelley Vohr
be3a3d554d fix: file selection when disallowed on macOS (#39097) 2023-07-18 10:42:20 +02:00
Shelley Vohr
549221d0f1 fix: navigator.connection not working as intended (#39100)
fix: navigator.connection not working as intended
2023-07-13 19:25:25 -04:00
trop[bot]
34e961a6dd fix: BrowserWindow.moveAbove() not working for child windows (#39072)
fix: BrowserWindow.moveAbove() not working for child windows

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-07-13 15:33:56 +09:00
trop[bot]
92ac9267f0 fix: use StartUpdating method for PipeWire capturer (#39050)
* fix: use StartUpdating method for PipeWire capturer

Fixed a crash related to PipeWire capturer by adapting to Chromium's
interface changes. Chromium expects a call to
`NativeDesktopMediaList::StartUpdating` with an implementation of
`DesktopMediaListObserver` for delegated capturers like PipeWire. This
interface allows listening to user permission events and listing
sources only after the user has made a choice on the permission dialog.

The interface has been implemented by an inner class to allow listening
to screen and window capture permissions concurrently using two
instances of the class. A patch that was resetting the capturer on the
first refresh has been changed to exclude PipeWire. PipeWire capturer
object will follow the lifecycle of `NativeDesktopMediaList`, as is the
case in Chromium.

Fixes #37463

Co-authored-by: Athul Iddya <athul@iddya.com>

* fix: wait for thumbnails from PipeWire when necessary

The PipeWire stream starts after the dialog is dismissed. If the sources
are listed immediately afterwards, the thumbnail may not have been
generated by that time. Explicitly wait for both thumbnail generation
and a selection on the source dialog before listing sources.

Co-authored-by: Athul Iddya <athul@iddya.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Athul Iddya <athul@iddya.com>
2023-07-11 15:17:52 +02:00
trop[bot]
6a20f61102 fix: webview crash when removing in close event (#39009)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-07-10 13:42:24 +02:00
trop[bot]
2136769836 build: disable unneeded depot_tools update on Windows CI (#39018)
build: disable unneeded depot_tools update

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-07-10 10:43:57 +02:00
trop[bot]
c998d2fb41 fix: Notification 'Show' button visible when no actions exist (#39012)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-07-07 09:58:35 +02:00
Pedro Pontes
fa768aa749 chore: cherry-pick 4 changes from Release-3-M114 (#38947)
* chore: [24-x-y] cherry-pick 4 changes from Release-3-M114

* 85beff6fd302 from chromium
* 60b93798c991 from chromium
* a1efa5343880 from v8
* d20849d07107 from webrtc

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-29 12:44:26 -07:00
trop[bot]
f7e22ed743 fix: child window may have opener removed (#38932)
* fix: child window may have opener removed

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

* Update chromium-spec.ts

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2023-06-27 11:34:12 -04:00
Charles Kerr
437bf7d1fd refactor: api web contents ownership (#38894)
refactor: api web contents ownership (#38695)

* refactor: aggregate api::WebContents::exclusive_access_manager_ directly

* refactor: make WebContents::devtools_file_system_indexer_ scoped_refptr const

* refactor: make WebContents::file_task_runner_ scoped_refptr const

* refactor: make WebContents::print_task_runner_ scoped_refptr const
2023-06-22 13:01:27 -05:00
trop[bot]
d0b2a4e48f refactor: prefer base::Contains() over find() + end() (#38890)
refactor: prefer base::Contains() over find() + end() (#38443)

* refactor: use base::Contains() in KeyWeakMap::Has()

* refactor: use base::Contains() in WebRequest::RequestFilter::MatchesType()

* refactor: use base::Contains() in BaseWindow::AddBrowserView()

* refactor: use base::Contains() in DeepFreeze()

* refactor: use base::Contains() in Clipboard::Read()

* Revert "refactor: use base::Contains() in BaseWindow::AddBrowserView()"
This reverts commit 60152359d3978451ebdd7c8eed602c2fb8a9cafa.

* refactor: use base::Contains() in BaseWindow::AddBrowserView()

* refactor: use base::Contains() in IsDevToolsFileSystemAdded()

* refactor: use base::Contains() in MessagePort::DisentanglePorts()

* refactor: use base::Contains() in PowerSaveBlocker::IsStarted()

* refactor: use base::Contains() in SpellCheckClient::OnSpellCheckDone()

* refactor: use base::Contains() in ShowTaskDialogWstr()

* refactor: use base::Contains() in PrintViewManagerElectron::ScriptedPrint()

* refactor: use base::Contains() in PrintViewManagerElectron::DidGetPrintedPagesCount()

* refactor: use base::Contains() in NativeWindow::AddDraggableRegionProvider()

* refactor: use base::Contains() in ElectronBindings::ActivateUVLoop()

* refactor: use base::Contains() in NativeWindowViews::IsVisibleOnAllWorkspaces()

* refactor: use base::Contains() in HidChooserController::OnDeviceAdded()

* refactor: use base::Contains() in ElectronSandboxedRendererClient::WillReleaseScriptContext()

* refactor: use base::Contains() in ElectronRendererClient::WillDestroyWorkerContextOnWorkerThread()

* refactor: use base::Contains() in GlobalShortcut::OnKeyPressed()

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-22 13:06:35 +02:00
trop[bot]
192295697e fix: crash calling BrowserWindow.removeBrowserView() with destroyed webContents (#38884)
fix: crash calling removeBrowserView() with destroyed webContents

https://github.com/electron/electron/issues/37642

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-22 11:22:30 +02:00
trop[bot]
e47bdb67f8 fix: set minimize visibility true with enable (#38881)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: mlaurencin <mlaurencin@electronjs.org>
2023-06-22 10:31:06 +02:00
trop[bot]
25dee92c57 refactor: remove unused InspectableWebContentsView::GetWebView() (#38819)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-16 12:43:47 -05:00
trop[bot]
053031e96c refactor: constexpr lookup tables (#38807)
* refactor: constexpr lookup tables (#38771)

* refactor: use a constexpr lookup table in GetPathConstant()

* refactor: use a constexpr lookup table in SystemPreferences::GetColor()

* refactor: use a constexpr lookup table in SimpleURLLoaderWrapper::Create()

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

* fix: use MakeFixedFlatMap() instead of MakeFixedFlatMapSorted()

The latter compiles faster but does not exist in 24-x-y

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-16 10:03:09 +02:00
trop[bot]
1e64527ec3 feat: support node: prefixed requires in sandboxed renderer preloads (#38727)
feat: support node: prefixed requires in sandboxed renderer preloads

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-06-15 12:00:01 +02:00
trop[bot]
1645aece38 fix: preferCSSPageSize error type (#38792)
fix: preferCSSPageSize error type

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-14 11:03:13 -07:00
Pedro Pontes
1f66b20392 chore: cherry-pick 3 changes from Release-2-M114 (#38787)
* chore: [24-x-y] cherry-pick 1 changes from Release-2-M114

* 2e76270cf65e from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-14 11:02:59 -07:00
146 changed files with 5422 additions and 728 deletions

View File

@@ -65,6 +65,9 @@ jobs:
curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | DESTDIR=$CIRCLECI_BINARY bash
node build.js
name: Pack config.yml
- run:
name: Set params
command: node .circleci/config/params.js
- continuation/continue:
configuration_path: .circleci/config-staging/built.yml
parameters: /tmp/pipeline-parameters.json

View File

@@ -35,6 +35,16 @@ parameters:
default: all
enum: ["all", "osx-x64", "osx-arm64", "mas-x64", "mas-arm64"]
medium-linux-executor:
type: enum
default: electronjs/aks-linux-medium
enum: ["electronjs/aks-linux-medium", "medium"]
large-linux-executor:
type: enum
default: electronjs/aks-linux-large
enum: ["electronjs/aks-linux-large", "2xlarge"]
# Executors
executors:
linux-docker:
@@ -42,7 +52,9 @@ executors:
size:
description: "Docker executor size"
type: enum
enum: ["medium", "xlarge", "2xlarge"]
# aks-linux-large === 32 core
# 2xlarge should not be used directly, use the pipeline param instead
enum: ["medium", "electronjs/aks-linux-medium", "xlarge", "electronjs/aks-linux-large", "2xlarge"]
docker:
- image: ghcr.io/electron/build:e6bebd08a51a0d78ec23e5b3fd7e7c0846412328
resource_class: << parameters.size >>
@@ -247,19 +259,19 @@ step-depot-tools-get: &step-depot-tools-get
cd depot_tools
cat > gclient.diff \<< 'EOF'
diff --git a/gclient.py b/gclient.py
index 3a9c5c6..f222043 100755
index c305c248..e6e0fbdc 100755
--- a/gclient.py
+++ b/gclient.py
@@ -712,7 +712,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
if dep_type == 'cipd':
cipd_root = self.GetCipdRoot()
- for package in dep_value.get('packages', []):
+ packages = dep_value.get('packages', [])
+ for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
deps_to_add.append(
CipdDependency(
parent=self,
@@ -735,7 +735,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
if dep_type == 'cipd':
cipd_root = self.GetCipdRoot()
- for package in dep_value.get('packages', []):
+ packages = dep_value.get('packages', [])
+ for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
deps_to_add.append(
CipdDependency(parent=self,
name=name,
EOF
git apply --3way gclient.diff
fi
@@ -347,7 +359,7 @@ step-setup-goma-for-build: &step-setup-goma-for-build
exit 1
fi
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
echo 'export GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
echo 'export GOMA_FALLBACK_ON_AUTH_FAILURE=true' >> $BASH_ENV
cd ..
touch "${TMPDIR:=/tmp}"/.goma-ready
@@ -730,8 +742,8 @@ step-show-goma-stats: &step-show-goma-stats
command: |
set +e
set +o pipefail
$LOCAL_GOMA_DIR/goma_ctl.py stat
$LOCAL_GOMA_DIR/diagnose_goma_log.py
$GOMA_DIR/goma_ctl.py stat
$GOMA_DIR/diagnose_goma_log.py
true
when: always
background: true
@@ -883,14 +895,26 @@ step-touch-sync-done: &step-touch-sync-done
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
restore_cache:
keys:
- v16-src-cache-{{ checksum "src/electron/.depshash" }}
- v17-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:
- v16-src-cache-marker-{{ checksum "src/electron/.depshash" }}
- v17-src-cache-marker-{{ checksum "src/electron/.depshash" }}
name: Restoring src cache marker
step-maybe-restore-src-cache-aks: &step-maybe-restore-src-cache-aks
restore_cache_aks:
step-name: Restoring src cache
cache_key: v17-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')
cache_path: /var/portal
step-maybe-restore-src-cache-marker-aks: &step-maybe-restore-src-cache-marker-aks
restore_cache_aks:
step-name: Restoring src cache marker
cache_key: v17-src-cache-marker-$(shasum src/electron/.depshash | cut -f1 -d' ')
cache_path: "."
# Restore exact or closest git cache based on the hash of DEPS and .circle-sync-done
# If the src cache was restored above then this will match an empty cache
# If the src cache was not restored above then this will match a close git cache
@@ -903,6 +927,12 @@ 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-maybe-restore-git-cache-aks: &step-maybe-restore-git-cache-aks
restore_cache_aks:
step-name: Conditionally restoring git cache (aks)
cache_key: v1-git-cache-$(shasum src/electron/.circle-sync-done | cut -f1 -d' ')-$(shasum src/electron/DEPS | cut -f1 -d' ') v1-git-cache-$(shasum src/electron/.circle-sync-done | cut -f1 -d' ')
cache_path: git-cache
step-set-git-cache-path: &step-set-git-cache-path
run:
name: Set GIT_CACHE_PATH to make gclient to use the cache
@@ -920,6 +950,12 @@ 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-git-cache-aks: &step-save-git-cache-aks
save_cache_aks:
step-name: Persisting git cache (AKS)
cache_key: v1-git-cache-$(shasum src/electron/.circle-sync-done | cut -f1 -d' ')-$(shasum src/electron/DEPS | cut -f1 -d' ')
cache_path: git-cache
step-run-electron-only-hooks: &step-run-electron-only-hooks
run:
name: Run Electron Only Hooks
@@ -957,7 +993,7 @@ step-save-src-cache: &step-save-src-cache
save_cache:
paths:
- /var/portal
key: v16-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
key: v17-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
name: Persisting src cache
step-make-src-cache-marker: &step-make-src-cache-marker
run:
@@ -967,7 +1003,17 @@ step-save-src-cache-marker: &step-save-src-cache-marker
save_cache:
paths:
- .src-cache-marker
key: v16-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
key: v17-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
step-save-src-cache-aks: &step-save-src-cache-aks
save_cache_aks:
step-name: Persisting src cache (aks)
cache_key: v17-src-cache-$(shasum /var/portal/src/electron/.depshash | cut -f1 -d' ')
cache_path: /var/portal
step-save-src-cache-marker-aks: &step-save-src-cache-marker-aks
save_cache_aks:
step-name: Persisting src cache marker (aks)
cache_key: v17-src-cache-marker-$(shasum /var/portal/src/electron/.depshash | cut -f1 -d' ')
cache_path: .src-cache-marker
step-maybe-early-exit-no-doc-change: &step-maybe-early-exit-no-doc-change
run:
@@ -993,15 +1039,6 @@ step-ts-compile: &step-ts-compile
done
# List of all steps.
steps-electron-gn-check: &steps-electron-gn-check
steps:
- *step-setup-goma-for-build
- checkout-from-cache
- *step-setup-env-for-build
- *step-wait-for-goma
- *step-gn-gen-default
- *step-gn-check
steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-change
steps:
# Checkout - Copied from steps-checkout
@@ -1013,11 +1050,92 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
# Command Aliases
commands:
aks-specific-step:
parameters:
circle:
type: steps
aks:
type: steps
could-be-aks:
type: boolean
description: Only set this to true on linux hosts
steps:
- when:
condition:
or:
- equal: [<< parameters.could-be-aks >>, false]
- equal: [<< pipeline.parameters.large-linux-executor >>, 2xlarge]
steps: << parameters.circle >>
- when:
condition:
and:
- equal: [<< parameters.could-be-aks >>, true]
- equal: [<< pipeline.parameters.large-linux-executor >>, electronjs/aks-linux-large]
steps: << parameters.aks >>
save_cache_aks:
parameters:
step-name:
type: string
cache_key:
type: string
cache_path:
type: string
steps:
- run:
name: << parameters.step-name >>
command: |
cache_key="<< parameters.cache_key >>"
final_cache_path=/mnt/cross-instance-cache/${cache_key}.tar
echo "Using cache key: $cache_key"
echo "Checking path: $final_cache_path"
if [ ! -f "$final_cache_path" ]; then
echo "Cache key not founding, storing tarball"
tmp_container=/mnt/cross-instance-cache/tmp/$CIRCLE_WORKFLOW_JOB_ID
tmp_cache_path=$tmp_container/${cache_key}.tar
mkdir -p $tmp_container
if [ -f "<< parameters.cache_path >>" ]; then
tar -cf $tmp_cache_path -C $(dirname << parameters.cache_path >>) ./$(basename << parameters.cache_path >>)
else
tar -cf $tmp_cache_path -C << parameters.cache_path >>/ ./
fi
mv -vn $tmp_cache_path $final_cache_path
rm -rf $tmp_container
else
echo "Cache key already exists, skipping.."
fi
restore_cache_aks:
parameters:
step-name:
type: string
cache_key:
type: string
cache_path:
type: string
steps:
- run:
name: << parameters.step-name >>
command: |
df -h
for cache_key in << parameters.cache_key >>; do
cache_path=/mnt/cross-instance-cache/${cache_key}.tar
echo "Using cache key: $cache_key"
echo "Checking path: $cache_path"
if [ ! -f "$cache_path" ]; then
echo "Cache key not found, nothing to restore..."
else
echo "Cache key found, restoring to path..."
mkdir -p << parameters.cache_path >>/
tar -xf /mnt/cross-instance-cache/${cache_key}.tar -C << parameters.cache_path >>/
exit 0
fi
done
maybe-restore-portaled-src-cache:
parameters:
halt-if-successful:
type: boolean
default: false
could-be-aks:
type: boolean
steps:
- run:
name: Prepare for cross-OS sync restore
@@ -1027,23 +1145,44 @@ commands:
- when:
condition: << parameters.halt-if-successful >>
steps:
- *step-maybe-restore-src-cache-marker
- aks-specific-step:
circle:
- *step-maybe-restore-src-cache-marker
aks:
- *step-maybe-restore-src-cache-marker-aks
could-be-aks: << parameters.could-be-aks >>
- run:
name: Halt the job early if the src cache exists
command: |
if [ -f ".src-cache-marker" ]; then
circleci-agent step halt
fi
- *step-maybe-restore-src-cache
- aks-specific-step:
circle:
- *step-maybe-restore-src-cache
aks:
- *step-maybe-restore-src-cache-aks
could-be-aks: << parameters.could-be-aks >>
- run:
name: Fix the src cache restore point on macOS
name: Fix the src cache restore point
command: |
if [ -d "/var/portal/src" ]; then
echo Relocating Cache
rm -rf src
mv /var/portal/src ./
fi
run-gn-check:
parameters:
could-be-aks:
type: boolean
steps:
- *step-setup-goma-for-build
- checkout-from-cache:
could-be-aks: << parameters.could-be-aks >>
- *step-setup-env-for-build
- *step-wait-for-goma
- *step-gn-gen-default
- *step-gn-check
build_and_save_artifacts:
parameters:
artifact-key:
@@ -1158,12 +1297,16 @@ commands:
mv_if_exist cross-arch-snapshots src
checkout-from-cache:
parameters:
could-be-aks:
type: boolean
steps:
- *step-checkout-electron
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-generate-deps-hash
- maybe-restore-portaled-src-cache
- maybe-restore-portaled-src-cache:
could-be-aks: << parameters.could-be-aks >>
- run:
name: Ensure src checkout worked
command: |
@@ -1301,6 +1444,8 @@ commands:
after-persist:
type: steps
default: []
could-be-aks:
type: boolean
steps:
- when:
condition: << parameters.attach >>
@@ -1318,7 +1463,8 @@ commands:
- when:
condition: << parameters.checkout-and-assume-cache >>
steps:
- checkout-from-cache
- checkout-from-cache:
could-be-aks: << parameters.could-be-aks >>
- when:
condition: << parameters.checkout >>
steps:
@@ -1334,8 +1480,15 @@ commands:
steps:
- maybe-restore-portaled-src-cache:
halt-if-successful: << parameters.checkout-to-create-src-cache >>
- *step-maybe-restore-git-cache
could-be-aks: << parameters.could-be-aks >>
- aks-specific-step:
circle:
- *step-maybe-restore-git-cache
aks:
- *step-maybe-restore-git-cache-aks
could-be-aks: << parameters.could-be-aks >>
- *step-set-git-cache-path
- *step-fix-known-hosts-linux
# This sync call only runs if .circle-sync-done is an EMPTY file
- *step-gclient-sync
- store_artifacts:
@@ -1351,7 +1504,12 @@ commands:
- when:
condition: << parameters.save-git-cache >>
steps:
- *step-save-git-cache
- aks-specific-step:
circle:
- *step-save-git-cache
aks:
- *step-save-git-cache-aks
could-be-aks: << parameters.could-be-aks >>
# Mark sync as done _after_ saving the git cache so that it is uploaded
# only when the src cache was not present
# Their are theoretically two cases for this cache key
@@ -1401,9 +1559,19 @@ commands:
sudo mkdir -p /var/portal
sudo chown -R $(id -u):$(id -g) /var/portal
mv ./src /var/portal
- *step-save-src-cache
- aks-specific-step:
circle:
- *step-save-src-cache
aks:
- *step-save-src-cache-aks
could-be-aks: << parameters.could-be-aks >>
- *step-make-src-cache-marker
- *step-save-src-cache-marker
- aks-specific-step:
circle:
- *step-save-src-cache-marker
aks:
- *step-save-src-cache-marker-aks
could-be-aks: << parameters.could-be-aks >>
- when:
condition: << parameters.build >>
@@ -1455,6 +1623,18 @@ commands:
condition: << parameters.build >>
steps:
- *step-maybe-notify-slack-failure
- when:
condition: << parameters.could-be-aks >>
steps:
- run:
name: Wait for active debug sessions
command: |
while [ -f /var/.ssh-lock ]
do
sleep 60
done
no_output_timeout: 2h
when: always
electron-tests:
parameters:
@@ -1592,6 +1772,7 @@ commands:
- *step-minimize-workspace-size-from-checkout
- *step-fix-sync
- *step-setup-env-for-build
- *step-fix-known-hosts-linux
- *step-setup-goma-for-build
- *step-wait-for-goma
- *step-gn-gen-default
@@ -1650,7 +1831,7 @@ jobs:
linux-make-src-cache:
executor:
name: linux-docker
size: xlarge
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
@@ -1663,6 +1844,7 @@ jobs:
checkout-to-create-src-cache: true
artifact-key: 'nil'
build-type: 'nil'
could-be-aks: true
mac-checkout:
executor:
@@ -1682,6 +1864,7 @@ jobs:
restore-src-cache: false
artifact-key: 'nil'
build-type: 'nil'
could-be-aks: false
mac-make-src-cache:
executor:
@@ -1701,12 +1884,13 @@ jobs:
checkout-to-create-src-cache: true
artifact-key: 'nil'
build-type: 'nil'
could-be-aks: false
# Layer 2: Builds.
linux-x64-testing:
executor:
name: linux-docker
size: xlarge
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-global
<<: *env-testing-build
@@ -1719,11 +1903,12 @@ jobs:
checkout-and-assume-cache: true
artifact-key: 'linux-x64'
build-type: 'Linux'
could-be-aks: true
linux-x64-testing-asan:
executor:
name: linux-docker
size: 2xlarge
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-global
<<: *env-testing-build
@@ -1734,15 +1919,17 @@ jobs:
steps:
- electron-build:
persist: true
checkout: true
checkout: false
checkout-and-assume-cache: true
build-nonproprietary-ffmpeg: false
artifact-key: 'linux-x64-asan'
build-type: 'Linux'
could-be-aks: true
linux-x64-testing-no-run-as-node:
executor:
name: linux-docker
size: xlarge
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-linux-2xlarge
<<: *env-testing-build
@@ -1755,21 +1942,24 @@ jobs:
checkout: true
artifact-key: 'linux-x64-no-run-as-node'
build-type: 'Linux'
could-be-aks: true
linux-x64-testing-gn-check:
executor:
name: linux-docker
size: medium
size: << pipeline.parameters.medium-linux-executor >>
environment:
<<: *env-linux-medium
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-gn-check
steps:
- run-gn-check:
could-be-aks: true
linux-x64-publish:
executor:
name: linux-docker
size: 2xlarge
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-linux-2xlarge-release
<<: *env-release-build
@@ -1792,7 +1982,7 @@ jobs:
linux-arm-testing:
executor:
name: linux-docker
size: 2xlarge
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-global
<<: *env-arm
@@ -1808,11 +1998,12 @@ jobs:
checkout-and-assume-cache: true
artifact-key: 'linux-arm'
build-type: 'Linux ARM'
could-be-aks: true
linux-arm-publish:
executor:
name: linux-docker
size: 2xlarge
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-linux-2xlarge-release
<<: *env-arm
@@ -1837,7 +2028,7 @@ jobs:
linux-arm64-testing:
executor:
name: linux-docker
size: 2xlarge
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-global
<<: *env-arm64
@@ -1853,22 +2044,25 @@ jobs:
checkout-and-assume-cache: true
artifact-key: 'linux-arm64'
build-type: 'Linux ARM64'
could-be-aks: true
linux-arm64-testing-gn-check:
executor:
name: linux-docker
size: medium
size: << pipeline.parameters.medium-linux-executor >>
environment:
<<: *env-linux-medium
<<: *env-arm64
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-gn-check
steps:
- run-gn-check:
could-be-aks: true
linux-arm64-publish:
executor:
name: linux-docker
size: 2xlarge
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-linux-2xlarge-release
<<: *env-arm64
@@ -1923,6 +2117,7 @@ jobs:
root: .
paths:
- generated_artifacts_mas-x64
could-be-aks: false
osx-testing-x64-gn-check:
executor:
@@ -1932,7 +2127,9 @@ jobs:
<<: *env-machine-mac
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
<<: *steps-electron-gn-check
steps:
- run-gn-check:
could-be-aks: false
osx-publish-x64:
executor:
@@ -2015,6 +2212,7 @@ jobs:
root: .
paths:
- generated_artifacts_mas-arm64
could-be-aks: false
mas-publish-x64:
executor:

View File

@@ -0,0 +1,12 @@
const fs = require('fs');
const PARAMS_PATH = '/tmp/pipeline-parameters.json';
const content = JSON.parse(fs.readFileSync(PARAMS_PATH, 'utf-8'));
// Choose resource class for linux hosts
const currentBranch = process.env.CIRCLE_BRANCH || '';
content['large-linux-executor'] = /^pull\/[0-9-]+$/.test(currentBranch) ? '2xlarge' : 'electronjs/aks-linux-large';
content['medium-linux-executor'] = /^pull\/[0-9-]+$/.test(currentBranch) ? 'medium' : 'electronjs/aks-linux-medium';
fs.writeFileSync(PARAMS_PATH, JSON.stringify(content));

View File

@@ -3,5 +3,6 @@
set -e
mkdir -p ~/.ssh
echo "|1|B3r+7aO0/x90IdefihIjxIoJrrk=|OJddGDfhbuLFc1bUyy84hhIw57M= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
|1|rGlEvW55DtzNZp+pzw9gvyOyKi4=|LLWr+7qlkAlw3YGGVfLHHxB/kR0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts
echo "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=" >> ~/.ssh/known_hosts

View File

@@ -16,6 +16,8 @@ ln -s $buildtools_configs $buildtools/configs
# Write the gclient config if it does not already exist
if [ ! -f $gclient_root/.gclient ]; then
echo "Creating gclient config"
echo "solutions = [
{ \"name\" : \"src/electron\",
\"url\" : \"https://github.com/electron/electron\",
@@ -32,6 +34,8 @@ fi
# Write the default buildtools config file if it does
# not already exist
if [ ! -f $buildtools/configs/evm.testing.json ]; then
echo "Creating build-tools testing config"
write_config() {
echo "
{
@@ -53,7 +57,7 @@ if [ ! -f $buildtools/configs/evm.testing.json ]; then
\"CHROMIUM_BUILDTOOLS_PATH\": \"/workspaces/gclient/src/buildtools\",
\"GIT_CACHE_PATH\": \"/workspaces/gclient/.git-cache\"
},
\"$schema\": \"file:///home/builduser/.electron_build_tools/evm-config.schema.json\"
\"\$schema\": \"file:///home/builduser/.electron_build_tools/evm-config.schema.json\"
}
" >$buildtools/configs/evm.testing.json
}
@@ -67,10 +71,12 @@ if [ ! -f $buildtools/configs/evm.testing.json ]; then
# if it works we can use the goma cluster
export NOTGOMA_CODESPACES_TOKEN=$GITHUB_TOKEN
if e d goma_auth login; then
echo "$GITHUB_USER has GOMA access - switching to cluster mode"
write_config cluster
fi
else
# Even if the config file existed we still need to re-auth with the goma
# cluster
echo "build-tools testing config already exists"
# Re-auth with the goma cluster regardless.
NOTGOMA_CODESPACES_TOKEN=$GITHUB_TOKEN e d goma_auth login || true
fi

View File

@@ -49,6 +49,11 @@ environment:
APPVEYOR_BUILD_WORKER_IMAGE: base-woa
APPVEYOR_BUILD_WORKER_CLOUD: electronhq-woa
clone_script:
- ps: git clone -q $("--branch=" + $Env:APPVEYOR_REPO_BRANCH) $("https://github.com/" + $Env:APPVEYOR_REPO_NAME + ".git") $Env:APPVEYOR_BUILD_FOLDER
- ps: if (!$Env:APPVEYOR_PULL_REQUEST_NUMBER) {$("git checkout -qf " + $Env:APPVEYOR_REPO_COMMIT)}
- ps: if ($Env:APPVEYOR_PULL_REQUEST_NUMBER) {git fetch -q origin +refs/pull/$($Env:APPVEYOR_PULL_REQUEST_NUMBER)/head; git checkout -qf FETCH_HEAD}
clone_folder: C:\projects\src\electron
skip_branch_with_pr: true
@@ -67,8 +72,10 @@ for:
- ps: |
node script/yarn.js install --frozen-lockfile
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "false"
if ($LASTEXITCODE -eq 0) {
Write-warning "Skipping build for doc only change"
Write-warning "Skipping build for doc-only change"
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "true"
Exit-AppveyorBuild
} else {
$global:LASTEXITCODE = 0
@@ -85,6 +92,8 @@ for:
Remove-Item -Recurse -Force $pwd\build-tools
}
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
- depot_tools\bootstrap\win_tools.bat
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (Test-Path -Path "$pwd\src\electron") {
@@ -107,7 +116,7 @@ for:
- 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
$goma_login = python3 $env:LOCAL_GOMA_DIR\goma_auth.py info
if ($goma_login -eq 'Login as Fermi Planck') {
Write-warning "Goma authentication is correct";
} else {
@@ -157,7 +166,7 @@ for:
- 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 %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
@@ -178,6 +187,30 @@ for:
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
- ps: |
cd C:\projects\src
$missing_artifacts = $false
if ($env:SHOULD_SKIP_ARTIFACT_VALIDATION -eq 'true') {
Write-warning "Skipping artifact validation for doc-only PR"
} else {
$artifacts_to_validate = 'dist.zip','windows_toolchain_profile.json','shell_browser_ui_unittests.exe','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib','hunspell_dictionaries.zip'
foreach($artifact_name in $artifacts_to_validate) {
if ($artifact_name -eq 'ffmpeg.zip') {
$artifact_file = "out\ffmpeg\ffmpeg.zip"
} elseif ($artifact_name -eq 'node_headers.zip') {
$artifact_file = $artifact_name
} else {
$artifact_file = "out\Default\$artifact_name"
}
if (-not(Test-Path $artifact_file)) {
Write-warning "$artifact_name is missing and cannot be added to artifacts"
$missing_artifacts = $true
}
}
}
if ($missing_artifacts) {
throw "Build failed due to missing artifacts"
}
deploy_script:
- cd electron
@@ -203,7 +236,7 @@ for:
- 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)
- 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
@@ -236,7 +269,7 @@ for:
# 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')
$artifacts_to_download = @('dist.zip','ffmpeg.zip','node_headers.zip','electron.lib')
foreach ($job in $build_info.build.jobs) {
if ($job.name -eq "Build Arm on X64 Windows") {
$jobId = $job.jobId
@@ -248,10 +281,13 @@ for:
}
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifact_name" -OutFile $outfile
}
# Uncomment the following lines to download the pdb.zip to show real stacktraces when crashes happen during testing
# Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/pdb.zip" -OutFile pdb.zip
# 7z x -y -osrc pdb.zip
}
}
- ps: |
$out_default_zips = @('dist.zip','pdb.zip')
$out_default_zips = @('dist.zip')
foreach($zip_name in $out_default_zips) {
7z x -y -osrc\out\Default $zip_name
}

View File

@@ -47,6 +47,11 @@ environment:
- job_name: Test
job_depends_on: Build
clone_script:
- ps: git clone -q $("--branch=" + $Env:APPVEYOR_REPO_BRANCH) $("https://github.com/" + $Env:APPVEYOR_REPO_NAME + ".git") $Env:APPVEYOR_BUILD_FOLDER
- ps: if (!$Env:APPVEYOR_PULL_REQUEST_NUMBER) {$("git checkout -qf " + $Env:APPVEYOR_REPO_COMMIT)}
- ps: if ($Env:APPVEYOR_PULL_REQUEST_NUMBER) {git fetch -q origin +refs/pull/$($Env:APPVEYOR_PULL_REQUEST_NUMBER)/head; git checkout -qf FETCH_HEAD}
clone_folder: C:\projects\src\electron
skip_branch_with_pr: true
@@ -65,8 +70,10 @@ for:
- ps: |
node script/yarn.js install --frozen-lockfile
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "false"
if ($LASTEXITCODE -eq 0) {
Write-warning "Skipping build for doc only change"
Write-warning "Skipping build for doc-only change"
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "true"
Exit-AppveyorBuild
} else {
$global:LASTEXITCODE = 0
@@ -83,6 +90,8 @@ for:
Remove-Item -Recurse -Force $pwd\build-tools
}
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
- depot_tools\bootstrap\win_tools.bat
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (Test-Path -Path "$pwd\src\electron") {
@@ -105,7 +114,7 @@ for:
- 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
$goma_login = python3 $env:LOCAL_GOMA_DIR\goma_auth.py info
if ($goma_login -eq 'Login as Fermi Planck') {
Write-warning "Goma authentication is correct";
} else {
@@ -155,7 +164,7 @@ for:
- 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 %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
@@ -176,6 +185,30 @@ for:
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
- ps: |
cd C:\projects\src
$missing_artifacts = $false
if ($env:SHOULD_SKIP_ARTIFACT_VALIDATION -eq 'true') {
Write-warning "Skipping artifact validation for doc-only PR"
} else {
$artifacts_to_validate = 'dist.zip','windows_toolchain_profile.json','shell_browser_ui_unittests.exe','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib','hunspell_dictionaries.zip'
foreach($artifact_name in $artifacts_to_validate) {
if ($artifact_name -eq 'ffmpeg.zip') {
$artifact_file = "out\ffmpeg\ffmpeg.zip"
} elseif ($artifact_name -eq 'node_headers.zip') {
$artifact_file = $artifact_name
} else {
$artifact_file = "out\Default\$artifact_name"
}
if (-not(Test-Path $artifact_file)) {
Write-warning "$artifact_name is missing and cannot be added to artifacts"
$missing_artifacts = $true
}
}
}
if ($missing_artifacts) {
throw "Build failed due to missing artifacts"
}
deploy_script:
- cd electron
@@ -201,7 +234,7 @@ for:
- 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)
- 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
@@ -244,6 +277,9 @@ for:
}
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifact_name" -OutFile $outfile
}
# Uncomment the following lines to download the pdb.zip to show real stacktraces when crashes happen during testing
# Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/pdb.zip" -OutFile pdb.zip
# 7z x -y -osrc pdb.zip
}
}
- ps: |

View File

@@ -402,18 +402,7 @@ Returns:
* `event` Event
* `webContents` [WebContents](web-contents.md)
* `details` Object
* `reason` string - The reason the render process is gone. Possible values:
* `clean-exit` - Process exited with an exit code of zero
* `abnormal-exit` - Process exited with a non-zero exit code
* `killed` - Process was sent a SIGTERM or otherwise killed externally
* `crashed` - Process crashed
* `oom` - Process ran out of memory
* `launch-failed` - Process never successfully launched
* `integrity-failure` - Windows code integrity checks failed
* `exitCode` Integer - The exit code of the process, unless `reason` is
`launch-failed`, in which case `exitCode` will be a platform-specific
launch failure error code.
* `details` [RenderProcessGoneDetails](structures/render-process-gone-details.md)
Emitted when the renderer process unexpectedly disappears. This is normally
because it was crashed or killed.

View File

@@ -1110,10 +1110,14 @@ win.setBounds({ width: 100 })
console.log(win.getBounds())
```
**Note:** On macOS, the y-coordinate value cannot be smaller than the [Tray](tray.md) height. The tray height has changed over time and depends on the operating system, but is between 20-40px. Passing a value lower than the tray height will result in a window that is flush to the tray.
#### `win.getBounds()`
Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window as `Object`.
**Note:** On macOS, the y-coordinate value returned will be at minimum the [Tray](tray.md) height. For example, calling `win.setBounds({ x: 25, y: 20, width: 800, height: 600 })` with a tray height of 38 means that `win.getBounds()` will return `{ x: 25, y: 38, width: 800, height: 600 }`.
#### `win.getBackgroundColor()`
Returns `string` - Gets the background color of the window in Hex (`#RRGGBB`) format.

View File

@@ -116,14 +116,20 @@ Ignore the connections limit for `domains` list separated by `,`.
### --js-flags=`flags`
Specifies the flags passed to the Node.js engine. It has to be passed when starting
Electron if you want to enable the `flags` in the main process.
Specifies the flags passed to the [V8 engine](https://v8.dev). In order to enable the `flags` in the main process,
this switch must be passed on startup.
```sh
$ electron --js-flags="--harmony_proxies --harmony_collections" your-app
```
See the [Node.js documentation][node-cli] or run `node --help` in your terminal for a list of available flags. Additionally, run `node --v8-options` to see a list of flags that specifically refer to Node.js's V8 JavaScript engine.
Run `node --v8-options` or `electron --js-flags="--help"` in your terminal for the list of available flags. These can be used to enable early-stage JavaScript features, or log and manipulate garbage collection, among other things.
For example, to trace V8 optimization and deoptimization:
```sh
$ electron --js-flags="--trace-opt --trace-deopt" your-app
```
### --lang
@@ -241,19 +247,25 @@ Electron supports some of the [CLI flags][node-cli] supported by Node.js.
**Note:** Passing unsupported command line switches to Electron when it is not running in `ELECTRON_RUN_AS_NODE` will have no effect.
### --inspect-brk\[=\[host:]port]
### `--inspect-brk\[=\[host:]port]`
Activate inspector on host:port and break at start of user script. Default host:port is 127.0.0.1:9229.
Aliased to `--debug-brk=[host:]port`.
### --inspect-port=\[host:]port
#### `--inspect-brk-node[=[host:]port]`
Activate inspector on `host:port` and break at start of the first internal
JavaScript script executed when the inspector is available.
Default `host:port` is `127.0.0.1:9229`.
### `--inspect-port=\[host:]port`
Set the `host:port` to be used when the inspector is activated. Useful when activating the inspector by sending the SIGUSR1 signal. Default host is `127.0.0.1`.
Aliased to `--debug-port=[host:]port`.
### --inspect\[=\[host:]port]
### `--inspect\[=\[host:]port]`
Activate inspector on `host:port`. Default is `127.0.0.1:9229`.
@@ -263,12 +275,28 @@ See the [Debugging the Main Process][debugging-main-process] guide for more deta
Aliased to `--debug[=[host:]port`.
### --inspect-publish-uid=stderr,http
### `--inspect-publish-uid=stderr,http`
Specify ways of the inspector web socket url exposure.
By default inspector websocket url is available in stderr and under /json/list endpoint on http://host:port/json/list.
### `--no-deprecation`
Silence deprecation warnings.
### `--throw-deprecation`
Throw errors for deprecations.
### `--trace-deprecation`
Print stack traces for deprecations.
### `--trace-warnings`
Print stack traces for process warnings (including deprecations).
[app]: app.md
[append-switch]: command-line.md#commandlineappendswitchswitch-value
[debugging-main-process]: ../tutorial/debugging-main-process.md

View File

@@ -49,6 +49,8 @@ is used.
Stops the specified power save blocker.
Returns `boolean` - Whether the specified `powerSaveBlocker` has been stopped.
### `powerSaveBlocker.isStarted(id)`
* `id` Integer - The power save blocker id returned by `powerSaveBlocker.start`.

View File

@@ -822,18 +822,19 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
* `permission` string - The type of requested permission.
* `clipboard-read` - Request access to read from the clipboard.
* `clipboard-sanitized-write` - Request access to write to the clipboard.
* `display-capture` - Request access to capture the screen via the [Screen Capture API](https://developer.mozilla.org/en-US/docs/Web/API/Screen_Capture_API).
* `fullscreen` - Request control of the app's fullscreen state via the [Fullscreen API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API).
* `geolocation` - Request access to the user's location via the [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API)
* `idle-detection` - Request access to the user's idle state via the [IdleDetector API](https://developer.mozilla.org/en-US/docs/Web/API/IdleDetector).
* `media` - Request access to media devices such as camera, microphone and speakers.
* `display-capture` - Request access to capture the screen.
* `mediaKeySystem` - Request access to DRM protected content.
* `geolocation` - Request access to user's current location.
* `notifications` - Request notification creation and the ability to display them in the user's system tray.
* `midi` - Request MIDI access in the `webmidi` API.
* `midiSysex` - Request the use of system exclusive messages in the `webmidi` API.
* `pointerLock` - Request to directly interpret mouse movements as an input method. Click [here](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) to know more. These requests always appear to originate from the main frame.
* `fullscreen` - Request for the app to enter fullscreen mode.
* `midi` - Request MIDI access in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
* `midiSysex` - Request the use of system exclusive messages in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
* `notifications` - Request notification creation and the ability to display them in the user's system tray using the [Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/notification)
* `pointerLock` - Request to directly interpret mouse movements as an input method via the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API). These requests always appear to originate from the main frame.
* `openExternal` - Request to open links in external applications.
* `window-management` - Request access to enumerate screens using the [`getScreenDetails`](https://developer.chrome.com/en/articles/multi-screen-window-placement/) API.
* `unknown` - An unrecognized permission request
* `unknown` - An unrecognized permission request.
* `callback` Function
* `permissionGranted` boolean - Allow or deny the permission.
* `details` Object - Some properties are only available on certain permission types.
@@ -865,7 +866,22 @@ session.fromPartition('some-partition').setPermissionRequestHandler((webContents
* `handler` Function\<boolean> | null
* `webContents` ([WebContents](web-contents.md) | null) - WebContents checking the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin. All cross origin sub frames making permission checks will pass a `null` webContents to this handler, while certain other permission checks such as `notifications` checks will always pass `null`. You should use `embeddingOrigin` and `requestingOrigin` to determine what origin the owning frame and the requesting frame are on respectively.
* `permission` string - Type of permission check. Valid values are `midiSysex`, `notifications`, `geolocation`, `media`,`mediaKeySystem`,`midi`, `pointerLock`, `fullscreen`, `openExternal`, `hid`, `serial`, or `usb`.
* `permission` string - Type of permission check.
* `clipboard-read` - Request access to read from the clipboard.
* `clipboard-sanitized-write` - Request access to write to the clipboard.
* `geolocation` - Access the user's geolocation data via the [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API)
* `fullscreen` - Control of the app's fullscreen state via the [Fullscreen API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API).
* `hid` - Access the HID protocol to manipulate HID devices via the [WebHID API](https://developer.mozilla.org/en-US/docs/Web/API/WebHID_API).
* `idle-detection` - Access the user's idle state via the [IdleDetector API](https://developer.mozilla.org/en-US/docs/Web/API/IdleDetector).
* `media` - Access to media devices such as camera, microphone and speakers.
* `mediaKeySystem` - Access to DRM protected content.
* `midi` - Enable MIDI access in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
* `midiSysex` - Use system exclusive messages in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
* `notifications` - Configure and display desktop notifications to the user with the [Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/notification).
* `openExternal` - Open links in external applications.
* `pointerLock` - Directly interpret mouse movements as an input method via the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API). These requests always appear to originate from the main frame.
* `serial` - Read from and write to serial devices with the [Web Serial API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API).
* `usb` - Expose non-standard Universal Serial Bus (USB) compatible devices services to the web with the [WebUSB API](https://developer.mozilla.org/en-US/docs/Web/API/WebUSB_API).
* `requestingOrigin` string - The origin URL of the permission check
* `details` Object - Some properties are only available on certain permission types.
* `embeddingOrigin` string (optional) - The origin of the frame embedding the frame that made the permission check. Only set for cross-origin sub frames making permission checks.

View File

@@ -2,6 +2,7 @@
* `sender` [IpcRenderer](../ipc-renderer.md) - The `IpcRenderer` instance that emitted the event originally
* `senderId` Integer - The `webContents.id` that sent the message, you can call `event.sender.sendTo(event.senderId, ...)` to reply to the message, see [ipcRenderer.sendTo][ipc-renderer-sendto] for more information. This only applies to messages sent from a different renderer. Messages sent directly from the main process set `event.senderId` to `0`.
* `senderIsMainFrame` boolean (optional) - Whether the message sent via [ipcRenderer.sendTo][ipc-renderer-sendto] was sent by the main frame. This is relevant when `nodeIntegrationInSubFrames` is enabled in the originating `webContents`.
* `ports` [MessagePort][][] - A list of MessagePorts that were transferred with this message
[ipc-renderer-sendto]: ../ipc-renderer.md#ipcrenderersendtowebcontentsid-channel-args

View File

@@ -0,0 +1,13 @@
# RenderProcessGoneDetails Object
* `reason` string - The reason the render process is gone. Possible values:
* `clean-exit` - Process exited with an exit code of zero
* `abnormal-exit` - Process exited with a non-zero exit code
* `killed` - Process was sent a SIGTERM or otherwise killed externally
* `crashed` - Process crashed
* `oom` - Process ran out of memory
* `launch-failed` - Process never successfully launched
* `integrity-failure` - Windows code integrity checks failed
* `exitCode` Integer - The exit code of the process, unless `reason` is
`launch-failed`, in which case `exitCode` will be a platform-specific
launch failure error code.

View File

@@ -6,7 +6,7 @@ Process: [Main](../glossary.md#main-process)
```javascript
const { systemPreferences } = require('electron')
console.log(systemPreferences.isDarkMode())
console.log(systemPreferences.isAeroGlassEnabled())
```
## Events
@@ -47,12 +47,6 @@ Returns:
## Methods
### `systemPreferences.isDarkMode()` _macOS_ _Windows_ _Deprecated_
Returns `boolean` - Whether the system is in Dark Mode.
**Deprecated:** Should use the new [`nativeTheme.shouldUseDarkColors`](native-theme.md#nativethemeshouldusedarkcolors-readonly) API.
### `systemPreferences.isSwipeTrackingFromScrollEventsEnabled()` _macOS_
Returns `boolean` - Whether the Swipe between pages setting is on.
@@ -356,18 +350,6 @@ Returns `string` - The standard system color formatted as `#RRGGBBAA`.
Returns one of several standard system colors that automatically adapt to vibrancy and changes in accessibility settings like 'Increase contrast' and 'Reduce transparency'. See [Apple Documentation](https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/color#system-colors) for more details.
### `systemPreferences.isInvertedColorScheme()` _Windows_ _Deprecated_
Returns `boolean` - `true` if an inverted color scheme (a high contrast color scheme with light text and dark backgrounds) is active, `false` otherwise.
**Deprecated:** Should use the new [`nativeTheme.shouldUseInvertedColorScheme`](native-theme.md#nativethemeshoulduseinvertedcolorscheme-macos-windows-readonly) API.
### `systemPreferences.isHighContrastColorScheme()` _macOS_ _Windows_ _Deprecated_
Returns `boolean` - `true` if a high contrast theme is active, `false` otherwise.
**Deprecated:** Should use the new [`nativeTheme.shouldUseHighContrastColors`](native-theme.md#nativethemeshouldusehighcontrastcolors-macos-windows-readonly) API.
### `systemPreferences.getEffectiveAppearance()` _macOS_
Returns `string` - Can be `dark`, `light` or `unknown`.

View File

@@ -373,18 +373,7 @@ checking `reason === 'killed'` when you switch to that event.
Returns:
* `event` Event
* `details` Object
* `reason` string - The reason the render process is gone. Possible values:
* `clean-exit` - Process exited with an exit code of zero
* `abnormal-exit` - Process exited with a non-zero exit code
* `killed` - Process was sent a SIGTERM or otherwise killed externally
* `crashed` - Process crashed
* `oom` - Process ran out of memory
* `launch-failed` - Process never successfully launched
* `integrity-failure` - Windows code integrity checks failed
* `exitCode` Integer - The exit code of the process, unless `reason` is
`launch-failed`, in which case `exitCode` will be a platform-specific
launch failure error code.
* `details` [RenderProcessGoneDetails](structures/render-process-gone-details.md)
Emitted when the renderer process unexpectedly disappears. This is normally
because it was crashed or killed.

View File

@@ -938,9 +938,22 @@ ipcRenderer.on('ping', () => {
})
```
### Event: 'crashed'
### Event: 'crashed' _Deprecated_
Fired when the renderer process is crashed.
Fired when the renderer process crashes or is killed.
**Deprecated:** This event is superceded by the `render-process-gone` event
which contains more information about why the render process disappeared. It
isn't always because it crashed.
### Event: 'render-process-gone'
Returns:
* `details` [RenderProcessGoneDetails](structures/render-process-gone-details.md)
Fired when the renderer process unexpectedly disappears. This is normally
because it was crashed or killed.
### Event: 'plugin-crashed'

View File

@@ -51,6 +51,12 @@ but can only import a subset of Electron and Node's built-in modules:
* [`timers`](https://nodejs.org/api/timers.html)
* [`url`](https://nodejs.org/api/url.html)
[node: imports](https://nodejs.org/api/esm.html#node-imports) are supported as well:
* [`node:events`](https://nodejs.org/api/events.html)
* [`node:timers`](https://nodejs.org/api/timers.html)
* [`node:url`](https://nodejs.org/api/url.html)
In addition, the preload script also polyfills certain Node.js primitives as globals:
* [`Buffer`](https://nodejs.org/api/buffer.html)

View File

@@ -115,6 +115,7 @@ auto_filenames = {
"docs/api/structures/protocol-response.md",
"docs/api/structures/rectangle.md",
"docs/api/structures/referrer.md",
"docs/api/structures/render-process-gone-details.md",
"docs/api/structures/resolved-endpoint.md",
"docs/api/structures/resolved-host.md",
"docs/api/structures/scrubber-item.md",

View File

@@ -27,7 +27,7 @@ const cachedArchives = new Map<string, NodeJS.AsarArchive>();
const getOrCreateArchive = (archivePath: string) => {
const isCached = cachedArchives.has(archivePath);
if (isCached) {
return cachedArchives.get(archivePath);
return cachedArchives.get(archivePath)!;
}
try {
@@ -39,6 +39,8 @@ const getOrCreateArchive = (archivePath: string) => {
}
};
process._getOrCreateArchive = getOrCreateArchive;
const asarRe = /\.asar/i;
// Separate asar package's path from full path.
@@ -839,7 +841,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
const originalModuleLoad = Module._load;
Module._load = (request: string, ...args: any[]) => {
const loadResult = originalModuleLoad(request, ...args);
if (request === 'child_process') {
if (request === 'child_process' || request === 'node:child_process') {
if (!asarReady.has(loadResult)) {
asarReady.add(loadResult);
// Just to make it obvious what we are dealing with here

View File

@@ -317,7 +317,7 @@ WebContents.prototype.printToPDF = async function (options) {
if (options.preferCSSPageSize !== undefined) {
if (typeof options.preferCSSPageSize !== 'boolean') {
return Promise.reject(new Error('footerTemplate must be a String'));
return Promise.reject(new Error('preferCSSPageSize must be a Boolean'));
}
printSettings.preferCSSPageSize = options.preferCSSPageSize;
}

View File

@@ -84,11 +84,20 @@ const v8Util = process._linkedBinding('electron_common_v8_util');
let packagePath = null;
let packageJson = null;
const searchPaths: string[] = v8Util.getHiddenValue(global, 'appSearchPaths');
const searchPathsOnlyLoadASAR: boolean = v8Util.getHiddenValue(global, 'appSearchPathsOnlyLoadASAR');
// Borrow the _getOrCreateArchive asar helper
const getOrCreateArchive = process._getOrCreateArchive;
delete process._getOrCreateArchive;
if (process.resourcesPath) {
for (packagePath of searchPaths) {
try {
packagePath = path.join(process.resourcesPath, packagePath);
if (searchPathsOnlyLoadASAR) {
if (!getOrCreateArchive?.(packagePath)) {
continue;
}
}
packageJson = Module._load(path.join(packagePath, 'package.json'));
break;
} catch {

View File

@@ -17,13 +17,13 @@ const isWebView = mainFrame.getWebPreference('isWebView');
// ElectronApiServiceImpl will look for the "ipcNative" hidden object when
// invoking the 'onMessage' callback.
v8Util.setHiddenValue(global, 'ipcNative', {
onMessage (internal: boolean, channel: string, ports: MessagePort[], args: any[], senderId: number) {
onMessage (internal: boolean, channel: string, ports: MessagePort[], args: any[], senderId: number, senderIsMainFrame: boolean) {
if (internal && senderId !== 0) {
console.error(`Message ${channel} sent by unexpected WebContents (${senderId})`);
return;
}
const sender = internal ? ipcRendererInternal : ipcRenderer;
sender.emit(channel, { sender, senderId, ports }, ...args);
sender.emit(channel, { sender, senderId, ...(senderId ? { senderIsMainFrame } : {}), ports }, ...args);
}
});

View File

@@ -33,12 +33,15 @@ const loadedModules = new Map<string, any>([
['electron', electron],
['electron/common', electron],
['electron/renderer', electron],
['events', events]
['events', events],
['node:events', events]
]);
const loadableModules = new Map<string, Function>([
['timers', () => require('timers')],
['url', () => require('url')]
['node:timers', () => require('timers')],
['url', () => require('url')],
['node:url', () => require('url')]
]);
// Pass different process object to the preload script.

View File

@@ -1 +1,3 @@
fix_rename_webswapcgllayer_to_webswapcgllayerchromium.patch
cherry-pick-5486190be556.patch
cherry-pick-e4669a74888d.patch

View File

@@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Fri, 21 Jul 2023 13:45:52 -0400
Subject: Fix read size validation for RGBX formats.
GL_RGBX8_ANGLE is the only format where the upload format is 3-channel
RGB, whilethe download format is 4-channel RGBX. As such, the internal
format corresponding to format+type expects 3-byte input/output. The
format is fixed here for readPixels to output 4 bytes per pixel.
Bug: chromium:1458046
Change-Id: Iec737ed64bade003cfab50dc5f595eb4875e81e4
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4706957
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
(cherry picked from commit 430a4f559cbc2bcd5d026e8b36ee46ddd80e9651)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4765136
Commit-Queue: Daniel Yip <danielyip@google.com>
Auto-Submit: Daniel Yip <danielyip@google.com>
(cherry picked from commit 4a372ad49ceddea6c13f79adb212a777ec770a66)
diff --git a/src/libANGLE/formatutils.cpp b/src/libANGLE/formatutils.cpp
index 0b8d4eeb537690da830a0d7162e86ea1379c42b4..9e3007fa12189aa8a1bebb33e869cf5f597e04a9 100644
--- a/src/libANGLE/formatutils.cpp
+++ b/src/libANGLE/formatutils.cpp
@@ -1715,7 +1715,15 @@ const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type)
GLuint InternalFormat::computePixelBytes(GLenum formatType) const
{
const auto &typeInfo = GetTypeInfo(formatType);
- GLuint components = typeInfo.specialInterpretation ? 1u : componentCount;
+ GLuint components = componentCount;
+ if (sizedInternalFormat == GL_RGBX8_ANGLE)
+ {
+ components = 4;
+ }
+ else if (typeInfo.specialInterpretation)
+ {
+ components = 1;
+ }
return components * typeInfo.bytes;
}

View File

@@ -0,0 +1,395 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Charlie Lao <cclao@google.com>
Date: Tue, 8 Aug 2023 10:14:47 -0700
Subject: M116: Vulkan: Fix data race with DynamicDescriptorPool
Right now DynamicDescriptorPool::destroyCachedDescriptorSet can be
called from garbage clean up thread, while simultaneously accessed from
context main thread, and data race will happen and cause bugs. This can
only happen when the buffer is not being suballocated. In this case,
suballocation owns the bufferBlock and bufferBlock gets destroyed when
suballocation is destroyed from garbage collection thread. If buffer is
suballocated, the shared group owns pool which owns bufferBlocks and
they gets destroyed from shared group with the share group lock. This CL
avoids this race problem by release the shared cacheKey when the buffer
is released, while we still had the shared group lock.
Bug: chromium:1469542
Change-Id: Ie6235fcfb77dee2a12b2ebde44042c3845fc0aca
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4790523
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/BufferVk.cpp b/src/libANGLE/renderer/vulkan/BufferVk.cpp
index 0898e7d67f47b0d87476a70b9bede290d22ca87a..2957ddf5dede7ffcf7a918ba2f6c8235feb7357b 100644
--- a/src/libANGLE/renderer/vulkan/BufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/BufferVk.cpp
@@ -285,7 +285,7 @@ void BufferVk::release(ContextVk *contextVk)
RendererVk *renderer = contextVk->getRenderer();
if (mBuffer.valid())
{
- mBuffer.releaseBufferAndDescriptorSetCache(contextVk);
+ mBuffer.releaseBufferAndDescriptorSetCache(renderer);
}
if (mStagingBuffer.valid())
{
@@ -628,7 +628,7 @@ angle::Result BufferVk::ghostMappedBuffer(ContextVk *contextVk,
memcpy(dstMapPtr, srcMapPtr, static_cast<size_t>(mState.getSize()));
}
- src.releaseBufferAndDescriptorSetCache(contextVk);
+ src.releaseBufferAndDescriptorSetCache(contextVk->getRenderer());
// Return the already mapped pointer with the offset adjustment to avoid the call to unmap().
*mapPtr = dstMapPtr + offset;
@@ -966,7 +966,7 @@ angle::Result BufferVk::acquireAndUpdate(ContextVk *contextVk,
if (src.valid())
{
- src.releaseBufferAndDescriptorSetCache(contextVk);
+ src.releaseBufferAndDescriptorSetCache(contextVk->getRenderer());
}
return angle::Result::Continue;
@@ -1073,7 +1073,7 @@ angle::Result BufferVk::acquireBufferHelper(ContextVk *contextVk, size_t sizeInB
if (mBuffer.valid())
{
- mBuffer.releaseBufferAndDescriptorSetCache(contextVk);
+ mBuffer.releaseBufferAndDescriptorSetCache(renderer);
}
// Allocate the buffer directly
diff --git a/src/libANGLE/renderer/vulkan/Suballocation.h b/src/libANGLE/renderer/vulkan/Suballocation.h
index d25481bdbbb12d9377eb8ae540a8603a16e453b1..276f6b4c854df2a2a4a353f2893c4bc2df9e8502 100644
--- a/src/libANGLE/renderer/vulkan/Suballocation.h
+++ b/src/libANGLE/renderer/vulkan/Suballocation.h
@@ -86,6 +86,13 @@ class BufferBlock final : angle::NonCopyable
{
mDescriptorSetCacheManager.addKey(sharedCacheKey);
}
+ void releaseAllCachedDescriptorSetCacheKeys(RendererVk *renderer)
+ {
+ if (!mDescriptorSetCacheManager.empty())
+ {
+ mDescriptorSetCacheManager.releaseKeys(renderer);
+ }
+ }
private:
mutable std::mutex mVirtualBlockMutex;
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index 1375e39971faff88db94c09b50b8c0db761eaba2..903def6e88e8d0f3a16f1f891429b9e088191f32 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -1617,7 +1617,7 @@ void TextureVk::releaseAndDeleteImageAndViews(ContextVk *contextVk)
mBufferViews.release(contextVk);
mRedefinedLevels.reset();
- mDescriptorSetCacheManager.releaseKeys(contextVk);
+ mDescriptorSetCacheManager.releaseKeys(contextVk->getRenderer());
}
void TextureVk::initImageUsageFlags(ContextVk *contextVk, angle::FormatID actualFormatID)
@@ -2845,7 +2845,7 @@ angle::Result TextureVk::syncState(const gl::Context *context,
mBufferViews.release(contextVk);
mBufferViews.init(renderer, offset, size);
- mDescriptorSetCacheManager.releaseKeys(contextVk);
+ mDescriptorSetCacheManager.releaseKeys(renderer);
return angle::Result::Continue;
}
@@ -3285,7 +3285,7 @@ void TextureVk::releaseImageViews(ContextVk *contextVk)
{
RendererVk *renderer = contextVk->getRenderer();
- mDescriptorSetCacheManager.releaseKeys(contextVk);
+ mDescriptorSetCacheManager.releaseKeys(renderer);
if (mImage == nullptr)
{
diff --git a/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp b/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
index abab85dcfb5da21630b9e8987543a09e7fb9e6c4..965e6ee4e1f8349c057e7fdbca7ebaa4593823ac 100644
--- a/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
@@ -2588,11 +2588,19 @@ void ReleaseCachedObject(ContextVk *contextVk, const FramebufferDesc &desc)
{
contextVk->getShareGroup()->getFramebufferCache().erase(contextVk, desc);
}
+void ReleaseCachedObject(RendererVk *renderer, const FramebufferDesc &desc)
+{
+ UNREACHABLE();
+}
void ReleaseCachedObject(ContextVk *contextVk, const DescriptorSetDescAndPool &descAndPool)
+{
+ UNREACHABLE();
+}
+void ReleaseCachedObject(RendererVk *renderer, const DescriptorSetDescAndPool &descAndPool)
{
ASSERT(descAndPool.mPool != nullptr);
- descAndPool.mPool->releaseCachedDescriptorSet(contextVk, descAndPool.mDesc);
+ descAndPool.mPool->releaseCachedDescriptorSet(renderer, descAndPool.mDesc);
}
void DestroyCachedObject(RendererVk *renderer, const FramebufferDesc &desc)
@@ -6255,6 +6263,22 @@ void SharedCacheKeyManager<SharedCacheKeyT>::releaseKeys(ContextVk *contextVk)
mSharedCacheKeys.clear();
}
+template <class SharedCacheKeyT>
+void SharedCacheKeyManager<SharedCacheKeyT>::releaseKeys(RendererVk *renderer)
+{
+ for (SharedCacheKeyT &sharedCacheKey : mSharedCacheKeys)
+ {
+ if (*sharedCacheKey.get() != nullptr)
+ {
+ // Immediate destroy the cached object and the key itself when first releaseKeys call is
+ // made
+ ReleaseCachedObject(renderer, *(*sharedCacheKey.get()));
+ *sharedCacheKey.get() = nullptr;
+ }
+ }
+ mSharedCacheKeys.clear();
+}
+
template <class SharedCacheKeyT>
void SharedCacheKeyManager<SharedCacheKeyT>::destroyKeys(RendererVk *renderer)
{
diff --git a/src/libANGLE/renderer/vulkan/vk_cache_utils.h b/src/libANGLE/renderer/vulkan/vk_cache_utils.h
index 2d9784c1e0db828a5aacefa19168795da85fc5a5..c7213a1193fee21595737047e2379231039b66e9 100644
--- a/src/libANGLE/renderer/vulkan/vk_cache_utils.h
+++ b/src/libANGLE/renderer/vulkan/vk_cache_utils.h
@@ -1937,6 +1937,7 @@ class SharedCacheKeyManager
void addKey(const SharedCacheKeyT &key);
// Iterate over the descriptor array and release the descriptor and cache.
void releaseKeys(ContextVk *contextVk);
+ void releaseKeys(RendererVk *rendererVk);
// Iterate over the descriptor array and destroy the descriptor and cache.
void destroyKeys(RendererVk *renderer);
void clear();
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
index b6efd6855a819d28f60a79848dd811a347704d44..b56e78f8f5335e14826c58bfc521bd7d8e55caeb 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
@@ -3598,7 +3598,7 @@ angle::Result DynamicDescriptorPool::allocateNewPool(Context *context)
return mDescriptorPools[mCurrentPoolIndex]->get().init(context, mPoolSizes, mMaxSetsPerPool);
}
-void DynamicDescriptorPool::releaseCachedDescriptorSet(ContextVk *contextVk,
+void DynamicDescriptorPool::releaseCachedDescriptorSet(RendererVk *renderer,
const DescriptorSetDesc &desc)
{
VkDescriptorSet descriptorSet;
@@ -3612,7 +3612,7 @@ void DynamicDescriptorPool::releaseCachedDescriptorSet(ContextVk *contextVk,
// Wrap it with helper object so that it can be GPU tracked and add it to resource list.
DescriptorSetHelper descriptorSetHelper(poolOut->get().getResourceUse(), descriptorSet);
poolOut->get().addGarbage(std::move(descriptorSetHelper));
- checkAndReleaseUnusedPool(contextVk->getRenderer(), poolOut);
+ checkAndReleaseUnusedPool(renderer, poolOut);
}
}
@@ -4807,6 +4807,12 @@ void BufferHelper::release(RendererVk *renderer)
if (mSuballocation.valid())
{
+ if (!mSuballocation.isSuballocated())
+ {
+ // Destroy cacheKeys now to avoid getting into situation that having to destroy
+ // descriptorSet from garbage collection thread.
+ mSuballocation.getBufferBlock()->releaseAllCachedDescriptorSetCacheKeys(renderer);
+ }
renderer->collectSuballocationGarbage(mUse, std::move(mSuballocation),
std::move(mBufferForVertexArray));
}
@@ -4815,17 +4821,15 @@ void BufferHelper::release(RendererVk *renderer)
ASSERT(!mBufferForVertexArray.valid());
}
-void BufferHelper::releaseBufferAndDescriptorSetCache(ContextVk *contextVk)
+void BufferHelper::releaseBufferAndDescriptorSetCache(RendererVk *renderer)
{
- RendererVk *renderer = contextVk->getRenderer();
-
if (renderer->hasResourceUseFinished(getResourceUse()))
{
mDescriptorSetCacheManager.destroyKeys(renderer);
}
else
{
- mDescriptorSetCacheManager.releaseKeys(contextVk);
+ mDescriptorSetCacheManager.releaseKeys(renderer);
}
release(renderer);
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h
index 29f7d2141fab70e0f542b05004b21701883a39c9..d81f9a4b9b07c6e34094d6d275a04c74c2652d3a 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.h
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.h
@@ -247,7 +247,7 @@ class DynamicDescriptorPool final : angle::NonCopyable
VkDescriptorSet *descriptorSetOut,
SharedDescriptorSetCacheKey *sharedCacheKeyOut);
- void releaseCachedDescriptorSet(ContextVk *contextVk, const DescriptorSetDesc &desc);
+ void releaseCachedDescriptorSet(RendererVk *renderer, const DescriptorSetDesc &desc);
void destroyCachedDescriptorSet(RendererVk *renderer, const DescriptorSetDesc &desc);
template <typename Accumulator>
@@ -771,7 +771,7 @@ class BufferHelper : public ReadWriteResource
void destroy(RendererVk *renderer);
void release(RendererVk *renderer);
- void releaseBufferAndDescriptorSetCache(ContextVk *contextVk);
+ void releaseBufferAndDescriptorSetCache(RendererVk *renderer);
BufferSerial getBufferSerial() const { return mSerial; }
BufferSerial getBlockSerial() const
diff --git a/src/tests/gl_tests/TransformFeedbackTest.cpp b/src/tests/gl_tests/TransformFeedbackTest.cpp
index ea3eeea4015dcb56f710c873b22c95d168bb287c..226eb1f049bb708e0221c81e9b836a67594eb7b0 100644
--- a/src/tests/gl_tests/TransformFeedbackTest.cpp
+++ b/src/tests/gl_tests/TransformFeedbackTest.cpp
@@ -507,8 +507,8 @@ TEST_P(TransformFeedbackTest, UseAsUBOThenUpdateThenCapture)
const std::array<uint32_t, 12> kInitialData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
const std::array<uint32_t, 12> kUpdateData = {
- 0x12345678u, 0x9ABCDEF0u, 0x13579BDFu, 0x2468ACE0u, 0x23456781u, 0xABCDEF09u,
- 0x3579BDF1u, 0x468ACE02u, 0x34567812u, 0xBCDEF09Au, 0x579BDF13u, 0x68ACE024u,
+ 0x12345678u, 0x9ABCDEF0u, 0x13579BDFu, 0x2468ACE0u, 0x23456781u, 0xABCDEF09u,
+ 0x3579BDF1u, 0x468ACE02u, 0x34567812u, 0xBCDEF09Au, 0x579BDF13u, 0x68ACE024u,
};
GLBuffer buffer;
@@ -3749,9 +3749,9 @@ void main()
constexpr size_t kCapturedVaryingsCount = 3;
constexpr std::array<size_t, kCapturedVaryingsCount> kCaptureSizes = {8, 9, 4};
const std::vector<float> kExpected[kCapturedVaryingsCount] = {
- {0.27, 0.30, 0.33, 0.36, 0.39, 0.42, 0.45, 0.48},
- {0.63, 0.66, 0.69, 0.72, 0.75, 0.78, 0.81, 0.84, 0.87},
- {0.25, 0.5, 0.75, 1.0},
+ {0.27, 0.30, 0.33, 0.36, 0.39, 0.42, 0.45, 0.48},
+ {0.63, 0.66, 0.69, 0.72, 0.75, 0.78, 0.81, 0.84, 0.87},
+ {0.25, 0.5, 0.75, 1.0},
};
ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(program, kVS, kFS, tfVaryings, GL_INTERLEAVED_ATTRIBS);
@@ -3848,9 +3848,9 @@ void main()
constexpr size_t kCapturedVaryingsCount = 3;
constexpr std::array<size_t, kCapturedVaryingsCount> kCaptureSizes = {1, 2, 1};
const std::vector<float> kExpected[kCapturedVaryingsCount] = {
- {0.25},
- {0.5, 0.75},
- {1.0},
+ {0.25},
+ {0.5, 0.75},
+ {1.0},
};
ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(program, kVS, kFS, tfVaryings, GL_SEPARATE_ATTRIBS);
@@ -4392,6 +4392,51 @@ TEST_P(TransformFeedbackTest, RenderOnceChangeXfbBufferRenderAgain)
glEndTransformFeedback();
}
+// Test bufferData call and transform feedback.
+TEST_P(TransformFeedbackTest, BufferDataAndTransformFeedback)
+{
+ const char kVS[] = R"(#version 300 es
+flat out highp int var;
+void main() {
+var = 1;
+})";
+
+ const char kFS[] = R"(#version 300 es
+flat in highp int var;
+out highp int color;
+void main() {
+color = var;
+})";
+
+ ANGLE_GL_PROGRAM(program, kVS, kFS);
+
+ GLTexture texture;
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32I, 1, 1);
+
+ GLFramebuffer fbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+ EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ constexpr int kClearColor[] = {123, 0, 0, 0};
+ glClearBufferiv(GL_COLOR, 0, kClearColor);
+ glDrawArrays(GL_POINTS, 0, 1);
+
+ const char *kVarying = "var";
+ glTransformFeedbackVaryings(program, 1, &kVarying, GL_INTERLEAVED_ATTRIBS);
+ glLinkProgram(program);
+ ASSERT_GL_NO_ERROR();
+
+ GLBuffer buffer;
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
+ glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 0x7ffc * 10000, nullptr, GL_DYNAMIC_READ);
+ glBeginTransformFeedback(GL_POINTS);
+ glDrawArrays(GL_POINTS, 0, 1);
+ glEndTransformFeedback();
+ glFlush();
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TransformFeedbackTest);
ANGLE_INSTANTIATE_TEST_ES3_AND(TransformFeedbackTest,
ES3_VULKAN()
diff --git a/src/tests/gl_tests/UniformBufferTest.cpp b/src/tests/gl_tests/UniformBufferTest.cpp
index 4d005c0740d5ff918af103236aa18e8249e00acc..71b85043bd9ca49018e9ed79fa36f24f8499757e 100644
--- a/src/tests/gl_tests/UniformBufferTest.cpp
+++ b/src/tests/gl_tests/UniformBufferTest.cpp
@@ -3422,6 +3422,50 @@ void main() {
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
+// Calling BufferData and use it in a loop to force descriptorSet creation and destroy.
+TEST_P(UniformBufferTest, BufferDataInLoop)
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ // Use large buffer size to get around suballocation, so that we will gets a new buffer with
+ // bufferData call.
+ static constexpr size_t kBufferSize = 4 * 1024 * 1024;
+ std::vector<float> floatData;
+ floatData.resize(kBufferSize / (sizeof(float)), 0.0f);
+ floatData[0] = 0.5f;
+ floatData[1] = 0.75f;
+ floatData[2] = 0.25f;
+ floatData[3] = 1.0f;
+
+ GLTexture textures[2];
+ GLFramebuffer fbos[2];
+ for (int i = 0; i < 2; i++)
+ {
+ glBindTexture(GL_TEXTURE_2D, textures[i]);
+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, fbos[i]);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[i], 0);
+ EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+ }
+
+ for (int loop = 0; loop < 10; loop++)
+ {
+ int i = loop & 0x1;
+ // Switch FBO to get around deferred flush
+ glBindFramebuffer(GL_FRAMEBUFFER, fbos[i]);
+ glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
+ glBufferData(GL_UNIFORM_BUFFER, kBufferSize, floatData.data(), GL_STATIC_DRAW);
+
+ glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
+ glUniformBlockBinding(mProgram, mUniformBufferIndex, 0);
+ drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
+ glFlush();
+ }
+ ASSERT_GL_NO_ERROR();
+ EXPECT_PIXEL_NEAR(0, 0, 128, 191, 64, 255, 1);
+}
+
class WebGL2UniformBufferTest : public UniformBufferTest
{
protected:

View File

@@ -132,3 +132,16 @@ cherry-pick-94af9d13a14b.patch
cherry-pick-ea1cd76358e0.patch
m114_merge_fix_a_crash_caused_by_calling_trace_event.patch
mojoipcz_copy_incoming_messages_early.patch
base_do_not_use_va_args_twice_in_asprintf.patch
cherry-pick-85beff6fd302.patch
cherry-pick-60b93798c991.patch
cherry-pick-933b9fad3a53.patch
cherry-pick-b03973561862.patch
cherry-pick-c60a1ab717c7.patch
cherry-pick-aa23556ff213.patch
networkcontext_don_t_access_url_loader_factories_during_destruction.patch
cherry-pick-1939f7b78eda.patch
cherry-pick-35c06406a658.patch
cherry-pick-74a2eb9c8cb2.patch
cherry-pick-26175b0903d8.patch
fix_use_delegated_generic_capturer_when_available.patch

View File

@@ -0,0 +1,96 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benoit Lize <lizeb@chromium.org>
Date: Fri, 9 Jun 2023 17:59:08 +0000
Subject: Do not use va_args twice in asprintf()
(cherry picked from commit 3cff0cb19a6d01cbdd9932f43dabaaeda9c0330a)
Bug: 1450536
Change-Id: Ib34d96935278869a63897f9a1c66afc98865d90f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4579347
Reviewed-by: Egor Pasko <pasko@chromium.org>
Commit-Queue: Benoit Lize <lizeb@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1151796}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4604070
Reviewed-by: Michael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/branch-heads/5735@{#1224}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h b/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
index 621873126602463a09efca1bf1548ed10910d323..de2af6d7d54e254b9e7b8264b53d30a338fb13e8 100644
--- a/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
+++ b/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
@@ -123,13 +123,21 @@ SHIM_ALWAYS_EXPORT char* __wrap_getcwd(char* buffer, size_t size) {
SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
const char* fmt,
va_list va_args) {
+ // There are cases where we need to use the list of arguments twice, namely
+ // when the original buffer is too small. It is not allowed to walk the list
+ // twice, so make a copy for the second invocation of vsnprintf().
+ va_list va_args_copy;
+ va_copy(va_args_copy, va_args);
+
constexpr int kInitialSize = 128;
*strp = static_cast<char*>(
malloc(kInitialSize)); // Our malloc() doesn't return nullptr.
int actual_size = vsnprintf(*strp, kInitialSize, fmt, va_args);
- if (actual_size < 0)
+ if (actual_size < 0) {
+ va_end(va_args_copy);
return actual_size;
+ }
*strp =
static_cast<char*>(realloc(*strp, static_cast<size_t>(actual_size + 1)));
@@ -139,9 +147,14 @@ SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
//
// This is very lightly used in Chromium in practice, see crbug.com/116558 for
// details.
- if (actual_size >= kInitialSize)
- return vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt, va_args);
-
+ if (actual_size >= kInitialSize) {
+ int ret = vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt,
+ va_args_copy);
+ va_end(va_args_copy);
+ return ret;
+ }
+
+ va_end(va_args_copy);
return actual_size;
}
diff --git a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
index dcf26fa5fc6d51de6276aa6fdcc4691f781c4bfd..fd46a15799864acaf58ef57315606bf515b48b15 100644
--- a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
+++ b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
@@ -734,6 +734,28 @@ TEST_F(AllocatorShimTest, InterceptVasprintf) {
// Should not crash.
}
+TEST_F(AllocatorShimTest, InterceptLongVasprintf) {
+ char* str = nullptr;
+ const char* lorem_ipsum =
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. "
+ "Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, "
+ "ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula "
+ "massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci "
+ "nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit "
+ "amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat "
+ "in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero "
+ "pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo "
+ "in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue "
+ "blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus "
+ "et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed "
+ "pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales "
+ "hendrerit.";
+ int err = asprintf(&str, "%s", lorem_ipsum);
+ EXPECT_EQ(err, static_cast<int>(strlen(lorem_ipsum)));
+ EXPECT_TRUE(str);
+ free(str);
+}
+
#endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
#endif // BUILDFLAG(IS_ANDROID)

View File

@@ -0,0 +1,84 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rune Lillesveen <futhark@chromium.org>
Date: Thu, 24 Aug 2023 10:53:36 +0000
Subject: Don't keep pointer to popped stack memory for :has()
The sibling_features pass into UpdateFeaturesFromCombinator may be
initialized to last_compound_in_adjacent_chain_features if null. The
outer while loop in
AddFeaturesToInvalidationSetsForLogicalCombinationInHas() could then
reference to the last_compound_in_adjacent_chain_features which is
popped from the stack on every outer iteration. That caused an ASAN
failure for reading stack memory that had been popped.
Instead make sure each inner iteration restarts with the same
sibling_features pointer, which seems to have been the intent here.
(cherry picked from commit 5e213507a2f0d6e3c96904a710407b01493670bd)
Bug: 1470477
Change-Id: I260c93016f8ab0d165e4b29ca1aea810bede5b97
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4759326
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1181365}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4777251
Cr-Commit-Position: refs/branch-heads/5845@{#1482}
Cr-Branched-From: 5a5dff63a4a4c63b9b18589819bebb2566c85443-refs/heads/main@{#1160321}
(cherry picked from commit 34e544e4dedf299211f104a2822d98ce1db80f61)
diff --git a/third_party/blink/renderer/core/css/rule_feature_set.cc b/third_party/blink/renderer/core/css/rule_feature_set.cc
index 35483b54816197b3244cac4bb32759a88de57664..c6a93968829a8dc6d14247e8882a9a3fdcfb6f84 100644
--- a/third_party/blink/renderer/core/css/rule_feature_set.cc
+++ b/third_party/blink/renderer/core/css/rule_feature_set.cc
@@ -1322,6 +1322,7 @@ void RuleFeatureSet::AddFeaturesToInvalidationSetsForLogicalCombinationInHas(
descendant_features);
const CSSSelector* compound_in_logical_combination = complex;
+ InvalidationSetFeatures* inner_sibling_features = sibling_features;
InvalidationSetFeatures last_compound_in_adjacent_chain_features;
while (compound_in_logical_combination) {
AddFeaturesToInvalidationSetsForLogicalCombinationInHasContext context(
@@ -1333,14 +1334,14 @@ void RuleFeatureSet::AddFeaturesToInvalidationSetsForLogicalCombinationInHas(
last_in_compound =
SkipAddingAndGetLastInCompoundForLogicalCombinationInHas(
compound_in_logical_combination, compound_containing_has,
- sibling_features, descendant_features, previous_combinator,
- add_features_method);
+ inner_sibling_features, descendant_features,
+ previous_combinator, add_features_method);
} else {
last_in_compound =
AddFeaturesAndGetLastInCompoundForLogicalCombinationInHas(
compound_in_logical_combination, compound_containing_has,
- sibling_features, descendant_features, previous_combinator,
- add_features_method);
+ inner_sibling_features, descendant_features,
+ previous_combinator, add_features_method);
}
if (!last_in_compound) {
@@ -1355,7 +1356,7 @@ void RuleFeatureSet::AddFeaturesToInvalidationSetsForLogicalCombinationInHas(
? CSSSelector::kIndirectAdjacent
: previous_combinator,
context.last_compound_in_adjacent_chain,
- last_compound_in_adjacent_chain_features, sibling_features,
+ last_compound_in_adjacent_chain_features, inner_sibling_features,
descendant_features);
}
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/has-sibling-chrome-crash.html b/third_party/blink/web_tests/external/wpt/css/selectors/has-sibling-chrome-crash.html
new file mode 100644
index 0000000000000000000000000000000000000000..0306e3e39272c321fc3539aa582b4e239ffe2fa1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/selectors/has-sibling-chrome-crash.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<title>CSS Selectors Test: Chrome crash issue 1470477</title>
+<link rel="help" href="https://crbug.com/1470477">
+<style>
+ :has(> :where(label:first-child + [a="a"]:only-of-type,
+ [a="a"]:only-of-type + label:last-child)) label:last-child {
+ margin-inline: 1em;
+ }
+</style>
+<p>PASS if this tests does not crash</p>

View File

@@ -0,0 +1,61 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yi Gu <yigu@chromium.org>
Date: Thu, 31 Aug 2023 20:12:41 +0000
Subject: ReportBadMessage when the provider list is empty
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The provider list should not be empty unless the API is called from a
compromised renderer.
(cherry picked from commit 3b19acb01dcea93b423aa0da56c4a9811a067353)
Change-Id: I3e497fae2343342b3ec6b17bd663f2ec1bf12d54
Bug: 1476403
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4822925
Reviewed-by: Nicolás Peña <npm@chromium.org>
Commit-Queue: Yi Gu <yigu@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1189841}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4833411
Commit-Queue: Nicolás Peña <npm@chromium.org>
Auto-Submit: Yi Gu <yigu@chromium.org>
Cr-Commit-Position: refs/branch-heads/5845@{#1698}
Cr-Branched-From: 5a5dff63a4a4c63b9b18589819bebb2566c85443-refs/heads/main@{#1160321}
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc
index cbae35e588c2db4ac83a23d62fa7c5b0aec09324..194e4d937562ce73fb6e1e095dc16d13f74f002b 100644
--- a/content/browser/webid/federated_auth_request_impl.cc
+++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -415,6 +415,16 @@ void FederatedAuthRequestImpl::RequestToken(
mojo::ReportBadMessage("idp_get_params_ptrs is empty.");
return;
}
+ // This could only happen with a compromised renderer process. We ensure that
+ // the provider list size is > 0 on the renderer side at the beginning of
+ // parsing |IdentityCredentialRequestOptions|.
+ for (auto& idp_get_params_ptr : idp_get_params_ptrs) {
+ if (idp_get_params_ptr->providers.size() == 0) {
+ mojo::ReportBadMessage("The provider list should not be empty.");
+ return;
+ }
+ }
+
// It should not be possible to receive multiple IDPs when the
// `kFedCmMultipleIdentityProviders` flag is disabled. But such a message
// could be received from a compromised renderer.
@@ -425,14 +435,6 @@ void FederatedAuthRequestImpl::RequestToken(
return;
}
- // Check that providers are non-empty.
- for (auto& idp_get_params_ptr : idp_get_params_ptrs) {
- if (idp_get_params_ptr->providers.size() == 0) {
- std::move(callback).Run(RequestTokenStatus::kError, absl::nullopt, "");
- return;
- }
- }
-
if (!fedcm_metrics_) {
// TODO(crbug.com/1307709): Handle FedCmMetrics for multiple IDPs.
fedcm_metrics_ =

View File

@@ -0,0 +1,162 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Guido Urdaneta <guidou@chromium.org>
Date: Thu, 24 Aug 2023 11:12:43 +0000
Subject: Handle object destruction in MediaStreamDeviceObserver
MSDO executes some callbacks that can result in the destruction of
MSDO upon an external event such as removing a media device or the
user revoking permission.
This CL adds code to detect this condition and prevent further
processing that would result in UAF. It also removes some invalid
DCHECKs.
Drive-by: minor style fixes
(cherry picked from commit 7337133682ab0404b753c563dde2ae2b1dc13171)
Bug: 1472492, b/296997707
Change-Id: I76f019bb110e7d9cca276444bc23a7e43114d2cc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4798398
Reviewed-by: Palak Agarwal <agpalak@chromium.org>
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1186452}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4810035
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5845@{#1586}
Cr-Branched-From: 5a5dff63a4a4c63b9b18589819bebb2566c85443-refs/heads/main@{#1160321}
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc b/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc
index 0715b727f7e2b319243f5ec47ead48c8b1b1f644..7bf375055637d67fa409ce977e103baf4aecdf6b 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc
@@ -37,11 +37,11 @@ MediaStreamDeviceObserver::MediaStreamDeviceObserver(LocalFrame* frame) {
if (frame) {
frame->GetInterfaceRegistry()->AddInterface(WTF::BindRepeating(
&MediaStreamDeviceObserver::BindMediaStreamDeviceObserverReceiver,
- WTF::Unretained(this)));
+ weak_factory_.GetWeakPtr()));
}
}
-MediaStreamDeviceObserver::~MediaStreamDeviceObserver() {}
+MediaStreamDeviceObserver::~MediaStreamDeviceObserver() = default;
MediaStreamDevices MediaStreamDeviceObserver::GetNonScreenCaptureDevices() {
MediaStreamDevices video_devices;
@@ -70,13 +70,21 @@ void MediaStreamDeviceObserver::OnDeviceStopped(
}
for (Stream& stream : it->value) {
- if (IsAudioInputMediaType(device.type))
+ if (IsAudioInputMediaType(device.type)) {
RemoveStreamDeviceFromArray(device, &stream.audio_devices);
- else
+ } else {
RemoveStreamDeviceFromArray(device, &stream.video_devices);
-
- if (stream.on_device_stopped_cb)
+ }
+ if (stream.on_device_stopped_cb) {
+ // Running `stream.on_device_stopped_cb` can destroy `this`. Use a weak
+ // pointer to detect that condition, and stop processing if it happens.
+ base::WeakPtr<MediaStreamDeviceObserver> weak_this =
+ weak_factory_.GetWeakPtr();
stream.on_device_stopped_cb.Run(device);
+ if (!weak_this) {
+ return;
+ }
+ }
}
// |it| could have already been invalidated in the function call above. So we
@@ -85,8 +93,9 @@ void MediaStreamDeviceObserver::OnDeviceStopped(
// iterator from |label_stream_map_| (https://crbug.com/616884). Future work
// needs to be done to resolve this re-entrancy issue.
it = label_stream_map_.find(label);
- if (it == label_stream_map_.end())
+ if (it == label_stream_map_.end()) {
return;
+ }
Vector<Stream>& streams = it->value;
auto* stream_it = streams.begin();
@@ -122,8 +131,16 @@ void MediaStreamDeviceObserver::OnDeviceChanged(
DCHECK_EQ(1u, it->value.size());
Stream* stream = &it->value[0];
- if (stream->on_device_changed_cb)
+ if (stream->on_device_changed_cb) {
+ // Running `stream->on_device_changed_cb` can destroy `this`. Use a weak
+ // pointer to detect that condition, and stop processing if it happens.
+ base::WeakPtr<MediaStreamDeviceObserver> weak_this =
+ weak_factory_.GetWeakPtr();
stream->on_device_changed_cb.Run(old_device, new_device);
+ if (!weak_this) {
+ return;
+ }
+ }
// Update device list only for device changing. Removing device will be
// handled in its own callback.
@@ -304,9 +321,9 @@ void MediaStreamDeviceObserver::RemoveStreamDevice(
streams_to_remove.push_back(entry.key);
}
}
- DCHECK(device_found);
- for (const String& label : streams_to_remove)
+ for (const String& label : streams_to_remove) {
label_stream_map_.erase(label);
+ }
}
base::UnguessableToken MediaStreamDeviceObserver::GetAudioSessionId(
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h b/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h
index e14c74b7c4ba270efeb433eb0e5d876f6224e60b..a97e39274caa75a321d08afc8703bd9b2c29351d 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h
@@ -123,6 +123,7 @@ class MODULES_EXPORT MediaStreamDeviceObserver
using LabelStreamMap = HashMap<String, Vector<Stream>>;
LabelStreamMap label_stream_map_;
+ base::WeakPtrFactory<MediaStreamDeviceObserver> weak_factory_{this};
};
} // namespace blink
diff --git a/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
index 2cc3a9a7f072dec1aaf44b3e13d4ef6dacf3e943..e3eddc9d5ed12bf9947af12c1054f217c90d40b8 100644
--- a/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
+++ b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
@@ -32,10 +32,12 @@ void WebPlatformMediaStreamSource::StopSource() {
void WebPlatformMediaStreamSource::FinalizeStopSource() {
DCHECK(task_runner_->BelongsToCurrentThread());
- if (!stop_callback_.is_null())
+ if (!stop_callback_.is_null()) {
std::move(stop_callback_).Run(Owner());
- if (Owner())
+ }
+ if (Owner()) {
Owner().SetReadyState(WebMediaStreamSource::kReadyStateEnded);
+ }
}
void WebPlatformMediaStreamSource::SetSourceMuted(bool is_muted) {
@@ -43,8 +45,9 @@ void WebPlatformMediaStreamSource::SetSourceMuted(bool is_muted) {
// Although this change is valid only if the ready state isn't already Ended,
// there's code further along (like in MediaStreamTrack) which filters
// that out already.
- if (!Owner())
+ if (!Owner()) {
return;
+ }
Owner().SetReadyState(is_muted ? WebMediaStreamSource::kReadyStateMuted
: WebMediaStreamSource::kReadyStateLive);
}
@@ -73,7 +76,6 @@ void WebPlatformMediaStreamSource::SetStopCallback(
void WebPlatformMediaStreamSource::ResetSourceStoppedCallback() {
DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(!stop_callback_.is_null());
stop_callback_.Reset();
}

View File

@@ -0,0 +1,99 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Eugene Zemtsov <eugene@chromium.org>
Date: Wed, 21 Jun 2023 17:57:52 +0000
Subject: webcodecs: Fix crash when changing temporal layer count in AV1
encoder
(cherry picked from commit f312efac1b90117729e8961b58c643fc0eae1fbd)
Bug: 1447568
Change-Id: I4ecb02ed956707571573a65ade17fdffe676b502
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4554300
Auto-Submit: Eugene Zemtsov <eugene@chromium.org>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1148041}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4610718
Cr-Commit-Position: refs/branch-heads/5735@{#1360}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/media/video/av1_video_encoder.cc b/media/video/av1_video_encoder.cc
index 19796f667564412391abdb9d28f900f0364e37e3..72e4184861b6eb837a5d4830140d720b28c90f0f 100644
--- a/media/video/av1_video_encoder.cc
+++ b/media/video/av1_video_encoder.cc
@@ -119,6 +119,7 @@ EncoderStatus SetUpAomConfig(const VideoEncoder::Options& opts,
svc_params = {};
svc_params.framerate_factor[0] = 1;
svc_params.number_spatial_layers = 1;
+ svc_params.number_temporal_layers = 1;
if (opts.scalability_mode.has_value()) {
switch (opts.scalability_mode.value()) {
case SVCScalabilityMode::kL1T1:
diff --git a/media/video/software_video_encoder_test.cc b/media/video/software_video_encoder_test.cc
index c05337f87ff4b8e3a8baf4a417a7dcfc3a2074cc..7954254f7ebf21d7375fb7661cbeb3276a5a4e7f 100644
--- a/media/video/software_video_encoder_test.cc
+++ b/media/video/software_video_encoder_test.cc
@@ -612,6 +612,63 @@ TEST_P(SVCVideoEncoderTest, EncodeClipTemporalSvc) {
}
}
+TEST_P(SVCVideoEncoderTest, ChangeLayers) {
+ VideoEncoder::Options options;
+ options.frame_size = gfx::Size(640, 480);
+ options.bitrate = Bitrate::ConstantBitrate(1000000u); // 1Mbps
+ options.framerate = 25;
+ options.scalability_mode = GetParam().scalability_mode;
+ std::vector<scoped_refptr<VideoFrame>> frames_to_encode;
+
+ std::vector<VideoEncoderOutput> chunks;
+ size_t total_frames_count = 80;
+
+ // Encoder all frames with 3 temporal layers and put all outputs in |chunks|
+ auto frame_duration = base::Seconds(1.0 / options.framerate.value());
+
+ VideoEncoder::OutputCB encoder_output_cb = base::BindLambdaForTesting(
+ [&](VideoEncoderOutput output,
+ absl::optional<VideoEncoder::CodecDescription> desc) {
+ chunks.push_back(std::move(output));
+ });
+
+ encoder_->Initialize(profile_, options, /*info_cb=*/base::DoNothing(),
+ std::move(encoder_output_cb),
+ ValidatingStatusCB(/* quit_run_loop_on_call */ true));
+ RunUntilQuit();
+
+ uint32_t color = 0x964050;
+ for (auto frame_index = 0u; frame_index < total_frames_count; frame_index++) {
+ auto timestamp = frame_index * frame_duration;
+
+ const bool reconfigure = (frame_index == total_frames_count / 2);
+ if (reconfigure) {
+ encoder_->Flush(ValidatingStatusCB(/* quit_run_loop_on_call */ true));
+ RunUntilQuit();
+
+ // Ask encoder to change SVC mode, empty output callback
+ // means the encoder should keep the old one.
+ options.scalability_mode = SVCScalabilityMode::kL1T1;
+ encoder_->ChangeOptions(
+ options, VideoEncoder::OutputCB(),
+ ValidatingStatusCB(/* quit_run_loop_on_call */ true));
+ RunUntilQuit();
+ }
+
+ auto frame =
+ CreateFrame(options.frame_size, pixel_format_, timestamp, color);
+ color = (color << 1) + frame_index;
+ frames_to_encode.push_back(frame);
+ encoder_->Encode(frame, VideoEncoder::EncodeOptions(false),
+ ValidatingStatusCB(/* quit_run_loop_on_call */ true));
+ RunUntilQuit();
+ }
+
+ encoder_->Flush(ValidatingStatusCB(/* quit_run_loop_on_call */ true));
+ RunUntilQuit();
+ EXPECT_EQ(chunks.size(), total_frames_count);
+}
+
TEST_P(H264VideoEncoderTest, ReconfigureWithResize) {
VideoEncoder::Options options;
gfx::Size size1(320, 200), size2(400, 240);

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yoichi Osato <yoichio@chromium.org>
Date: Tue, 29 Aug 2023 02:37:46 +0000
Subject: Readd lock when ObserverListMap::erase()
We should lock when remove an item from the map.
This lock was accidentally removed in:
https://chromium-review.googlesource.com/c/chromium/src/+/4280021
(cherry picked from commit a41479ba6efb5e48b82edad972c7dded6f385b79)
Bug: 1469928
Change-Id: I2512e14d4ad9b246cadae947023dbccb5158da51
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4790983
Auto-Submit: Yoichi Osato <yoichio@chromium.org>
Reviewed-by: Yoichi Osato <yoichio@chromium.org>
Reviewed-by: Koji Ishii <kojii@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1187668}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4820108
Reviewed-by: Kent Tamura <tkent@chromium.org>
Commit-Queue: Kent Tamura <tkent@chromium.org>
Cr-Commit-Position: refs/branch-heads/5845@{#1666}
Cr-Branched-From: 5a5dff63a4a4c63b9b18589819bebb2566c85443-refs/heads/main@{#1160321}
diff --git a/third_party/blink/renderer/platform/network/network_state_notifier.cc b/third_party/blink/renderer/platform/network/network_state_notifier.cc
index 39c417e0f8ec672d413bb69a3b98f06442183295..e74b4ea41b2b30037890f36dd9ff81d6ef3c4e88 100644
--- a/third_party/blink/renderer/platform/network/network_state_notifier.cc
+++ b/third_party/blink/renderer/platform/network/network_state_notifier.cc
@@ -350,6 +350,7 @@ void NetworkStateNotifier::RemoveObserver(
DCHECK(task_runner->RunsTasksInCurrentSequence());
DCHECK(observer);
+ base::AutoLock locker(lock_);
ObserverListMap& map = GetObserverMapFor(type);
DCHECK_NE(map.end(), map.find(observer));
map.erase(observer);

View File

@@ -0,0 +1,215 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kevin McNee <mcnee@chromium.org>
Date: Wed, 14 Jun 2023 01:10:19 +0000
Subject: M114: Don't recursively destroy guests when clearing unattached
guests
Don't recursively destroy guests when clearing unattached guests
When an embedder process is destroyed, we also destroy any unattached
guests associated with that process. This is currently done with a
single call to `owned_guests_.erase`. However, it's possible that two
unattached guests could have an opener relationship, which causes the
destruction of the opener guest to also destroy the other guest, during
the call to `erase`, which is unsafe.
We now separate the steps of erasing `owned_guests_` and destroying the
guests, to avoid this recursive guest destruction.
This also fixes the WaitForNumGuestsCreated test method to not
return prematurely.
(cherry picked from commit 6345e7871e8197af92f9c6158b06c6e197f87945)
Bug: 1450397
Change-Id: Ifef5ec9ff3a1e6952ff56ec279e29e8522625ac0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4589949
Commit-Queue: Kevin McNee <mcnee@chromium.org>
Auto-Submit: Kevin McNee <mcnee@chromium.org>
Reviewed-by: James Maclean <wjmaclean@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1153396}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4611152
Commit-Queue: James Maclean <wjmaclean@chromium.org>
Cr-Commit-Position: refs/branch-heads/5735@{#1292}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index c5167c135a7e41705ac018d3aec568c65fdcb0dc..bdfbf5c75a4275d4a395ff182cbfeda3cb2cc699 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -2884,6 +2884,22 @@ IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest,
EXPECT_TRUE(content::NavigateToURLFromRenderer(guest2, coop_url));
}
+// This test creates a situation where we have two unattached webviews which
+// have an opener relationship, and ensures that we can shutdown safely. See
+// https://crbug.com/1450397.
+IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest, DestroyOpenerBeforeAttachment) {
+ TestHelper("testDestroyOpenerBeforeAttachment", "web_view/newwindow",
+ NEEDS_TEST_SERVER);
+ GetGuestViewManager()->WaitForNumGuestsCreated(2);
+
+ content::RenderProcessHost* embedder_rph =
+ GetEmbedderWebContents()->GetPrimaryMainFrame()->GetProcess();
+ content::RenderProcessHostWatcher kill_observer(
+ embedder_rph, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ EXPECT_TRUE(embedder_rph->Shutdown(content::RESULT_CODE_KILLED));
+ kill_observer.Wait();
+}
+
IN_PROC_BROWSER_TEST_P(WebViewTest, ContextMenuInspectElement) {
LoadAppWithGuest("web_view/context_menus/basic");
content::RenderFrameHost* guest_rfh = GetGuestRenderFrameHost();
diff --git a/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js b/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
index 900911f4963d23d74225868dce01326ba533f63a..4dd25d8849b0b13957ab7fa2912c0a158d3cd244 100644
--- a/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
+++ b/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
@@ -34,6 +34,9 @@ embedder.setUp_ = function(config) {
embedder.guestWithLinkURL = embedder.baseGuestURL +
'/extensions/platform_apps/web_view/newwindow' +
'/guest_with_link.html';
+ embedder.guestOpenOnLoadURL = embedder.baseGuestURL +
+ '/extensions/platform_apps/web_view/newwindow' +
+ '/guest_opener_open_on_load.html';
};
/** @private */
@@ -652,6 +655,24 @@ function testNewWindowDeferredAttachmentIndefinitely() {
embedder.setUpNewWindowRequest_(webview, 'guest.html', '', testName);
}
+// This is not a test in and of itself, but a means of creating a webview that
+// is left in an unattached state while its opener webview is also in an
+// unattached state, so that the C++ side can test it in that state.
+function testDestroyOpenerBeforeAttachment() {
+ embedder.test.succeed();
+
+ let webview = new WebView();
+ webview.src = embedder.guestOpenOnLoadURL;
+ document.body.appendChild(webview);
+
+ // By spinning forever here, we prevent `webview` from completing the
+ // attachment process. But since the guest is still created and it calls
+ // window.open, we have a situation where two unattached webviews have an
+ // opener relationship. The C++ side will test that we can shutdown safely in
+ // this case.
+ while (true) {}
+}
+
embedder.test.testList = {
'testNewWindowAttachAfterOpenerDestroyed':
testNewWindowAttachAfterOpenerDestroyed,
@@ -675,7 +696,9 @@ embedder.test.testList = {
testNewWindowWebViewNameTakesPrecedence,
'testNewWindowAndUpdateOpener': testNewWindowAndUpdateOpener,
'testNewWindowDeferredAttachmentIndefinitely':
- testNewWindowDeferredAttachmentIndefinitely
+ testNewWindowDeferredAttachmentIndefinitely,
+ 'testDestroyOpenerBeforeAttachment':
+ testDestroyOpenerBeforeAttachment
};
onload = function() {
diff --git a/chrome/test/data/extensions/platform_apps/web_view/newwindow/guest_opener_open_on_load.html b/chrome/test/data/extensions/platform_apps/web_view/newwindow/guest_opener_open_on_load.html
new file mode 100644
index 0000000000000000000000000000000000000000..e961feb3c6487066801adf414bf4a2746c50a3f6
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/newwindow/guest_opener_open_on_load.html
@@ -0,0 +1,13 @@
+<!--
+Copyright 2023 The Chromium Authors
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+<html>
+<body>
+<script>
+ // A guest that opens a new window on load.
+ window.open('guest.html');
+</script>
+</body>
+</html>
diff --git a/components/guest_view/browser/guest_view_manager.cc b/components/guest_view/browser/guest_view_manager.cc
index 6b18dc43962386c11c9b656a0f74ae6867b50cd4..eecc03787430cfdbbf1804ebb5245fd6abf731db 100644
--- a/components/guest_view/browser/guest_view_manager.cc
+++ b/components/guest_view/browser/guest_view_manager.cc
@@ -332,7 +332,20 @@ void GuestViewManager::RemoveGuest(int guest_instance_id, bool invalidate_id) {
void GuestViewManager::EmbedderProcessDestroyed(int embedder_process_id) {
embedders_observed_.erase(embedder_process_id);
+
+ // We can't just call std::multimap::erase here because destroying a guest
+ // could trigger the destruction of another guest which is also owned by
+ // `owned_guests_`. Recursively calling std::multimap::erase is unsafe (see
+ // https://crbug.com/1450397). So we take ownership of all of the guests that
+ // will be destroyed before erasing the entries from the map.
+ std::vector<std::unique_ptr<GuestViewBase>> guests_to_destroy;
+ const auto destroy_range = owned_guests_.equal_range(embedder_process_id);
+ for (auto it = destroy_range.first; it != destroy_range.second; ++it) {
+ guests_to_destroy.push_back(std::move(it->second));
+ }
owned_guests_.erase(embedder_process_id);
+ guests_to_destroy.clear();
+
CallViewDestructionCallbacks(embedder_process_id);
}
diff --git a/components/guest_view/browser/test_guest_view_manager.cc b/components/guest_view/browser/test_guest_view_manager.cc
index a0fb5885084cb04688770323c940825ca8e0b6d5..44e264730e2a21d613f4515e8552ad81703f062b 100644
--- a/components/guest_view/browser/test_guest_view_manager.cc
+++ b/components/guest_view/browser/test_guest_view_manager.cc
@@ -37,7 +37,6 @@ TestGuestViewManager::TestGuestViewManager(
num_guests_created_(0),
expected_num_guests_created_(0),
num_views_garbage_collected_(0),
- waiting_for_guests_created_(false),
waiting_for_attach_(nullptr) {}
TestGuestViewManager::~TestGuestViewManager() = default;
@@ -128,14 +127,15 @@ GuestViewBase* TestGuestViewManager::WaitForNextGuestViewCreated() {
}
void TestGuestViewManager::WaitForNumGuestsCreated(size_t count) {
- if (count == num_guests_created_)
+ if (count == num_guests_created_) {
return;
+ }
- waiting_for_guests_created_ = true;
expected_num_guests_created_ = count;
num_created_run_loop_ = std::make_unique<base::RunLoop>();
num_created_run_loop_->Run();
+ num_created_run_loop_ = nullptr;
}
void TestGuestViewManager::WaitUntilAttached(GuestViewBase* guest_view) {
@@ -180,13 +180,11 @@ void TestGuestViewManager::AddGuest(int guest_instance_id,
created_run_loop_->Quit();
++num_guests_created_;
- if (!waiting_for_guests_created_ &&
- num_guests_created_ != expected_num_guests_created_) {
- return;
- }
- if (num_created_run_loop_)
+ if (num_created_run_loop_ &&
+ num_guests_created_ == expected_num_guests_created_) {
num_created_run_loop_->Quit();
+ }
}
void TestGuestViewManager::AttachGuest(int embedder_process_id,
diff --git a/components/guest_view/browser/test_guest_view_manager.h b/components/guest_view/browser/test_guest_view_manager.h
index 094524fad8b5d46cc938e8ac8559bac019b25c09..0c0b718be474335bf95767308f400e40379775d1 100644
--- a/components/guest_view/browser/test_guest_view_manager.h
+++ b/components/guest_view/browser/test_guest_view_manager.h
@@ -120,7 +120,6 @@ class TestGuestViewManager : public GuestViewManager {
size_t num_guests_created_;
size_t expected_num_guests_created_;
int num_views_garbage_collected_;
- bool waiting_for_guests_created_;
// Tracks the life time of the GuestView's main FrameTreeNode. The main FTN
// has the same lifesspan as the GuestView.

View File

@@ -0,0 +1,404 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Fri, 9 Jun 2023 07:49:02 +0000
Subject: Reland "ipcz: Refactor FragmentDescriptor decode"
This is a reland of commit 17dd18d1f2194089b8433e0ca334c81343b591e2
Original change's description:
> ipcz: Refactor FragmentDescriptor decode
>
> Funnels untrusted FragmentDescriptor mapping through a new
> Fragment::MappedFromDescriptor helper. See the linked bug
> for more details.
>
> Fixed: 1450899
> Change-Id: I4c7751b9f4299da4a13c0becc1b889160a0c6e66
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4599218
> Reviewed-by: Daniel Cheng <dcheng@chromium.org>
> Commit-Queue: Ken Rockot <rockot@google.com>
> Cr-Commit-Position: refs/heads/main@{#1155133}
Change-Id: I86ee9118a30dea59d837c377a1f751b20a85a3c3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4602794
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/main@{#1155397}
diff --git a/third_party/ipcz/src/BUILD.gn b/third_party/ipcz/src/BUILD.gn
index 4b3bbaf262815573249648b56c03442757c098ae..3c1cd26c65e5be543e24f51ad0d89b482d177a79 100644
--- a/third_party/ipcz/src/BUILD.gn
+++ b/third_party/ipcz/src/BUILD.gn
@@ -212,6 +212,7 @@ ipcz_source_set("impl") {
"ipcz/application_object.h",
"ipcz/block_allocator.h",
"ipcz/box.h",
+ "ipcz/buffer_id.h",
"ipcz/buffer_pool.h",
"ipcz/driver_memory.h",
"ipcz/driver_memory_mapping.h",
@@ -254,7 +255,6 @@ ipcz_source_set("impl") {
"ipcz/block_allocator_pool.cc",
"ipcz/block_allocator_pool.h",
"ipcz/box.cc",
- "ipcz/buffer_id.h",
"ipcz/buffer_pool.cc",
"ipcz/driver_memory.cc",
"ipcz/driver_memory_mapping.cc",
@@ -378,6 +378,7 @@ ipcz_source_set("ipcz_tests_sources") {
"ipcz/driver_memory_test.cc",
"ipcz/driver_object_test.cc",
"ipcz/driver_transport_test.cc",
+ "ipcz/fragment_test.cc",
"ipcz/message_test.cc",
"ipcz/node_connector_test.cc",
"ipcz/node_link_memory_test.cc",
diff --git a/third_party/ipcz/src/ipcz/block_allocator_pool.cc b/third_party/ipcz/src/ipcz/block_allocator_pool.cc
index bd464f897d1fcbde03941ee334d0e1706bf59868..1b9d50b2c77c046d815a94d7760328c8b379ecab 100644
--- a/third_party/ipcz/src/ipcz/block_allocator_pool.cc
+++ b/third_party/ipcz/src/ipcz/block_allocator_pool.cc
@@ -86,7 +86,7 @@ Fragment BlockAllocatorPool::Allocate() {
FragmentDescriptor descriptor(
entry->buffer_id, checked_cast<uint32_t>(offset),
checked_cast<uint32_t>(allocator.block_size()));
- return Fragment(descriptor, block);
+ return Fragment::FromDescriptorUnsafe(descriptor, block);
}
// Allocation from the active allocator failed. Try another if available.
diff --git a/third_party/ipcz/src/ipcz/buffer_pool.cc b/third_party/ipcz/src/ipcz/buffer_pool.cc
index 6881346d8f8532f070e5121da16f064ae4a9bdaf..27b23049848967f29f81b10ba4f8fa4ead14d2e2 100644
--- a/third_party/ipcz/src/ipcz/buffer_pool.cc
+++ b/third_party/ipcz/src/ipcz/buffer_pool.cc
@@ -26,15 +26,11 @@ Fragment BufferPool::GetFragment(const FragmentDescriptor& descriptor) {
absl::MutexLock lock(&mutex_);
auto it = mappings_.find(descriptor.buffer_id());
if (it == mappings_.end()) {
- return Fragment(descriptor, nullptr);
+ return Fragment::PendingFromDescriptor(descriptor);
}
auto& [id, mapping] = *it;
- if (descriptor.end() > mapping.bytes().size()) {
- return {};
- }
-
- return Fragment(descriptor, mapping.address_at(descriptor.offset()));
+ return Fragment::MappedFromDescriptor(descriptor, mapping);
}
bool BufferPool::AddBlockBuffer(
diff --git a/third_party/ipcz/src/ipcz/buffer_pool_test.cc b/third_party/ipcz/src/ipcz/buffer_pool_test.cc
index a009ffe1c20ade013a19b51eceee4faf334eb591..bff66c452a3e2c38b0f208cca1fa1a082f1ee871 100644
--- a/third_party/ipcz/src/ipcz/buffer_pool_test.cc
+++ b/third_party/ipcz/src/ipcz/buffer_pool_test.cc
@@ -194,9 +194,11 @@ TEST_F(BufferPoolTest, BasicBlockAllocation) {
pool.GetTotalBlockCapacity(kBlockSize));
// We can't free something that isn't a valid allocation.
- EXPECT_FALSE(pool.FreeBlock(Fragment{{}, nullptr}));
- EXPECT_FALSE(pool.FreeBlock(Fragment{{BufferId{1000}, 0, 1}, nullptr}));
- EXPECT_FALSE(pool.FreeBlock(Fragment{{BufferId{0}, 0, 1}, bytes0.data()}));
+ EXPECT_FALSE(pool.FreeBlock(Fragment::FromDescriptorUnsafe({}, nullptr)));
+ EXPECT_FALSE(pool.FreeBlock(
+ Fragment::FromDescriptorUnsafe({BufferId{1000}, 0, 1}, nullptr)));
+ EXPECT_FALSE(pool.FreeBlock(
+ Fragment::FromDescriptorUnsafe({BufferId{0}, 0, 1}, bytes0.data())));
// Allocate all available capacity.
std::vector<Fragment> fragments;
diff --git a/third_party/ipcz/src/ipcz/fragment.cc b/third_party/ipcz/src/ipcz/fragment.cc
index 651d1c2fca5fe4fb69cdf61c6062bd8804ebf704..2ef4ed8dcfa0a56a73975a0b7dcc3f86bf5a83a0 100644
--- a/third_party/ipcz/src/ipcz/fragment.cc
+++ b/third_party/ipcz/src/ipcz/fragment.cc
@@ -6,10 +6,38 @@
#include <cstdint>
+#include "ipcz/driver_memory_mapping.h"
+#include "ipcz/fragment_descriptor.h"
#include "third_party/abseil-cpp/absl/base/macros.h"
+#include "util/safe_math.h"
namespace ipcz {
+// static
+Fragment Fragment::MappedFromDescriptor(const FragmentDescriptor& descriptor,
+ DriverMemoryMapping& mapping) {
+ if (descriptor.is_null()) {
+ return {};
+ }
+
+ const uint32_t end = SaturatedAdd(descriptor.offset(), descriptor.size());
+ if (end > mapping.bytes().size()) {
+ return {};
+ }
+ return Fragment{descriptor, mapping.address_at(descriptor.offset())};
+}
+
+// static
+Fragment Fragment::PendingFromDescriptor(const FragmentDescriptor& descriptor) {
+ return Fragment{descriptor, nullptr};
+}
+
+// static
+Fragment Fragment::FromDescriptorUnsafe(const FragmentDescriptor& descriptor,
+ void* base_address) {
+ return Fragment{descriptor, base_address};
+}
+
Fragment::Fragment(const FragmentDescriptor& descriptor, void* address)
: descriptor_(descriptor), address_(address) {
// If `address` is non-null, the descriptor must also be. Note that the
diff --git a/third_party/ipcz/src/ipcz/fragment.h b/third_party/ipcz/src/ipcz/fragment.h
index c0151fdcf4b418680172a29d1c0d28b58a5807cd..de65f087b0bc27fd59ab88e23130d5ce0d345a8a 100644
--- a/third_party/ipcz/src/ipcz/fragment.h
+++ b/third_party/ipcz/src/ipcz/fragment.h
@@ -14,21 +14,32 @@
namespace ipcz {
+class DriverMemoryMapping;
+
// Represents a span of memory located within the shared memory regions owned by
// a NodeLinkMemory, via BufferPool. This is essentially a FragmentDescriptor
// plus the actual mapped address of the given buffer and offset.
struct Fragment {
constexpr Fragment() = default;
- // Constructs a new Fragment over `descriptor`, mapped to `address`. If
- // `address` is null, the Fragment is considered "pending" -- it has a
- // potentially valid descriptor, but could not be resolved to a mapped address
- // yet (e.g. because the relevant BufferPool doesn't have the identified
- // buffer mapped yet.)
- Fragment(const FragmentDescriptor& descriptor, void* address);
Fragment(const Fragment&);
Fragment& operator=(const Fragment&);
+ // Returns a new concrete Fragment corresponding to `descriptor` within the
+ // context of `mapping`. This validates that the fragment's bounds fall within
+ // the bounds of `mapping`. If `descriptor` was null or validation fails, this
+ // returns a null Fragment.
+ static Fragment MappedFromDescriptor(const FragmentDescriptor& descriptor,
+ DriverMemoryMapping& mapping);
+
+ // Returns a pending Fragment corresponding to `descriptor`.
+ static Fragment PendingFromDescriptor(const FragmentDescriptor& descriptor);
+
+ // Returns a Fragment corresponding to `descriptor`, with the starting address
+ // already mapped to `address`.
+ static Fragment FromDescriptorUnsafe(const FragmentDescriptor& descriptor,
+ void* address);
+
// A null fragment is a fragment with a null descriptor, meaning it does not
// reference a valid buffer ID.
bool is_null() const { return descriptor_.is_null(); }
@@ -66,6 +77,13 @@ struct Fragment {
}
private:
+ // Constructs a new Fragment over `descriptor`, mapped to `address`. If
+ // `address` is null, the Fragment is considered "pending" -- it has a
+ // potentially valid descriptor, but could not be resolved to a mapped address
+ // yet (e.g. because the relevant BufferPool doesn't have the identified
+ // buffer mapped yet.)
+ Fragment(const FragmentDescriptor& descriptor, void* address);
+
FragmentDescriptor descriptor_;
// The actual mapped address corresponding to `descriptor_`.
diff --git a/third_party/ipcz/src/ipcz/fragment_descriptor.h b/third_party/ipcz/src/ipcz/fragment_descriptor.h
index ed5229a392ca8f20ef092fec78c878a53babfa95..d8dbec5333b52f977d56571965ffbee79dff288c 100644
--- a/third_party/ipcz/src/ipcz/fragment_descriptor.h
+++ b/third_party/ipcz/src/ipcz/fragment_descriptor.h
@@ -36,7 +36,6 @@ struct IPCZ_ALIGN(8) FragmentDescriptor {
BufferId buffer_id() const { return buffer_id_; }
uint32_t offset() const { return offset_; }
uint32_t size() const { return size_; }
- uint32_t end() const { return offset_ + size_; }
private:
// Identifies the shared memory buffer in which the memory resides. This ID is
diff --git a/third_party/ipcz/src/ipcz/fragment_test.cc b/third_party/ipcz/src/ipcz/fragment_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e6b6baa6cb2f1fbdfb89d87d644f63681c797c01
--- /dev/null
+++ b/third_party/ipcz/src/ipcz/fragment_test.cc
@@ -0,0 +1,102 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ipcz/fragment.h"
+
+#include <algorithm>
+#include <cstring>
+#include <limits>
+#include <string>
+#include <utility>
+
+#include "ipcz/buffer_id.h"
+#include "ipcz/driver_memory.h"
+#include "ipcz/driver_memory_mapping.h"
+#include "reference_drivers/sync_reference_driver.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ipcz {
+namespace {
+
+const IpczDriver& kTestDriver = reference_drivers::kSyncReferenceDriver;
+
+using FragmentTest = testing::Test;
+
+TEST_F(FragmentTest, FromDescriptorUnsafe) {
+ char kBuffer[] = "Hello, world!";
+
+ Fragment f = Fragment::FromDescriptorUnsafe({BufferId{0}, 1, 4}, kBuffer + 1);
+ EXPECT_FALSE(f.is_null());
+ EXPECT_FALSE(f.is_pending());
+ EXPECT_EQ(1u, f.offset());
+ EXPECT_EQ(4u, f.size());
+ EXPECT_EQ("ello", std::string(f.bytes().begin(), f.bytes().end()));
+
+ f = Fragment::FromDescriptorUnsafe({BufferId{0}, 7, 6}, kBuffer + 7);
+ EXPECT_FALSE(f.is_null());
+ EXPECT_FALSE(f.is_pending());
+ EXPECT_EQ(7u, f.offset());
+ EXPECT_EQ(6u, f.size());
+ EXPECT_EQ("world!", std::string(f.bytes().begin(), f.bytes().end()));
+}
+
+TEST_F(FragmentTest, PendingFromDescriptor) {
+ Fragment f = Fragment::PendingFromDescriptor({BufferId{0}, 5, 42});
+ EXPECT_TRUE(f.is_pending());
+ EXPECT_FALSE(f.is_null());
+ EXPECT_EQ(5u, f.offset());
+ EXPECT_EQ(42u, f.size());
+
+ f = Fragment::PendingFromDescriptor({kInvalidBufferId, 0, 0});
+ EXPECT_TRUE(f.is_null());
+ EXPECT_FALSE(f.is_pending());
+}
+
+TEST_F(FragmentTest, NullMappedFromDescriptor) {
+ constexpr size_t kDataSize = 32;
+ DriverMemory memory(kTestDriver, kDataSize);
+ auto mapping = memory.Map();
+
+ Fragment f =
+ Fragment::MappedFromDescriptor({kInvalidBufferId, 0, 0}, mapping);
+ EXPECT_TRUE(f.is_null());
+}
+
+TEST_F(FragmentTest, InvalidMappedFromDescriptor) {
+ constexpr size_t kDataSize = 32;
+ DriverMemory memory(kTestDriver, kDataSize);
+ auto mapping = memory.Map();
+
+ Fragment f;
+
+ // Offset out of bounds
+ f = Fragment::MappedFromDescriptor({BufferId{0}, kDataSize, 1}, mapping);
+ EXPECT_TRUE(f.is_null());
+
+ // Tail out of bounds
+ f = Fragment::MappedFromDescriptor({BufferId{0}, 0, kDataSize + 5}, mapping);
+ EXPECT_TRUE(f.is_null());
+
+ // Tail overflow
+ f = Fragment::MappedFromDescriptor(
+ {BufferId{0}, std::numeric_limits<uint32_t>::max(), 2}, mapping);
+ EXPECT_TRUE(f.is_null());
+}
+
+TEST_F(FragmentTest, ValidMappedFromDescriptor) {
+ const char kData[] = "0123456789abcdef";
+ DriverMemory memory(kTestDriver, std::size(kData));
+ auto mapping = memory.Map();
+ memcpy(mapping.bytes().data(), kData, std::size(kData));
+
+ Fragment f = Fragment::MappedFromDescriptor({BufferId{0}, 2, 11}, mapping);
+ EXPECT_FALSE(f.is_null());
+ EXPECT_FALSE(f.is_pending());
+ EXPECT_EQ(2u, f.offset());
+ EXPECT_EQ(11u, f.size());
+ EXPECT_EQ("23456789abc", std::string(f.bytes().begin(), f.bytes().end()));
+}
+
+} // namespace
+} // namespace ipcz
diff --git a/third_party/ipcz/src/ipcz/node_link_memory.cc b/third_party/ipcz/src/ipcz/node_link_memory.cc
index 480c756f48f8367d8adacdda4867e8d5766fa760..e424192e77f2bc51215320a9ca7489931dcaf8ba 100644
--- a/third_party/ipcz/src/ipcz/node_link_memory.cc
+++ b/third_party/ipcz/src/ipcz/node_link_memory.cc
@@ -260,8 +260,9 @@ FragmentRef<RouterLinkState> NodeLinkMemory::GetInitialRouterLinkState(
FragmentDescriptor descriptor(kPrimaryBufferId,
ToOffset(state, primary_buffer_memory_.data()),
sizeof(RouterLinkState));
- return FragmentRef<RouterLinkState>(RefCountedFragment::kUnmanagedRef,
- Fragment(descriptor, state));
+ return FragmentRef<RouterLinkState>(
+ RefCountedFragment::kUnmanagedRef,
+ Fragment::FromDescriptorUnsafe(descriptor, state));
}
Fragment NodeLinkMemory::GetFragment(const FragmentDescriptor& descriptor) {
diff --git a/third_party/ipcz/src/ipcz/ref_counted_fragment_test.cc b/third_party/ipcz/src/ipcz/ref_counted_fragment_test.cc
index d5a2243a693597e43f87f116f80599fde383cb59..220c3556a261c5caab7194114af4cf375d9af683 100644
--- a/third_party/ipcz/src/ipcz/ref_counted_fragment_test.cc
+++ b/third_party/ipcz/src/ipcz/ref_counted_fragment_test.cc
@@ -64,7 +64,8 @@ TEST_F(RefCountedFragmentTest, SimpleRef) {
FragmentRef<TestObject> ref(
RefCountedFragment::kUnmanagedRef,
- Fragment(FragmentDescriptor(BufferId(0), 0, sizeof(object)), &object));
+ Fragment::FromDescriptorUnsafe(
+ FragmentDescriptor(BufferId(0), 0, sizeof(object)), &object));
EXPECT_EQ(1, object.ref_count_for_testing());
ref.reset();
EXPECT_EQ(0, object.ref_count_for_testing());
@@ -75,7 +76,8 @@ TEST_F(RefCountedFragmentTest, Copy) {
FragmentRef<TestObject> ref1(
RefCountedFragment::kUnmanagedRef,
- Fragment(FragmentDescriptor(BufferId(0), 0, sizeof(object1)), &object1));
+ Fragment::FromDescriptorUnsafe(
+ FragmentDescriptor(BufferId(0), 0, sizeof(object1)), &object1));
EXPECT_EQ(1, object1.ref_count_for_testing());
FragmentRef<TestObject> other1 = ref1;
@@ -88,7 +90,8 @@ TEST_F(RefCountedFragmentTest, Copy) {
TestObject object2;
auto ref2 = FragmentRef<TestObject>(
RefCountedFragment::kUnmanagedRef,
- Fragment(FragmentDescriptor(BufferId(0), 0, sizeof(object2)), &object2));
+ Fragment::FromDescriptorUnsafe(
+ FragmentDescriptor(BufferId(0), 0, sizeof(object2)), &object2));
EXPECT_EQ(1, object1.ref_count_for_testing());
EXPECT_EQ(1, object2.ref_count_for_testing());
ref2 = ref1;
@@ -115,7 +118,8 @@ TEST_F(RefCountedFragmentTest, Move) {
FragmentRef<TestObject> ref1(
RefCountedFragment::kUnmanagedRef,
- Fragment(FragmentDescriptor(BufferId(0), 0, sizeof(object1)), &object1));
+ Fragment::FromDescriptorUnsafe(
+ FragmentDescriptor(BufferId(0), 0, sizeof(object1)), &object1));
EXPECT_EQ(1, ref1.ref_count_for_testing());
FragmentRef<TestObject> other1 = std::move(ref1);
@@ -133,10 +137,12 @@ TEST_F(RefCountedFragmentTest, Move) {
TestObject object3;
FragmentRef<TestObject> ref2(
RefCountedFragment::kUnmanagedRef,
- Fragment(FragmentDescriptor(BufferId(0), 0, sizeof(object2)), &object2));
+ Fragment::FromDescriptorUnsafe(
+ FragmentDescriptor(BufferId(0), 0, sizeof(object2)), &object2));
FragmentRef<TestObject> ref3(
RefCountedFragment::kUnmanagedRef,
- Fragment(FragmentDescriptor(BufferId(0), 0, sizeof(object3)), &object3));
+ Fragment::FromDescriptorUnsafe(
+ FragmentDescriptor(BufferId(0), 0, sizeof(object3)), &object3));
EXPECT_FALSE(ref2.is_null());
EXPECT_TRUE(ref2.is_addressable());

View File

@@ -0,0 +1,266 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alex Moshchuk <alexmos@chromium.org>
Date: Tue, 13 Jun 2023 20:27:29 +0000
Subject: Remove SiteInstanceDeleting from content/public API.
Currently, two unit tests are relying on
ContentBrowserClient::SiteInstanceDeleting() to ensure that
SiteInstance lifetimes are managed properly. However, it is
undesirable to allow //content embedders to run arbitrary code during
SiteInstance destruction, per the linked bug. Hence, this CL converts
SiteInstanceDeleting() usage to a test-specific callback instead and
removes it from ContentBrowserClient.
(cherry picked from commit f149f77b2a4f3416f8f7ea54a8fd972763c4b383)
Bug: 1444438
Change-Id: I2affcb4a40ccfbf3bd715d7b225976a687405616
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4564316
Commit-Queue: Alex Moshchuk <alexmos@chromium.org>
Reviewed-by: Charlie Reis <creis@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1149171}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4610071
Cr-Commit-Position: refs/branch-heads/5790@{#710}
Cr-Branched-From: 1d71a337b1f6e707a13ae074dca1e2c34905eb9f-refs/heads/main@{#1148114}
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc
index 3fd0545c6a9a49e064d54d3292187e78a4900040..8ba13311bdd825d6b07b941769af94f6e9002091 100644
--- a/content/browser/site_instance_impl.cc
+++ b/content/browser/site_instance_impl.cc
@@ -105,7 +105,9 @@ SiteInstanceImpl::SiteInstanceImpl(BrowsingInstance* browsing_instance)
}
SiteInstanceImpl::~SiteInstanceImpl() {
- GetContentClient()->browser()->SiteInstanceDeleting(this);
+ if (destruction_callback_for_testing_) {
+ std::move(destruction_callback_for_testing_).Run();
+ }
// Now that no one is referencing us, we can safely remove ourselves from
// the BrowsingInstance. Any future visits to a page from this site
diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h
index bea6b211ead2190960a3bf5a52ca888daa7c5797..28d03536c16aad7d4021e6a9efddd1bc06324ace 100644
--- a/content/browser/site_instance_impl.h
+++ b/content/browser/site_instance_impl.h
@@ -446,6 +446,12 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance {
// BrowsingInstance.
RenderProcessHost* GetDefaultProcessForBrowsingInstance();
+ // Set a callback to be run from this SiteInstance's destructor. Used only in
+ // tests.
+ void set_destruction_callback_for_testing(base::OnceClosure callback) {
+ destruction_callback_for_testing_ = std::move(callback);
+ }
+
private:
friend class BrowsingInstance;
friend class SiteInstanceTestBrowserClient;
@@ -585,6 +591,12 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance {
// Keeps track of whether we need to verify that the StoragePartition
// information does not change when `site_info_` is set.
bool verify_storage_partition_info_ = false;
+
+ // Tracks the number of active documents currently in this SiteInstance.
+ size_t active_document_count_ = 0;
+
+ // Test-only callback to run when this SiteInstance is destroyed.
+ base::OnceClosure destruction_callback_for_testing_;
};
} // namespace content
diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc
index 73a689bb2680bd7d76cf580c1a085923c0e1e464..e89c0866d23d8a6353eed4a5d424113112f3cad7 100644
--- a/content/browser/site_instance_impl_unittest.cc
+++ b/content/browser/site_instance_impl_unittest.cc
@@ -91,32 +91,8 @@ class SiteInstanceTestBrowserClient : public TestContentBrowserClient {
privileged_process_id_ = process_id;
}
- void SiteInstanceDeleting(content::SiteInstance* site_instance) override {
- site_instance_delete_count_++;
- // Infer deletion of the browsing instance.
- if (static_cast<SiteInstanceImpl*>(site_instance)
- ->browsing_instance_->HasOneRef()) {
- browsing_instance_delete_count_++;
- }
- }
-
- int GetAndClearSiteInstanceDeleteCount() {
- int result = site_instance_delete_count_;
- site_instance_delete_count_ = 0;
- return result;
- }
-
- int GetAndClearBrowsingInstanceDeleteCount() {
- int result = browsing_instance_delete_count_;
- browsing_instance_delete_count_ = 0;
- return result;
- }
-
private:
int privileged_process_id_ = -1;
-
- int site_instance_delete_count_ = 0;
- int browsing_instance_delete_count_ = 0;
};
class SiteInstanceTest : public testing::Test {
@@ -193,6 +169,45 @@ class SiteInstanceTest : public testing::Test {
/*should_compare_effective_urls=*/true);
}
+ // Helper class to watch whether a particular SiteInstance has been
+ // destroyed.
+ class SiteInstanceDestructionObserver {
+ public:
+ SiteInstanceDestructionObserver() = default;
+
+ explicit SiteInstanceDestructionObserver(SiteInstanceImpl* site_instance) {
+ SetSiteInstance(site_instance);
+ }
+
+ void SetSiteInstance(SiteInstanceImpl* site_instance) {
+ site_instance_ = site_instance;
+ site_instance_->set_destruction_callback_for_testing(
+ base::BindOnce(&SiteInstanceDestructionObserver::SiteInstanceDeleting,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ void SiteInstanceDeleting() {
+ ASSERT_FALSE(site_instance_deleted_);
+ ASSERT_FALSE(browsing_instance_deleted_);
+
+ site_instance_deleted_ = true;
+ // Infer deletion of the BrowsingInstance.
+ if (site_instance_->browsing_instance_->HasOneRef()) {
+ browsing_instance_deleted_ = true;
+ }
+ site_instance_ = nullptr;
+ }
+
+ bool site_instance_deleted() { return site_instance_deleted_; }
+ bool browsing_instance_deleted() { return browsing_instance_deleted_; }
+
+ private:
+ raw_ptr<SiteInstanceImpl> site_instance_ = nullptr;
+ bool site_instance_deleted_ = false;
+ bool browsing_instance_deleted_ = false;
+ base::WeakPtrFactory<SiteInstanceDestructionObserver> weak_factory_{this};
+ };
+
private:
BrowserTaskEnvironment task_environment_;
TestBrowserContext context_;
@@ -440,7 +455,8 @@ TEST_F(SiteInstanceTest, SiteInstanceDestructor) {
// Ensure that instances are deleted when their NavigationEntries are gone.
scoped_refptr<SiteInstanceImpl> instance = SiteInstanceImpl::Create(&context);
- EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount());
+ SiteInstanceDestructionObserver observer(instance.get());
+ EXPECT_FALSE(observer.site_instance_deleted());
NavigationEntryImpl* e1 = new NavigationEntryImpl(
instance, url, Referrer(), /* initiator_origin= */ absl::nullopt,
@@ -450,8 +466,8 @@ TEST_F(SiteInstanceTest, SiteInstanceDestructor) {
// Redundantly setting e1's SiteInstance shouldn't affect the ref count.
e1->set_site_instance(instance);
- EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
+ EXPECT_FALSE(observer.site_instance_deleted());
+ EXPECT_FALSE(observer.browsing_instance_deleted());
// Add a second reference
NavigationEntryImpl* e2 = new NavigationEntryImpl(
@@ -461,36 +477,40 @@ TEST_F(SiteInstanceTest, SiteInstanceDestructor) {
false /* is_initial_entry */);
instance = nullptr;
- EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
+
+ EXPECT_FALSE(observer.site_instance_deleted());
+ EXPECT_FALSE(observer.browsing_instance_deleted());
// Now delete both entries and be sure the SiteInstance goes away.
delete e1;
- EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
+ EXPECT_FALSE(observer.site_instance_deleted());
+ EXPECT_FALSE(observer.browsing_instance_deleted());
delete e2;
// instance is now deleted
- EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(1, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
+ EXPECT_TRUE(observer.site_instance_deleted());
+ EXPECT_TRUE(observer.browsing_instance_deleted());
// browsing_instance is now deleted
- // Ensure that instances are deleted when their RenderViewHosts are gone.
+ // Ensure that instances are deleted when their RenderFrameHosts are gone.
std::unique_ptr<TestBrowserContext> browser_context(new TestBrowserContext());
+ SiteInstanceDestructionObserver observer2;
{
std::unique_ptr<WebContents> web_contents(
WebContents::Create(WebContents::CreateParams(
browser_context.get(),
SiteInstance::Create(browser_context.get()))));
- EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
+ observer2.SetSiteInstance(static_cast<SiteInstanceImpl*>(
+ web_contents->GetPrimaryMainFrame()->GetSiteInstance()));
+ EXPECT_FALSE(observer2.site_instance_deleted());
+ EXPECT_FALSE(observer2.browsing_instance_deleted());
}
// Make sure that we flush any messages related to the above WebContentsImpl
// destruction.
DrainMessageLoop();
- EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(1, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
+ EXPECT_TRUE(observer2.site_instance_deleted());
+ EXPECT_TRUE(observer2.browsing_instance_deleted());
// contents is now deleted, along with instance and browsing_instance
}
@@ -521,7 +541,6 @@ TEST_F(SiteInstanceTest, DefaultSiteInstanceProperties) {
auto site_instance = SiteInstanceImpl::CreateForTesting(
&browser_context, GURL("http://foo.com"));
-
EXPECT_TRUE(site_instance->IsDefaultSiteInstance());
EXPECT_TRUE(site_instance->HasSite());
EXPECT_EQ(site_instance->GetSiteInfo(),
@@ -547,14 +566,15 @@ TEST_F(SiteInstanceTest, DefaultSiteInstanceDestruction) {
// are gone.
auto site_instance = SiteInstanceImpl::CreateForTesting(
&browser_context, GURL("http://foo.com"));
+ SiteInstanceDestructionObserver observer(site_instance.get());
EXPECT_EQ(AreDefaultSiteInstancesEnabled(),
site_instance->IsDefaultSiteInstance());
site_instance.reset();
- EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(1, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
+ EXPECT_TRUE(observer.site_instance_deleted());
+ EXPECT_TRUE(observer.browsing_instance_deleted());
}
// Test to ensure GetProcess returns and creates processes correctly.
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 543b1712a9b744598ec6d851bc658e5b7e86d39e..757b20c73826e291c8958cc2bfaded2a8f8cd576 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -582,9 +582,6 @@ class CONTENT_EXPORT ContentBrowserClient {
// Called when a site instance is first associated with a process.
virtual void SiteInstanceGotProcess(SiteInstance* site_instance) {}
- // Called from a site instance's destructor.
- virtual void SiteInstanceDeleting(SiteInstance* site_instance) {}
-
// Returns true if for the navigation from |current_effective_url| to
// |destination_effective_url| in |site_instance|, a new SiteInstance and
// BrowsingInstance should be created (even if we are in a process model that

View File

@@ -0,0 +1,119 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tommi <tommi@chromium.org>
Date: Wed, 5 Jul 2023 10:55:53 +0000
Subject: Make RTCDataChannel's channel and observer pointers const.
This allows channel properties to be queried while the RTCDataChannel
instance exists and avoids potential null deref after entering the
kClosed state.
(cherry picked from commit 08d5ad011f53a1995bfccef6728bfa62541f7608)
Bug: 1456567, 1457421
Change-Id: I4747f9c00804b35711667d7320ec6188f20910c4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4663082
Commit-Queue: Tomas Gunnarsson <tommi@chromium.org>
Reviewed-by: Elad Alon <eladalon@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1165406}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4665530
Cr-Commit-Position: refs/branch-heads/5845@{#300}
Cr-Branched-From: 5a5dff63a4a4c63b9b18589819bebb2566c85443-refs/heads/main@{#1160321}
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
index 26879ee20a09044bf1ea914e872599b4a2e65ec8..317023c42431319b20d1cc72bc40f52fffc7708a 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
@@ -229,11 +229,12 @@ RTCDataChannel::Observer::Observer(
scoped_refptr<webrtc::DataChannelInterface> channel)
: main_thread_(main_thread),
blink_channel_(blink_channel),
- webrtc_channel_(channel) {}
+ webrtc_channel_(std::move(channel)) {
+ CHECK(webrtc_channel_.get());
+}
RTCDataChannel::Observer::~Observer() {
DCHECK(!blink_channel_) << "Reference to blink channel hasn't been released.";
- DCHECK(!webrtc_channel_.get()) << "Unregister hasn't been called.";
}
const scoped_refptr<webrtc::DataChannelInterface>&
@@ -243,13 +244,8 @@ RTCDataChannel::Observer::channel() const {
void RTCDataChannel::Observer::Unregister() {
DCHECK(main_thread_->BelongsToCurrentThread());
+ webrtc_channel_->UnregisterObserver();
blink_channel_ = nullptr;
- if (webrtc_channel_.get()) {
- webrtc_channel_->UnregisterObserver();
- // Now that we're guaranteed to not get further OnStateChange callbacks,
- // it's safe to release our reference to the channel.
- webrtc_channel_ = nullptr;
- }
}
void RTCDataChannel::Observer::OnStateChange() {
@@ -303,7 +299,7 @@ void RTCDataChannel::Observer::OnMessageImpl(
RTCDataChannel::RTCDataChannel(
ExecutionContext* context,
- scoped_refptr<webrtc::DataChannelInterface> channel,
+ scoped_refptr<webrtc::DataChannelInterface> data_channel,
RTCPeerConnectionHandler* peer_connection_handler)
: ExecutionContextLifecycleObserver(context),
state_(webrtc::DataChannelInterface::kConnecting),
@@ -318,7 +314,7 @@ RTCDataChannel::RTCDataChannel(
observer_(base::MakeRefCounted<Observer>(
context->GetTaskRunner(TaskType::kNetworking),
this,
- channel)),
+ std::move(data_channel))),
signaling_thread_(peer_connection_handler->signaling_thread()) {
DCHECK(peer_connection_handler);
@@ -341,7 +337,7 @@ RTCDataChannel::RTCDataChannel(
observer_, state_),
"RegisterObserverAndGetStateUpdate");
- IncrementCounters(*channel.get());
+ IncrementCounters(*(observer_->channel()).get());
}
RTCDataChannel::~RTCDataChannel() = default;
@@ -690,9 +686,8 @@ void RTCDataChannel::Dispose() {
if (stopped_)
return;
- // Clears the weak persistent reference to this on-heap object.
+ // Clear the weak persistent reference to this on-heap object.
observer_->Unregister();
- observer_ = nullptr;
}
void RTCDataChannel::ScheduleDispatchEvent(Event* event) {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
index 21bb39382ac0c6acbf984ffbda5f6a4e6c863432..6959b8b1e3a0b586be68cb4a8d0389b7926b98fe 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
@@ -152,7 +152,7 @@ class MODULES_EXPORT RTCDataChannel final
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
WeakPersistent<RTCDataChannel> blink_channel_;
- scoped_refptr<webrtc::DataChannelInterface> webrtc_channel_;
+ const scoped_refptr<webrtc::DataChannelInterface> webrtc_channel_;
};
void OnStateChange(webrtc::DataChannelInterface::DataState state);
@@ -195,7 +195,11 @@ class MODULES_EXPORT RTCDataChannel final
unsigned buffered_amount_;
bool stopped_;
bool closed_from_owner_;
- scoped_refptr<Observer> observer_;
+ // Keep the `observer_` reference const to make it clear that we don't want
+ // to free the underlying channel (or callback observer) until the
+ // `RTCDataChannel` instance goes away. This allows properties to be queried
+ // after the state reaches `kClosed`.
+ const scoped_refptr<Observer> observer_;
scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_;
THREAD_CHECKER(thread_checker_);
};

View File

@@ -0,0 +1,187 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taylor Bergquist <tbergquist@chromium.org>
Date: Tue, 11 Jul 2023 01:32:22 +0000
Subject: Fix UAF when exiting a nested run loop in
TabDragContextImpl::OnGestureEvent.
OnGestureEvent may call ContinueDrag, which may run a nested run loop. After the nested run loop returns, multiple seconds of time may have passed, and the world may be in a very different state; in particular, the window that contains this TabDragContext may have closed.
This CL checks if this has happened, and returns early in that case.
(cherry picked from commit 63d6b8ba8126b16215d33670df8c67dcbc6c9bef)
Bug: 1453465
Change-Id: I6095c0afeb5aa5f422717f1bbd93b96175e52afa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4657527
Reviewed-by: Darryl James <dljames@chromium.org>
Commit-Queue: Taylor Bergquist <tbergquist@chromium.org>
Code-Coverage: Findit <findit-for-me@appspot.gserviceaccount.com>
Cr-Original-Commit-Position: refs/heads/main@{#1164449}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4676126
Reviewed-by: Shibalik Mohapatra <shibalik@chromium.org>
Cr-Commit-Position: refs/branch-heads/5845@{#410}
Cr-Branched-From: 5a5dff63a4a4c63b9b18589819bebb2566c85443-refs/heads/main@{#1160321}
diff --git a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.cc b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.cc
index d1f5a96ed729fde1224f596212f49e386fc6f170..c80536b0d4601c68ce279dfa122f38b39b13fb72 100644
--- a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.cc
+++ b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.cc
@@ -43,6 +43,12 @@ bool FakeTabSlotController::IsFocusInTabs() const {
return false;
}
+TabSlotController::Liveness FakeTabSlotController::ContinueDrag(
+ views::View* view,
+ const ui::LocatedEvent& event) {
+ return Liveness::kAlive;
+}
+
bool FakeTabSlotController::EndDrag(EndDragReason reason) {
return false;
}
diff --git a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h
index 25f1c66d131189ebec2711b49f7f0c141f2c06d2..98dab21cfe2e3ecb88f70cac3868fb30828658be 100644
--- a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h
+++ b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h
@@ -60,8 +60,8 @@ class FakeTabSlotController : public TabSlotController {
TabSlotView* source,
const ui::LocatedEvent& event,
const ui::ListSelectionModel& original_selection) override {}
- void ContinueDrag(views::View* view, const ui::LocatedEvent& event) override {
- }
+ Liveness ContinueDrag(views::View* view,
+ const ui::LocatedEvent& event) override;
bool EndDrag(EndDragReason reason) override;
Tab* GetTabAt(const gfx::Point& point) override;
const Tab* GetAdjacentTab(const Tab* tab, int offset) override;
diff --git a/chrome/browser/ui/views/tabs/tab_slot_controller.h b/chrome/browser/ui/views/tabs/tab_slot_controller.h
index f729425995ffd1ee6926ef953417d2e81a1b527b..c57760f30ae515cf5ee7a021e07c8d049082e371 100644
--- a/chrome/browser/ui/views/tabs/tab_slot_controller.h
+++ b/chrome/browser/ui/views/tabs/tab_slot_controller.h
@@ -49,6 +49,8 @@ class TabSlotController {
kEvent
};
+ enum class Liveness { kAlive, kDeleted };
+
virtual const ui::ListSelectionModel& GetSelectionModel() const = 0;
// Returns the tab at |index|.
@@ -126,9 +128,10 @@ class TabSlotController {
const ui::LocatedEvent& event,
const ui::ListSelectionModel& original_selection) = 0;
- // Continues dragging a Tab.
- virtual void ContinueDrag(views::View* view,
- const ui::LocatedEvent& event) = 0;
+ // Continues dragging a Tab. May enter a nested event loop - returns
+ // Liveness::kDeleted if `this` was destroyed during this nested event loop,
+ // and Liveness::kAlive if `this` is still alive.
+ virtual Liveness ContinueDrag(views::View* view, const ui::LocatedEvent& event) = 0;
// Ends dragging a Tab. Returns whether the tab has been destroyed.
virtual bool EndDrag(EndDragReason reason) = 0;
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index c847ab83eaf94af83b0253747e6d15018d4eb5cf..8e5f40ca5a20f6010c573a51c816c0709322906c 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -179,7 +179,7 @@ class TabStrip::TabDragContextImpl : public TabDragContext,
}
bool OnMouseDragged(const ui::MouseEvent& event) override {
- ContinueDrag(this, event);
+ (void)ContinueDrag(this, event);
return true;
}
@@ -190,6 +190,7 @@ class TabStrip::TabDragContextImpl : public TabDragContext,
void OnMouseCaptureLost() override { EndDrag(END_DRAG_CAPTURE_LOST); }
void OnGestureEvent(ui::GestureEvent* event) override {
+ Liveness tabstrip_alive = Liveness::kAlive;
switch (event->type()) {
case ui::ET_GESTURE_SCROLL_END:
case ui::ET_SCROLL_FLING_START:
@@ -203,7 +204,8 @@ class TabStrip::TabDragContextImpl : public TabDragContext,
}
case ui::ET_GESTURE_SCROLL_UPDATE:
- ContinueDrag(this, *event);
+ // N.B. !! ContinueDrag may enter a nested run loop !!
+ tabstrip_alive = ContinueDrag(this, *event);
break;
case ui::ET_GESTURE_TAP_DOWN:
@@ -215,6 +217,12 @@ class TabStrip::TabDragContextImpl : public TabDragContext,
}
event->SetHandled();
+ // If tabstrip was destroyed (during ContinueDrag above), return early to
+ // avoid UAF below.
+ if (tabstrip_alive == Liveness::kDeleted) {
+ return;
+ }
+
// TabDragContext gets event capture as soon as a drag session begins, which
// precludes TabStrip from ever getting events like tap or long tap. Forward
// this on to TabStrip so it can respond to those events.
@@ -303,20 +311,20 @@ class TabStrip::TabDragContextImpl : public TabDragContext,
std::move(drag_controller_set_callback_).Run(drag_controller_.get());
}
- void ContinueDrag(views::View* view, const ui::LocatedEvent& event) {
- if (drag_controller_.get() &&
- drag_controller_->event_source() == EventSourceFromEvent(event)) {
- gfx::Point screen_location(event.location());
- views::View::ConvertPointToScreen(view, &screen_location);
+ Liveness ContinueDrag(views::View* view, const ui::LocatedEvent& event) {
+ if (!drag_controller_.get() ||
+ drag_controller_->event_source() != EventSourceFromEvent(event)) {
+ return Liveness::kAlive;
+ }
- // Note: |tab_strip_| can be destroyed during drag, also destroying
- // |this|.
- base::WeakPtr<TabDragContext> weak_ptr(weak_factory_.GetWeakPtr());
- drag_controller_->Drag(screen_location);
+ gfx::Point screen_location(event.location());
+ views::View::ConvertPointToScreen(view, &screen_location);
- if (!weak_ptr)
- return;
- }
+ // Note: `tab_strip_` can be destroyed during drag, also destroying `this`.
+ base::WeakPtr<TabDragContext> weak_ptr(weak_factory_.GetWeakPtr());
+ drag_controller_->Drag(screen_location);
+
+ return weak_ptr ? Liveness::kAlive : Liveness::kDeleted;
}
bool EndDrag(EndDragReason reason) {
@@ -1601,8 +1609,10 @@ void TabStrip::MaybeStartDrag(
drag_context_->MaybeStartDrag(source, event, original_selection);
}
-void TabStrip::ContinueDrag(views::View* view, const ui::LocatedEvent& event) {
- drag_context_->ContinueDrag(view, event);
+TabSlotController::Liveness TabStrip::ContinueDrag(
+ views::View* view,
+ const ui::LocatedEvent& event) {
+ return drag_context_->ContinueDrag(view, event);
}
bool TabStrip::EndDrag(EndDragReason reason) {
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h
index bae5dee16134a343173c3fd3f6005aef76ac1e25..ea3397c7da33ac5933caf7a8e9816a931ee064e7 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.h
+++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -277,7 +277,8 @@ class TabStrip : public views::View,
TabSlotView* source,
const ui::LocatedEvent& event,
const ui::ListSelectionModel& original_selection) override;
- void ContinueDrag(views::View* view, const ui::LocatedEvent& event) override;
+ Liveness ContinueDrag(views::View* view,
+ const ui::LocatedEvent& event) override;
bool EndDrag(EndDragReason reason) override;
Tab* GetTabAt(const gfx::Point& point) override;
const Tab* GetAdjacentTab(const Tab* tab, int offset) override;

View File

@@ -82,7 +82,7 @@ index 33ca7a53dfb6d2c9e3a33f0065a3acd806e82e01..9fdf2e8ff0056ff407015b914c6b03eb
const Source& GetSource(int index) const override;
DesktopMediaList::Type GetMediaListType() const override;
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list.cc b/chrome/browser/media/webrtc/native_desktop_media_list.cc
index b548c9fbd3c0bf425447b29dcd866cd27e96b14c..f994ac6086c7b4cd3e8534f34691189d78a21601 100644
index b548c9fbd3c0bf425447b29dcd866cd27e96b14c..4de719510eaeaaf77cdbd46560f3b4ab1869877a 100644
--- a/chrome/browser/media/webrtc/native_desktop_media_list.cc
+++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
@@ -147,7 +147,7 @@ BOOL CALLBACK AllHwndCollector(HWND hwnd, LPARAM param) {
@@ -94,17 +94,20 @@ index b548c9fbd3c0bf425447b29dcd866cd27e96b14c..f994ac6086c7b4cd3e8534f34691189d
#endif
} // namespace
@@ -457,6 +457,9 @@ void NativeDesktopMediaList::Worker::RefreshNextThumbnail() {
@@ -457,6 +457,12 @@ void NativeDesktopMediaList::Worker::RefreshNextThumbnail() {
FROM_HERE,
base::BindOnce(&NativeDesktopMediaList::UpdateNativeThumbnailsFinished,
media_list_));
+
+ // This call is necessary to release underlying OS screen capture mechanisms.
+ capturer_.reset();
+ // Skip if the source list is delegated, as the source list window will be active.
+ if (!capturer_->GetDelegatedSourceListController()) {
+ capturer_.reset();
+ }
}
void NativeDesktopMediaList::Worker::OnCaptureResult(
@@ -829,6 +832,11 @@ void NativeDesktopMediaList::RefreshForVizFrameSinkWindows(
@@ -829,6 +835,11 @@ void NativeDesktopMediaList::RefreshForVizFrameSinkWindows(
FROM_HERE, base::BindOnce(&Worker::RefreshThumbnails,
base::Unretained(worker_.get()),
std::move(native_ids), thumbnail_size_));

View File

@@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Athul Iddya <athul@iddya.com>
Date: Fri, 14 Jul 2023 08:03:37 -0700
Subject: fix: use delegated generic capturer when available
When the generic capturer is used to fetch capture sources, the returned
ID will be arbitrarily prefixed with "screen" or "window" regardless of
the source type. If the window capturer is used to stream video when the
source was a screen or vice-versa, the stream fails to restart in
delegated capturers like PipeWire.
To fix this, use the generic capturer to fetch the media stream if it's
delegated and available. This does not cause any issues if the original
capturer was window or screen-specific, as the IDs remain valid for
generic capturer as well.
diff --git a/content/browser/media/capture/desktop_capture_device.cc b/content/browser/media/capture/desktop_capture_device.cc
index 18b03b2f3cc6a36df1241decef190114eeacfb1f..a65989fcab06caea2cb955f7da050d8328cbcae4 100644
--- a/content/browser/media/capture/desktop_capture_device.cc
+++ b/content/browser/media/capture/desktop_capture_device.cc
@@ -622,8 +622,14 @@ std::unique_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
DesktopCapturerLacros::CaptureType::kScreen,
webrtc::DesktopCaptureOptions());
#else
- std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
- webrtc::DesktopCapturer::CreateScreenCapturer(options));
+ std::unique_ptr<webrtc::DesktopCapturer> screen_capturer;
+ if (auto generic_capturer =
+ webrtc::DesktopCapturer::CreateGenericCapturer(options);
+ generic_capturer && generic_capturer->GetDelegatedSourceListController()) {
+ screen_capturer = std::move(generic_capturer);
+ } else {
+ screen_capturer = webrtc::DesktopCapturer::CreateScreenCapturer(options);
+ }
#endif
if (screen_capturer && screen_capturer->SelectSource(source.id)) {
capturer = std::make_unique<webrtc::DesktopAndCursorComposer>(
@@ -642,8 +648,14 @@ std::unique_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
new DesktopCapturerLacros(DesktopCapturerLacros::CaptureType::kWindow,
webrtc::DesktopCaptureOptions()));
#else
- std::unique_ptr<webrtc::DesktopCapturer> window_capturer =
- webrtc::DesktopCapturer::CreateWindowCapturer(options);
+ std::unique_ptr<webrtc::DesktopCapturer> window_capturer;
+ if (auto generic_capturer =
+ webrtc::DesktopCapturer::CreateGenericCapturer(options);
+ generic_capturer && generic_capturer->GetDelegatedSourceListController()) {
+ window_capturer = std::move(generic_capturer);
+ } else {
+ window_capturer = webrtc::DesktopCapturer::CreateWindowCapturer(options);
+ }
#endif
if (window_capturer && window_capturer->SelectSource(source.id)) {
capturer = std::make_unique<webrtc::DesktopAndCursorComposer>(

View File

@@ -0,0 +1,93 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Adam Rice <ricea@chromium.org>
Date: Tue, 8 Aug 2023 08:48:51 +0000
Subject: NetworkContext: Don't access url_loader_factories_ during destruction
Move the contents of `url_loader_factories_` to a temporary variable in
the destructor of network::NetworkContext so that re-entrant calls to
DestroyURLLoaderFactory() don't happen after it has started being
destroyed.
BUG=1465833
(cherry picked from commit e579b20308290df03f045c5d0ccb852d96b24ce3)
Change-Id: I476f0865256bdcba4ec934688597e69991968f84
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4733351
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Commit-Queue: Adam Rice <ricea@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1177648}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4756334
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Adam Rice <ricea@chromium.org>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5845@{#1252}
Cr-Branched-From: 5a5dff63a4a4c63b9b18589819bebb2566c85443-refs/heads/main@{#1160321}
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 97fa9e6e96fde894feb7da28afca6f65a310199d..d3cda420386ce946568fdc2656308d9c3cf3b610 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -692,6 +692,8 @@ NetworkContext::NetworkContext(
}
NetworkContext::~NetworkContext() {
+ is_destructing_ = true;
+
// May be nullptr in tests.
if (network_service_)
network_service_->DeregisterNetworkContext(this);
@@ -749,6 +751,12 @@ NetworkContext::~NetworkContext() {
}
}
#endif // BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED)
+
+ // Clear `url_loader_factories_` before deleting the contents, as it can
+ // result in re-entrant calls to DestroyURLLoaderFactory().
+ std::set<std::unique_ptr<cors::CorsURLLoaderFactory>,
+ base::UniquePtrComparator>
+ url_loader_factories = std::move(url_loader_factories_);
}
// static
@@ -974,6 +982,9 @@ void NetworkContext::DisableQuic() {
void NetworkContext::DestroyURLLoaderFactory(
cors::CorsURLLoaderFactory* url_loader_factory) {
+ if (is_destructing_) {
+ return;
+ }
auto it = url_loader_factories_.find(url_loader_factory);
DCHECK(it != url_loader_factories_.end());
url_loader_factories_.erase(it);
diff --git a/services/network/network_context.h b/services/network/network_context.h
index 06cd75b4aa3ee7a582fe9a2b2cd288cb61b3c19e..fd3655943b1b1caf8a6db35219f437113163276a 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -915,6 +915,10 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
// according to the spec.
bool acam_preflight_spec_conformant_ = true;
+ // True once the destructor has been called. Used to guard against re-entrant
+ // calls to DestroyURLLoaderFactory().
+ bool is_destructing_ = false;
+
// Indicating whether
// https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name is
// supported.
@@ -923,13 +927,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
// CorsURLLoaderFactory assumes that fields owned by the NetworkContext always
// live longer than the factory. Therefore we want the factories to be
- // destroyed before other fields above. In particular:
- // - This must be below |url_request_context_| so that the URLRequestContext
- // outlives all the URLLoaderFactories and URLLoaders that depend on it;
- // for the same reason, it must also be below |network_context_|.
- // - This must be below |loader_count_per_process_| that is touched by
- // CorsURLLoaderFactory::DestroyURLLoader (see also
- // https://crbug.com/1174943).
+ // destroyed before other fields above. This is accomplished by explicitly
+ // clearing `url_loader_factories_` in the destructor.
std::set<std::unique_ptr<cors::CorsURLLoaderFactory>,
base::UniquePtrComparator>
url_loader_factories_;

View File

@@ -25,5 +25,11 @@
"src/electron/patches/webrtc": "src/third_party/webrtc",
"src/electron/patches/pdfium": "src/third_party/pdfium"
"src/electron/patches/pdfium": "src/third_party/pdfium",
"src/electron/patches/skia": "src/third_party/skia",
"src/electron/patches/libwebp": "src/third_party/libwebp/src",
"src/electron/patches/libvpx": "src/third_party/libvpx/source/libvpx"
}

1
patches/libvpx/.patches Normal file
View File

@@ -0,0 +1 @@
cherry-pick-3fbd1dca6a4d.patch

View File

@@ -0,0 +1,27 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: James Zern <jzern@google.com>
Date: Mon, 25 Sep 2023 18:55:59 -0700
Subject: VP8: disallow thread count changes
Currently allocations are done at encoder creation time. Going from
threaded to non-threaded would cause a crash.
Bug: chromium:1486441
Change-Id: Ie301c2a70847dff2f0daae408fbef1e4d42e73d4
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 4bbeadef013c8e0a1ae8d9241b90489e37ab36d7..148a16cc493d109fee859a9628f58e7361b02e0d 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -1443,6 +1443,11 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) {
last_h = cpi->oxcf.Height;
prev_number_of_layers = cpi->oxcf.number_of_layers;
+ if (cpi->initial_width) {
+ // TODO(https://crbug.com/1486441): Allow changing thread counts; the
+ // allocation is done once in vp8_create_compressor().
+ oxcf->multi_threaded = cpi->oxcf.multi_threaded;
+ }
cpi->oxcf = *oxcf;
switch (cpi->oxcf.Mode) {

1
patches/libwebp/.patches Normal file
View File

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

View File

@@ -0,0 +1,354 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Vincent Rabaud <vrabaud@google.com>
Date: Thu, 7 Sep 2023 21:16:03 +0200
Subject: Fix OOB write in BuildHuffmanTable.
First, BuildHuffmanTable is called to check if the data is valid.
If it is and the table is not big enough, more memory is allocated.
This will make sure that valid (but unoptimized because of unbalanced
codes) streams are still decodable.
Bug: chromium:1479274
Change-Id: I31c36dbf3aa78d35ecf38706b50464fd3d375741
(cherry picked from commit 902bc9190331343b2017211debcec8d2ab87e17a)
(cherry picked from commit 2af26267cdfcb63a88e5c74a85927a12d6ca1d76)
(cherry picked from commit 904941b437ccc2f14de7cd791994f655c3583050)
diff --git a/src/dec/vp8l_dec.c b/src/dec/vp8l_dec.c
index c0ea0181e52e31e8c03d6abe5597f3c50b8e4c09..7995313fa19cafe3b48bb6e3ad6160c8cac407e6 100644
--- a/src/dec/vp8l_dec.c
+++ b/src/dec/vp8l_dec.c
@@ -253,11 +253,11 @@ static int ReadHuffmanCodeLengths(
int symbol;
int max_symbol;
int prev_code_len = DEFAULT_CODE_LENGTH;
- HuffmanCode table[1 << LENGTHS_TABLE_BITS];
+ HuffmanTables tables;
- if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS,
- code_length_code_lengths,
- NUM_CODE_LENGTH_CODES)) {
+ if (!VP8LHuffmanTablesAllocate(1 << LENGTHS_TABLE_BITS, &tables) ||
+ !VP8LBuildHuffmanTable(&tables, LENGTHS_TABLE_BITS,
+ code_length_code_lengths, NUM_CODE_LENGTH_CODES)) {
goto End;
}
@@ -277,7 +277,7 @@ static int ReadHuffmanCodeLengths(
int code_len;
if (max_symbol-- == 0) break;
VP8LFillBitWindow(br);
- p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
+ p = &tables.curr_segment->start[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
VP8LSetBitPos(br, br->bit_pos_ + p->bits);
code_len = p->value;
if (code_len < kCodeLengthLiterals) {
@@ -300,6 +300,7 @@ static int ReadHuffmanCodeLengths(
ok = 1;
End:
+ VP8LHuffmanTablesDeallocate(&tables);
if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
return ok;
}
@@ -307,7 +308,8 @@ static int ReadHuffmanCodeLengths(
// 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
// tree.
static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
- int* const code_lengths, HuffmanCode* const table) {
+ int* const code_lengths,
+ HuffmanTables* const table) {
int ok = 0;
int size = 0;
VP8LBitReader* const br = &dec->br_;
@@ -362,8 +364,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
VP8LMetadata* const hdr = &dec->hdr_;
uint32_t* huffman_image = NULL;
HTreeGroup* htree_groups = NULL;
- HuffmanCode* huffman_tables = NULL;
- HuffmanCode* huffman_table = NULL;
+ HuffmanTables* huffman_tables = &hdr->huffman_tables_;
int num_htree_groups = 1;
int num_htree_groups_max = 1;
int max_alphabet_size = 0;
@@ -372,6 +373,10 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
int* mapping = NULL;
int ok = 0;
+ // Check the table has been 0 initialized (through InitMetadata).
+ assert(huffman_tables->root.start == NULL);
+ assert(huffman_tables->curr_segment == NULL);
+
if (allow_recursion && VP8LReadBits(br, 1)) {
// use meta Huffman codes.
const int huffman_precision = VP8LReadBits(br, 3) + 2;
@@ -434,16 +439,15 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
sizeof(*code_lengths));
- huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
- sizeof(*huffman_tables));
htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
- if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
+ if (htree_groups == NULL || code_lengths == NULL ||
+ !VP8LHuffmanTablesAllocate(num_htree_groups * table_size,
+ huffman_tables)) {
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
goto Error;
}
- huffman_table = huffman_tables;
for (i = 0; i < num_htree_groups_max; ++i) {
// If the index "i" is unused in the Huffman image, just make sure the
// coefficients are valid but do not store them.
@@ -468,19 +472,20 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
int max_bits = 0;
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
int alphabet_size = kAlphabetSize[j];
- htrees[j] = huffman_table;
if (j == 0 && color_cache_bits > 0) {
alphabet_size += (1 << color_cache_bits);
}
- size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table);
+ size =
+ ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables);
+ htrees[j] = huffman_tables->curr_segment->curr_table;
if (size == 0) {
goto Error;
}
if (is_trivial_literal && kLiteralMap[j] == 1) {
- is_trivial_literal = (huffman_table->bits == 0);
+ is_trivial_literal = (htrees[j]->bits == 0);
}
- total_size += huffman_table->bits;
- huffman_table += size;
+ total_size += htrees[j]->bits;
+ huffman_tables->curr_segment->curr_table += size;
if (j <= ALPHA) {
int local_max_bits = code_lengths[0];
int k;
@@ -515,14 +520,13 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
hdr->huffman_image_ = huffman_image;
hdr->num_htree_groups_ = num_htree_groups;
hdr->htree_groups_ = htree_groups;
- hdr->huffman_tables_ = huffman_tables;
Error:
WebPSafeFree(code_lengths);
WebPSafeFree(mapping);
if (!ok) {
WebPSafeFree(huffman_image);
- WebPSafeFree(huffman_tables);
+ VP8LHuffmanTablesDeallocate(huffman_tables);
VP8LHtreeGroupsFree(htree_groups);
}
return ok;
@@ -1358,7 +1362,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
assert(hdr != NULL);
WebPSafeFree(hdr->huffman_image_);
- WebPSafeFree(hdr->huffman_tables_);
+ VP8LHuffmanTablesDeallocate(&hdr->huffman_tables_);
VP8LHtreeGroupsFree(hdr->htree_groups_);
VP8LColorCacheClear(&hdr->color_cache_);
VP8LColorCacheClear(&hdr->saved_color_cache_);
@@ -1673,7 +1677,7 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
if (dec == NULL) return 0;
- assert(dec->hdr_.huffman_tables_ != NULL);
+ assert(dec->hdr_.huffman_tables_.root.start != NULL);
assert(dec->hdr_.htree_groups_ != NULL);
assert(dec->hdr_.num_htree_groups_ > 0);
diff --git a/src/dec/vp8li_dec.h b/src/dec/vp8li_dec.h
index 72b2e861208447f45e5ee12eac57b9c36ff2cd31..32540a4b88a05cc74b88f11da3f143e83be81c9c 100644
--- a/src/dec/vp8li_dec.h
+++ b/src/dec/vp8li_dec.h
@@ -51,7 +51,7 @@ typedef struct {
uint32_t* huffman_image_;
int num_htree_groups_;
HTreeGroup* htree_groups_;
- HuffmanCode* huffman_tables_;
+ HuffmanTables huffman_tables_;
} VP8LMetadata;
typedef struct VP8LDecoder VP8LDecoder;
diff --git a/src/utils/huffman_utils.c b/src/utils/huffman_utils.c
index 90c2fbf7c18c79ccb3597fe7cbbc332dbd1b2548..cf73abd437d02173f43c61c8877a5f467997774a 100644
--- a/src/utils/huffman_utils.c
+++ b/src/utils/huffman_utils.c
@@ -177,21 +177,24 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
if (num_open < 0) {
return 0;
}
- if (root_table == NULL) continue;
for (; count[len] > 0; --count[len]) {
HuffmanCode code;
if ((key & mask) != low) {
- table += table_size;
+ if (root_table != NULL) table += table_size;
table_bits = NextTableBitSize(count, len, root_bits);
table_size = 1 << table_bits;
total_size += table_size;
low = key & mask;
- root_table[low].bits = (uint8_t)(table_bits + root_bits);
- root_table[low].value = (uint16_t)((table - root_table) - low);
+ if (root_table != NULL) {
+ root_table[low].bits = (uint8_t)(table_bits + root_bits);
+ root_table[low].value = (uint16_t)((table - root_table) - low);
+ }
+ }
+ if (root_table != NULL) {
+ code.bits = (uint8_t)(len - root_bits);
+ code.value = (uint16_t)sorted[symbol++];
+ ReplicateValue(&table[key >> root_bits], step, table_size, code);
}
- code.bits = (uint8_t)(len - root_bits);
- code.value = (uint16_t)sorted[symbol++];
- ReplicateValue(&table[key >> root_bits], step, table_size, code);
key = GetNextKey(key, len);
}
}
@@ -211,25 +214,83 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES)
// Cut-off value for switching between heap and stack allocation.
#define SORTED_SIZE_CUTOFF 512
-int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
const int code_lengths[], int code_lengths_size) {
- int total_size;
+ const int total_size =
+ BuildHuffmanTable(NULL, root_bits, code_lengths, code_lengths_size, NULL);
assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);
- if (root_table == NULL) {
- total_size = BuildHuffmanTable(NULL, root_bits,
- code_lengths, code_lengths_size, NULL);
- } else if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
+ if (total_size == 0 || root_table == NULL) return total_size;
+
+ if (root_table->curr_segment->curr_table + total_size >=
+ root_table->curr_segment->start + root_table->curr_segment->size) {
+ // If 'root_table' does not have enough memory, allocate a new segment.
+ // The available part of root_table->curr_segment is left unused because we
+ // need a contiguous buffer.
+ const int segment_size = root_table->curr_segment->size;
+ struct HuffmanTablesSegment* next =
+ (HuffmanTablesSegment*)WebPSafeMalloc(1, sizeof(*next));
+ if (next == NULL) return 0;
+ // Fill the new segment.
+ // We need at least 'total_size' but if that value is small, it is better to
+ // allocate a big chunk to prevent more allocations later. 'segment_size' is
+ // therefore chosen (any other arbitrary value could be chosen).
+ next->size = total_size > segment_size ? total_size : segment_size;
+ next->start =
+ (HuffmanCode*)WebPSafeMalloc(next->size, sizeof(*next->start));
+ if (next->start == NULL) {
+ WebPSafeFree(next);
+ return 0;
+ }
+ next->curr_table = next->start;
+ next->next = NULL;
+ // Point to the new segment.
+ root_table->curr_segment->next = next;
+ root_table->curr_segment = next;
+ }
+ if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
// use local stack-allocated array.
uint16_t sorted[SORTED_SIZE_CUTOFF];
- total_size = BuildHuffmanTable(root_table, root_bits,
- code_lengths, code_lengths_size, sorted);
- } else { // rare case. Use heap allocation.
+ BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
+ code_lengths, code_lengths_size, sorted);
+ } else { // rare case. Use heap allocation.
uint16_t* const sorted =
(uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted));
if (sorted == NULL) return 0;
- total_size = BuildHuffmanTable(root_table, root_bits,
- code_lengths, code_lengths_size, sorted);
+ BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
+ code_lengths, code_lengths_size, sorted);
WebPSafeFree(sorted);
}
return total_size;
}
+
+int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables) {
+ // Have 'segment' point to the first segment for now, 'root'.
+ HuffmanTablesSegment* const root = &huffman_tables->root;
+ huffman_tables->curr_segment = root;
+ // Allocate root.
+ root->start = (HuffmanCode*)WebPSafeMalloc(size, sizeof(*root->start));
+ if (root->start == NULL) return 0;
+ root->curr_table = root->start;
+ root->next = NULL;
+ root->size = size;
+ return 1;
+}
+
+void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables) {
+ HuffmanTablesSegment *current, *next;
+ if (huffman_tables == NULL) return;
+ // Free the root node.
+ current = &huffman_tables->root;
+ next = current->next;
+ WebPSafeFree(current->start);
+ current->start = NULL;
+ current->next = NULL;
+ current = next;
+ // Free the following nodes.
+ while (current != NULL) {
+ next = current->next;
+ WebPSafeFree(current->start);
+ WebPSafeFree(current);
+ current = next;
+ }
+}
diff --git a/src/utils/huffman_utils.h b/src/utils/huffman_utils.h
index 13b7ad1ac40c5316f5506d9b4cbf5039c9fd5600..98415c532895374ea28fc1dc5c9a15c751ea9ba0 100644
--- a/src/utils/huffman_utils.h
+++ b/src/utils/huffman_utils.h
@@ -43,6 +43,29 @@ typedef struct {
// or non-literal symbol otherwise
} HuffmanCode32;
+// Contiguous memory segment of HuffmanCodes.
+typedef struct HuffmanTablesSegment {
+ HuffmanCode* start;
+ // Pointer to where we are writing into the segment. Starts at 'start' and
+ // cannot go beyond 'start' + 'size'.
+ HuffmanCode* curr_table;
+ // Pointer to the next segment in the chain.
+ struct HuffmanTablesSegment* next;
+ int size;
+} HuffmanTablesSegment;
+
+// Chained memory segments of HuffmanCodes.
+typedef struct HuffmanTables {
+ HuffmanTablesSegment root;
+ // Currently processed segment. At first, this is 'root'.
+ HuffmanTablesSegment* curr_segment;
+} HuffmanTables;
+
+// Allocates a HuffmanTables with 'size' contiguous HuffmanCodes. Returns 0 on
+// memory allocation error, 1 otherwise.
+int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables);
+void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables);
+
#define HUFFMAN_PACKED_BITS 6
#define HUFFMAN_PACKED_TABLE_SIZE (1u << HUFFMAN_PACKED_BITS)
@@ -78,9 +101,7 @@ void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups);
// the huffman table.
// Returns built table size or 0 in case of error (invalid tree or
// memory error).
-// If root_table is NULL, it returns 0 if a lookup cannot be built, something
-// > 0 otherwise (but not the table size).
-int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
const int code_lengths[], int code_lengths_size);
#ifdef __cplusplus

View File

@@ -36,3 +36,5 @@ src_allow_optional_isolation_termination_in_node.patch
test_mark_cpu_prof_tests_as_flaky_in_electron.patch
lib_fix_broadcastchannel_initialization_location.patch
intl_revert_date_formatting_behavior_change_from_icu_72.patch
fix_do_not_resolve_electron_entrypoints.patch
fix_assert_module_in_the_renderer_process.patch

View File

@@ -0,0 +1,75 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 16 Aug 2023 19:15:29 +0200
Subject: fix: assert module in the renderer process
When creating a Node.js Environment, embedders have the option to disable Node.js'
default overriding of Error.prepareStackTrace. However, the assert module depends on
a WeakMap that is populated with the error stacktraces in the overridden function.
This adds handling to fall back to the default implementation if Error.prepareStackTrace
if the override has been disabled.
This will be upstreamed.
diff --git a/lib/assert.js b/lib/assert.js
index 82c3a285f51abd1d517e7930887492652628e8c6..f68f22a4737ce395d3ee8a375513cb24ed1e8d2d 100644
--- a/lib/assert.js
+++ b/lib/assert.js
@@ -66,6 +66,7 @@ const { inspect } = require('internal/util/inspect');
const { isPromise, isRegExp } = require('internal/util/types');
const { EOL } = require('internal/constants');
const { BuiltinModule } = require('internal/bootstrap/loaders');
+const { getEmbedderOptions } = require('internal/options');
const { isError } = require('internal/util');
const errorCache = new SafeMap();
@@ -289,8 +290,16 @@ function getErrMessage(message, fn) {
ErrorCaptureStackTrace(err, fn);
if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = tmpLimit;
- overrideStackTrace.set(err, (_, stack) => stack);
- const call = err.stack[0];
+ let call;
+ if (getEmbedderOptions().hasPrepareStackTraceCallback) {
+ overrideStackTrace.set(err, (_, stack) => stack);
+ call = err.stack[0];
+ } else {
+ const tmpPrepare = Error.prepareStackTrace;
+ Error.prepareStackTrace = (_, stack) => stack;
+ call = err.stack[0];
+ Error.prepareStackTrace = tmpPrepare;
+ }
const filename = call.getFileName();
const line = call.getLineNumber() - 1;
diff --git a/src/api/environment.cc b/src/api/environment.cc
index c718b9919bb30627e5da2b92a8de58c494bf4b93..64f8bef214fa4d55114aa9d04c111fcc3033ad10 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -262,6 +262,9 @@ void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s) {
auto* prepare_stack_trace_cb = s.prepare_stack_trace_callback ?
s.prepare_stack_trace_callback : PrepareStackTraceCallback;
isolate->SetPrepareStackTraceCallback(prepare_stack_trace_cb);
+ } else {
+ auto env = Environment::GetCurrent(isolate);
+ env->set_prepare_stack_trace_callback(Local<Function>());
}
}
diff --git a/src/node_options.cc b/src/node_options.cc
index 99f5274aec7512956a5e13a5ca9c0b593a57cc7a..2094efecfb83e80a01d582fde7566f3eed79cd55 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -1186,6 +1186,11 @@ void GetEmbedderOptions(const FunctionCallbackInfo<Value>& args) {
Local<Context> context = env->context();
Local<Object> ret = Object::New(isolate);
+ if (ret->Set(context,
+ FIXED_ONE_BYTE_STRING(env->isolate(), "hasPrepareStackTraceCallback"),
+ Boolean::New(isolate, !env->prepare_stack_trace_callback().IsEmpty()))
+ .IsNothing()) return;
+
if (ret->Set(context,
FIXED_ONE_BYTE_STRING(env->isolate(), "shouldNotRegisterESMLoader"),
Boolean::New(isolate, env->should_not_register_esm_loader()))

View File

@@ -0,0 +1,47 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <marshallofsound@electronjs.org>
Date: Wed, 26 Jul 2023 17:03:15 -0700
Subject: fix: do not resolve electron entrypoints
This wastes fs cycles and can result in strange behavior if this path actually exists on disk
diff --git a/lib/internal/modules/run_main.js b/lib/internal/modules/run_main.js
index 5a50d5d6afab6e6648f72a1c0efa1df4cd80bcd9..ebc9999358ccf16689dc02322eb1aeb86355f39b 100644
--- a/lib/internal/modules/run_main.js
+++ b/lib/internal/modules/run_main.js
@@ -3,6 +3,7 @@
const {
ObjectCreate,
StringPrototypeEndsWith,
+ StringPrototypeStartsWith,
} = primordials;
const CJSLoader = require('internal/modules/cjs/loader');
const { Module, toRealPath, readPackageScope } = CJSLoader;
@@ -13,6 +14,13 @@ const {
} = require('internal/modules/esm/handle_process_exit');
function resolveMainPath(main) {
+ // For built-in modules used as the main entry point we _never_
+ // want to waste cycles resolving them to file paths on disk
+ // that actually might exist
+ if (typeof main === 'string' && StringPrototypeStartsWith(main, 'electron/js2c')) {
+ return main;
+ }
+
// Note extension resolution for the main entry point can be deprecated in a
// future major.
// Module._findPath is monkey-patchable here.
@@ -28,6 +36,13 @@ function resolveMainPath(main) {
}
function shouldUseESMLoader(mainPath) {
+ // For built-in modules used as the main entry point we _never_
+ // want to waste cycles resolving them to file paths on disk
+ // that actually might exist
+ if (typeof mainPath === 'string' && StringPrototypeStartsWith(mainPath, 'electron/js2c')) {
+ return false;
+ }
+
/**
* @type {string[]} userLoaders A list of custom loaders registered by the user
* (or an empty list when none have been registered).

1
patches/skia/.patches Normal file
View File

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

View File

@@ -0,0 +1,118 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: John Stiles <johnstiles@google.com>
Date: Thu, 3 Aug 2023 13:33:52 -0400
Subject: Enforce an upper limit of 715 million path verbs in SkPath.
Bug: chromium:1464215
Change-Id: Iedb7d73fc80de5ffb881b664dd77314cc2c6b108
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/735316
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
diff --git a/relnotes/path_715M.md b/relnotes/path_715M.md
new file mode 100644
index 0000000000000000000000000000000000000000..7be9a40f1fc5b4f6432c490725b05d536d497fb1
--- /dev/null
+++ b/relnotes/path_715M.md
@@ -0,0 +1 @@
+SkPath now enforces an upper limit of 715 million path verbs.
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 6cc1e2ef1b49b18aa6692dba655ef5ca83610b0d..976edee87e763a1f44396902d4f641ed3da8e452 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -34,6 +34,7 @@
#include <cmath>
#include <cstring>
#include <iterator>
+#include <limits.h>
#include <utility>
struct SkPath_Storage_Equivalent {
@@ -3421,43 +3422,52 @@ bool SkPath::IsCubicDegenerate(const SkPoint& p1, const SkPoint& p2,
SkPathVerbAnalysis sk_path_analyze_verbs(const uint8_t vbs[], int verbCount) {
SkPathVerbAnalysis info = {false, 0, 0, 0};
-
bool needMove = true;
bool invalid = false;
- for (int i = 0; i < verbCount; ++i) {
- switch ((SkPathVerb)vbs[i]) {
- case SkPathVerb::kMove:
- needMove = false;
- info.points += 1;
- break;
- case SkPathVerb::kLine:
- invalid |= needMove;
- info.segmentMask |= kLine_SkPathSegmentMask;
- info.points += 1;
- break;
- case SkPathVerb::kQuad:
- invalid |= needMove;
- info.segmentMask |= kQuad_SkPathSegmentMask;
- info.points += 2;
- break;
- case SkPathVerb::kConic:
- invalid |= needMove;
- info.segmentMask |= kConic_SkPathSegmentMask;
- info.points += 2;
- info.weights += 1;
- break;
- case SkPathVerb::kCubic:
- invalid |= needMove;
- info.segmentMask |= kCubic_SkPathSegmentMask;
- info.points += 3;
- break;
- case SkPathVerb::kClose:
- invalid |= needMove;
- needMove = true;
- break;
- default:
- invalid = true;
- break;
+
+ if (verbCount >= (INT_MAX / 3)) {
+ // A path with an extremely high number of quad, conic or cubic verbs could cause
+ // `info.points` to overflow. To prevent against this, we reject extremely large paths. This
+ // check is conservative and assumes the worst case (in particular, it assumes that every
+ // verb consumes 3 points, which would only happen for a path composed entirely of cubics).
+ // This limits us to 700 million verbs, which is large enough for any reasonable use case.
+ invalid = true;
+ } else {
+ for (int i = 0; i < verbCount; ++i) {
+ switch ((SkPathVerb)vbs[i]) {
+ case SkPathVerb::kMove:
+ needMove = false;
+ info.points += 1;
+ break;
+ case SkPathVerb::kLine:
+ invalid |= needMove;
+ info.segmentMask |= kLine_SkPathSegmentMask;
+ info.points += 1;
+ break;
+ case SkPathVerb::kQuad:
+ invalid |= needMove;
+ info.segmentMask |= kQuad_SkPathSegmentMask;
+ info.points += 2;
+ break;
+ case SkPathVerb::kConic:
+ invalid |= needMove;
+ info.segmentMask |= kConic_SkPathSegmentMask;
+ info.points += 2;
+ info.weights += 1;
+ break;
+ case SkPathVerb::kCubic:
+ invalid |= needMove;
+ info.segmentMask |= kCubic_SkPathSegmentMask;
+ info.points += 3;
+ break;
+ case SkPathVerb::kClose:
+ invalid |= needMove;
+ needMove = true;
+ break;
+ default:
+ invalid = true;
+ break;
+ }
}
}
info.valid = !invalid;

View File

@@ -13,3 +13,10 @@ cherry-pick-3b0607d14060.patch
cherry-pick-9c6dfc733fce.patch
cherry-pick-73af1a19a901.patch
cherry-pick-0035a4a8dac2.patch
cherry-pick-2e76270cf65e.patch
merged_runtime_set_instance_prototypes_directly_on_maps.patch
merged_compiler_stackcheck_can_have_side_effects.patch
cherry-pick-8ff63d378f2c.patch
cherry-pick-d671b099a57d.patch
merged_squashed_multiple_commits.patch
cherry-pick-038530c94a06.patch

View File

@@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tobias Tebbi <tebbi@chromium.org>
Date: Wed, 30 Aug 2023 10:59:48 +0200
Subject: Merged: [turbofan] Growing a non-JSArray packed elements kind makes
it holey
Bug: chromium:1473247
(cherry picked from commit ae7dc61652805bc8e2b060d53b2b6da7cf846b6f)
Change-Id: I5268513bc91ca0cc18e3e2115244c0b090afa0da
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4831892
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Owners-Override: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
Reviewed-by: Darius Mercadier <dmercadier@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.6@{#34}
Cr-Branched-From: e29c028f391389a7a60ee37097e3ca9e396d6fa4-refs/heads/11.6.189@{#3}
Cr-Branched-From: 95cbef20e2aa556a1ea75431a48b36c4de6b9934-refs/heads/main@{#88340}
diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc
index b6336828e564902923acefb789dc852aa56b8419..c2f9a4e0d1d2f8f1421ca17ee2c120e16fd09da5 100644
--- a/src/compiler/js-native-context-specialization.cc
+++ b/src/compiler/js-native-context-specialization.cc
@@ -3423,15 +3423,21 @@ JSNativeContextSpecialization::BuildElementAccess(
// the (potential) backing store growth would normalize and thus
// the elements kind of the {receiver} would change to slow mode.
//
- // For PACKED_*_ELEMENTS the {index} must be within the range
+ // For JSArray PACKED_*_ELEMENTS the {index} must be within the range
// [0,length+1[ to be valid. In case {index} equals {length},
// the {receiver} will be extended, but kept packed.
+ //
+ // Non-JSArray PACKED_*_ELEMENTS always grow by adding holes because they
+ // lack the magical length property, which requires a map transition.
+ // So we can assume that this did not happen if we did not see this map.
Node* limit =
IsHoleyElementsKind(elements_kind)
? graph()->NewNode(simplified()->NumberAdd(), elements_length,
jsgraph()->Constant(JSObject::kMaxGap))
- : graph()->NewNode(simplified()->NumberAdd(), length,
- jsgraph()->OneConstant());
+ : receiver_is_jsarray
+ ? graph()->NewNode(simplified()->NumberAdd(), length,
+ jsgraph()->OneConstant())
+ : elements_length;
index = effect = graph()->NewNode(
simplified()->CheckBounds(
FeedbackSource(), CheckBoundsFlag::kConvertStringAndMinusZero),

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shu-yu Guo <syg@chromium.org>
Date: Mon, 5 Jun 2023 16:05:52 -0700
Subject: Merged: Check for encoding when appending in string builder
Fixed: chromium:1450114
(cherry picked from commit a7e2bef27b72f187a7dcdf95714df686f56d9e0b)
Change-Id: I5838383b6b12d137e84c8a36863ef88000e85c76
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4604652
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#41}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/strings/string-builder.cc b/src/strings/string-builder.cc
index f6871d9e6aa33942ec595e3076f689c2008989d7..30540b6a32a006fa4417d612a1243f18f59d3c2e 100644
--- a/src/strings/string-builder.cc
+++ b/src/strings/string-builder.cc
@@ -317,12 +317,21 @@ bool IncrementalStringBuilder::CanAppendByCopy(Handle<String> string) {
void IncrementalStringBuilder::AppendStringByCopy(Handle<String> string) {
DCHECK(CanAppendByCopy(string));
- Handle<SeqOneByteString> part =
- Handle<SeqOneByteString>::cast(current_part());
{
DisallowGarbageCollection no_gc;
- String::WriteToFlat(*string, part->GetChars(no_gc) + current_index_, 0,
- string->length());
+ if (encoding_ == String::ONE_BYTE_ENCODING) {
+ String::WriteToFlat(
+ *string,
+ Handle<SeqOneByteString>::cast(current_part())->GetChars(no_gc) +
+ current_index_,
+ 0, string->length());
+ } else {
+ String::WriteToFlat(
+ *string,
+ Handle<SeqTwoByteString>::cast(current_part())->GetChars(no_gc) +
+ current_index_,
+ 0, string->length());
+ }
}
current_index_ += string->length();
DCHECK(current_index_ <= part_length_);

View File

@@ -0,0 +1,126 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shu-yu Guo <syg@chromium.org>
Date: Wed, 2 Aug 2023 17:41:03 -0700
Subject: Merged: [builtins] Clear FixedArray slot in Promise builtins
Fixed: chromium:1468943
(cherry picked from commit a84849ed718932b94dc877bb44a2d38eb8a0aef9)
Change-Id: Ia2b181c373c15bd1840e2a1572c0e930cddcd788
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4753495
Commit-Queue: Adam Klein <adamk@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Auto-Submit: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.6@{#28}
Cr-Branched-From: e29c028f391389a7a60ee37097e3ca9e396d6fa4-refs/heads/11.6.189@{#3}
Cr-Branched-From: 95cbef20e2aa556a1ea75431a48b36c4de6b9934-refs/heads/main@{#88340}
diff --git a/src/builtins/promise-all-element-closure.tq b/src/builtins/promise-all-element-closure.tq
index db3fb0134cf5bf0065174153171ef44a726a6fff..036e3c7b7473eae98f39a6da4472e826420086c8 100644
--- a/src/builtins/promise-all-element-closure.tq
+++ b/src/builtins/promise-all-element-closure.tq
@@ -175,11 +175,22 @@ transitioning macro PromiseAllResolveElementClosure<F: type>(
*NativeContextSlot(
nativeContext, ContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX);
- // If resolve and reject handlers close over values to keep track of whether
- // an input promise is already settled, mark the values array as COW before
- // letting it escape to user code.
- if (hasResolveAndRejectClosures) MakeFixedArrayCOW(values);
-
+ // After this point, values escapes to user code.
+ //
+ // If resolve and reject handlers close over values to keep track of
+ // whether an input promise is already settled, mark the values array as
+ // COW. The original values array is still needed to guard against resolve
+ // or reject being called multiple times for an element.
+ //
+ // Otherwise, clear the slot.
+ if (hasResolveAndRejectClosures) {
+ MakeFixedArrayCOW(values);
+ } else {
+ *ContextSlot(
+ promiseContext,
+ PromiseAllResolveElementContextSlots::
+ kPromiseAllResolveElementValuesSlot) = kEmptyFixedArray;
+ }
const valuesArray = NewJSArray(arrayMap, values);
Call(promiseContext, resolve, Undefined, valuesArray);
}
diff --git a/src/builtins/promise-all.tq b/src/builtins/promise-all.tq
index 4d131abb44b7593d3e361d1d2f971380ee91850c..7205279526fa9edd93f154feb9694c22cae68606 100644
--- a/src/builtins/promise-all.tq
+++ b/src/builtins/promise-all.tq
@@ -278,15 +278,16 @@ Reject(JSAny) {
check(remainingElementsCount >= 0);
+ const valuesRef:&FixedArray = ContextSlot(
+ resolveElementContext,
+ PromiseAllResolveElementContextSlots::
+ kPromiseAllResolveElementValuesSlot);
+ const values = *valuesRef;
+
if (remainingElementsCount > 0) {
// Pre-allocate the backing store for the {values} to the desired
// capacity. We may already have elements in "values" - this happens
// when the Thenable calls the resolve callback immediately.
- const valuesRef:&FixedArray = ContextSlot(
- resolveElementContext,
- PromiseAllResolveElementContextSlots::
- kPromiseAllResolveElementValuesSlot);
- const values = *valuesRef;
// 'index' is a 1-based index and incremented after every Promise. Later we
// use 'values' as a 0-based array, so capacity 'index - 1' is enough.
const newCapacity = SmiUntag(index) - 1;
@@ -301,19 +302,23 @@ Reject(JSAny) {
// Let valuesArray be CreateArrayFromList(values).
// Perform ? Call(resultCapability.[[Resolve]], undefined,
// « valuesArray »).
-
- const values: FixedArray = *ContextSlot(
- resolveElementContext,
- PromiseAllResolveElementContextSlots::
- kPromiseAllResolveElementValuesSlot);
const arrayMap =
*NativeContextSlot(
nativeContext, ContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX);
+ // After this point, values escapes to user code.
+ //
// If resolve and reject handlers close over values to keep track of
// whether an input promise is already settled, mark the values array as
- // COW before letting it escape to user code.
- if (hasResolveAndRejectClosures) MakeFixedArrayCOW(values);
+ // COW. The original values array is still needed to guard against resolve
+ // or reject being called multiple times for an element.
+ //
+ // Otherwise, clear the slot.
+ if (hasResolveAndRejectClosures) {
+ MakeFixedArrayCOW(values);
+ } else {
+ *valuesRef = kEmptyFixedArray;
+ }
const valuesArray = NewJSArray(arrayMap, values);
Call(nativeContext, UnsafeCast<JSAny>(resolve), Undefined, valuesArray);
diff --git a/src/builtins/promise-any.tq b/src/builtins/promise-any.tq
index 7e707e649f11bc946a6d1173180d7293fe94d8ce..45bafac0e6b09143b69b21a7292f9ed6b9c46239 100644
--- a/src/builtins/promise-any.tq
+++ b/src/builtins/promise-any.tq
@@ -313,10 +313,14 @@ Reject(JSAny) {
// We may already have elements in "errors" - this happens when the
// Thenable calls the reject callback immediately.
- const errors: FixedArray = *ContextSlot(
+ const errorsRef:&FixedArray = ContextSlot(
rejectElementContext,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementErrorsSlot);
+ const errors: FixedArray = *errorsRef;
+
+ // After this point, errors escapes to user code. Clear the slot.
+ *errorsRef = kEmptyFixedArray;
check(errors.length == index - 1);
const error = ConstructAggregateError(errors);

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tobias Tebbi <tebbi@chromium.org>
Date: Tue, 13 Jun 2023 11:50:11 +0200
Subject: Merged: [compiler] check for read-only property on
AccessMode::kDefine
(cherry picked from commit 95eda07ddbc1839e39b3d1ff5db329c0ceb6dfaa)
Change-Id: Ic5799a32e7c312e41cd0a7e1e6073a235414d56f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4665588
Auto-Submit: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Darius Mercadier <dmercadier@chromium.org>
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#53}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc
index 3120077a7710264926b9f9cce348cc3f7c0ac858..fc1bfcf2cd6c24ca9ddf8a95ef6a48b087ed3fde 100644
--- a/src/compiler/access-info.cc
+++ b/src/compiler/access-info.cc
@@ -749,8 +749,7 @@ PropertyAccessInfo AccessInfoFactory::ComputePropertyAccessInfo(
}
if (index.is_found()) {
- if (access_mode == AccessMode::kStore ||
- access_mode == AccessMode::kStoreInLiteral) {
+ if (IsAnyStore(access_mode)) {
DCHECK(!map.is_dictionary_map());
// Don't bother optimizing stores to read-only properties.

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tobias Tebbi <tebbi@chromium.org>
Date: Tue, 13 Jun 2023 17:08:59 +0200
Subject: Merged: [compiler] StackCheck can have side effects
Bug: chromium:1452137
(cherry picked from commit e548943e473b020fdc1de6e5543ca31b24d8b7f9)
Change-Id: Ibd7c9b02efd12341b452e4c34a635a58a817649f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4637129
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Auto-Submit: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#49}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/compiler/js-operator.cc b/src/compiler/js-operator.cc
index 1728f91280bf9e6a3cf173fe399a8b68bd64cad3..abdd45a16e9f207c8d9012cfb434e816218bbf7c 100644
--- a/src/compiler/js-operator.cc
+++ b/src/compiler/js-operator.cc
@@ -1400,7 +1400,7 @@ const Operator* JSOperatorBuilder::CloneObject(FeedbackSource const& feedback,
const Operator* JSOperatorBuilder::StackCheck(StackCheckKind kind) {
return zone()->New<Operator1<StackCheckKind>>( // --
IrOpcode::kJSStackCheck, // opcode
- Operator::kNoWrite, // properties
+ Operator::kNoProperties, // properties
"JSStackCheck", // name
0, 1, 1, 0, 1, 2, // counts
kind); // parameter

View File

@@ -0,0 +1,44 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Toon Verwaest <verwaest@chromium.org>
Date: Fri, 16 Jun 2023 17:13:52 +0200
Subject: Merged: [runtime] Set instance prototypes directly on maps
Bug: chromium:1452137
(cherry picked from commit c7c447735f762f6d6d0878e229371797845ef4ab)
Change-Id: I611c41f942e2e51f3c4b4f1d119c18410617188e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4637888
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Auto-Submit: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#47}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/objects/js-function.cc b/src/objects/js-function.cc
index 6f9b2f676ac5d3f91589a78344b27765dc8bef06..d50743b1c73ad3304c5c5c22a4e0589cca302502 100644
--- a/src/objects/js-function.cc
+++ b/src/objects/js-function.cc
@@ -676,6 +676,10 @@ void SetInstancePrototype(Isolate* isolate, Handle<JSFunction> function,
// At that point, a new initial map is created and the prototype is put
// into the initial map where it belongs.
function->set_prototype_or_initial_map(*value, kReleaseStore);
+ if (value->IsJSObjectThatCanBeTrackedAsPrototype()) {
+ // Optimize as prototype to detach it from its transition tree.
+ JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
+ }
} else {
Handle<Map> new_map =
Map::Copy(isolate, initial_map, "SetInstancePrototype");
@@ -801,8 +805,10 @@ void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
Handle<HeapObject> prototype;
if (function->has_instance_prototype()) {
prototype = handle(function->instance_prototype(), isolate);
+ map->set_prototype(*prototype);
} else {
prototype = isolate->factory()->NewFunctionPrototype(function);
+ Map::SetPrototype(isolate, map, prototype);
}
DCHECK(map->has_fast_object_elements());

View File

@@ -0,0 +1,51 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Samuel=20Gro=C3=9F?= <saelo@chromium.org>
Date: Thu, 17 Aug 2023 09:10:19 +0000
Subject: Merged: Squashed multiple commits.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Merged: [runtime] Recreate enum cache on map update
Revision: 1c623f9ff6e077be1c66f155485ea4005ddb6574
Merged: [runtime] Don't try to create empty enum cache.
Revision: 5516e06237c9f0013121f47319e8c253c896d52d
BUG=chromium:1470668,chromium:1472317
R=tebbi@chromium.org
Change-Id: I31d5491aba663661ba68bb55631747a195ed084e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4788990
Commit-Queue: Samuel Groß <saelo@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.6@{#32}
Cr-Branched-From: e29c028f391389a7a60ee37097e3ca9e396d6fa4-refs/heads/11.6.189@{#3}
Cr-Branched-From: 95cbef20e2aa556a1ea75431a48b36c4de6b9934-refs/heads/main@{#88340}
diff --git a/src/objects/map-updater.cc b/src/objects/map-updater.cc
index be6568aac4730d08601e883b80092bbd6ee8081a..2ebfc84d3e326abf2602a1af8309024a46cb9c9d 100644
--- a/src/objects/map-updater.cc
+++ b/src/objects/map-updater.cc
@@ -11,6 +11,7 @@
#include "src/execution/isolate.h"
#include "src/handles/handles.h"
#include "src/objects/field-type.h"
+#include "src/objects/keys.h"
#include "src/objects/objects-inl.h"
#include "src/objects/objects.h"
#include "src/objects/property-details.h"
@@ -1035,6 +1036,13 @@ MapUpdater::State MapUpdater::ConstructNewMap() {
// the new descriptors to maintain descriptors sharing invariant.
split_map->ReplaceDescriptors(isolate_, *new_descriptors);
+ // If the old descriptors had an enum cache, make sure the new ones do too.
+ if (old_descriptors_->enum_cache().keys().length() > 0 &&
+ new_map->NumberOfEnumerableProperties() > 0) {
+ FastKeyAccumulator::InitializeFastPropertyEnumCache(
+ isolate_, new_map, new_map->NumberOfEnumerableProperties());
+ }
+
if (has_integrity_level_transition_) {
target_map_ = new_map;
state_ = kAtIntegrityLevelSource;

View File

@@ -1 +1,6 @@
fix_fallback_to_x11_capturer_on_wayland.patch
m114_move_transceiver_iteration_loop_over_to_the_signaling_thread.patch
m114_sdp_reject_duplicate_ssrcs_in_ssrc-groups.patch
pipewire_capturer_fix_fcntl_call_when_duplicating_a_file_descriptor.patch
pipewire_capturer_increase_buffer_size_to_avoid_buffer_overflow.patch
desktop_capture_introduce_capturer_requesting_both_screen_and.patch

View File

@@ -0,0 +1,102 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jan Grulich <grulja@gmail.com>
Date: Wed, 12 Jul 2023 13:15:40 +0200
Subject: Desktop capture: introduce capturer requesting both screen and
windows
When PipeWire and xdg-desktop-portals are used, we can actually combine
both source types into one request. Make this part of the API for those
who want to use it this way, e.g. Firefox or Electron, otherwise they
will end up making two simultaneous requests, resulting into two dialogs
at the same time asking, while they can be combined into just one.
Bug: webrtc:15363
Change-Id: Ib6e1e47f66cb01d5c65096aec378b44c3af5f387
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/311549
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
Commit-Queue: Jan Grulich <grulja@gmail.com>
Cr-Commit-Position: refs/heads/main@{#40425}
diff --git a/modules/desktop_capture/desktop_capture_types.h b/modules/desktop_capture/desktop_capture_types.h
index 9627076eea3d1272f87b773ada86be6051f1e224..a4e3e897fde1d3c7bb470449448f30ff6e50caea 100644
--- a/modules/desktop_capture/desktop_capture_types.h
+++ b/modules/desktop_capture/desktop_capture_types.h
@@ -15,7 +15,7 @@
namespace webrtc {
-enum class CaptureType { kWindow, kScreen };
+enum class CaptureType { kWindow, kScreen, kAnyScreenContent };
// Type used to identify windows on the desktop. Values are platform-specific:
// - On Windows: HWND cast to intptr_t.
diff --git a/modules/desktop_capture/desktop_capturer.cc b/modules/desktop_capture/desktop_capturer.cc
index 5211f1acecaba963e1436c1d04aa953853c79eb7..b99f5ecb803ac0ac0e26fbdb3411c77605f33011 100644
--- a/modules/desktop_capture/desktop_capturer.cc
+++ b/modules/desktop_capture/desktop_capturer.cc
@@ -26,6 +26,10 @@
#include "rtc_base/win/windows_version.h"
#endif // defined(RTC_ENABLE_WIN_WGC)
+#if defined(WEBRTC_USE_PIPEWIRE)
+#include "modules/desktop_capture/linux/wayland/base_capturer_pipewire.h"
+#endif
+
namespace webrtc {
void LogDesktopCapturerFullscreenDetectorUsage() {
@@ -101,6 +105,25 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateScreenCapturer(
return capturer;
}
+// static
+std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateGenericCapturer(
+ const DesktopCaptureOptions& options) {
+ std::unique_ptr<DesktopCapturer> capturer;
+
+#if defined(WEBRTC_USE_PIPEWIRE)
+ if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) {
+ capturer = std::make_unique<BaseCapturerPipeWire>(
+ options, CaptureType::kAnyScreenContent);
+ }
+
+ if (capturer && options.detect_updated_region()) {
+ capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer)));
+ }
+#endif // defined(WEBRTC_USE_PIPEWIRE)
+
+ return capturer;
+}
+
#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11)
bool DesktopCapturer::IsRunningUnderWayland() {
const char* xdg_session_type = getenv("XDG_SESSION_TYPE");
diff --git a/modules/desktop_capture/desktop_capturer.h b/modules/desktop_capture/desktop_capturer.h
index fd884f13ff771de2d5ea8b79ba530e9d3b03e913..9c7ecc78f46ea2e2c173416132318f0526714265 100644
--- a/modules/desktop_capture/desktop_capturer.h
+++ b/modules/desktop_capture/desktop_capturer.h
@@ -186,6 +186,11 @@ class RTC_EXPORT DesktopCapturer {
static std::unique_ptr<DesktopCapturer> CreateScreenCapturer(
const DesktopCaptureOptions& options);
+ // Creates a DesktopCapturer instance which targets to capture windows and
+ // screens.
+ static std::unique_ptr<DesktopCapturer> CreateGenericCapturer(
+ const DesktopCaptureOptions& options);
+
#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11)
static bool IsRunningUnderWayland();
diff --git a/modules/desktop_capture/linux/wayland/screencast_portal.cc b/modules/desktop_capture/linux/wayland/screencast_portal.cc
index 52788524c88f8699afda54dcf5d3972618d595a3..8d9e956779e0d9826652c6c97485c8107cb4ad3b 100644
--- a/modules/desktop_capture/linux/wayland/screencast_portal.cc
+++ b/modules/desktop_capture/linux/wayland/screencast_portal.cc
@@ -41,6 +41,8 @@ ScreenCastPortal::CaptureSourceType ScreenCastPortal::ToCaptureSourceType(
return ScreenCastPortal::CaptureSourceType::kScreen;
case CaptureType::kWindow:
return ScreenCastPortal::CaptureSourceType::kWindow;
+ case CaptureType::kAnyScreenContent:
+ return ScreenCastPortal::CaptureSourceType::kAnyScreenContent;
}
}

View File

@@ -0,0 +1,126 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tommi <tommi@webrtc.org>
Date: Thu, 1 Jun 2023 16:08:52 +0200
Subject: Move transceiver iteration loop over to the signaling thread.
This is required for ReportTransportStats since iterating over the
transceiver list from the network thread is not safe.
(cherry picked from commit dba22d31909298161318e00d43a80cdb0abc940f)
No-Try: true
Bug: chromium:1446274, webrtc:12692
Change-Id: I7c514df9f029112c4b1da85826af91217850fb26
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/307340
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Original-Commit-Position: refs/heads/main@{#40197}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/308001
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/branch-heads/5735@{#3}
Cr-Branched-From: df7df199abd619e75b9f1d9a7e12fc3f3f748775-refs/heads/main@{#39949}
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 88b99bb515325b9c616b7d06495c7a9c924133b2..5701504e7a6ebd96bd5cafdbe37de4a510f6a436 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -728,9 +728,6 @@ JsepTransportController* PeerConnection::InitializeTransportController_n(
transport_controller_->SubscribeIceConnectionState(
[this](cricket::IceConnectionState s) {
RTC_DCHECK_RUN_ON(network_thread());
- if (s == cricket::kIceConnectionConnected) {
- ReportTransportStats();
- }
signaling_thread()->PostTask(
SafeTask(signaling_thread_safety_.flag(), [this, s]() {
RTC_DCHECK_RUN_ON(signaling_thread());
@@ -2415,6 +2412,20 @@ void PeerConnection::OnTransportControllerConnectionState(
case cricket::kIceConnectionConnected:
RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
"all transports are writable.";
+ {
+ std::vector<RtpTransceiverProxyRefPtr> transceivers;
+ if (ConfiguredForMedia()) {
+ transceivers = rtp_manager()->transceivers()->List();
+ }
+
+ network_thread()->PostTask(
+ SafeTask(network_thread_safety_,
+ [this, transceivers = std::move(transceivers)] {
+ RTC_DCHECK_RUN_ON(network_thread());
+ ReportTransportStats(std::move(transceivers));
+ }));
+ }
+
SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
break;
@@ -2762,20 +2773,18 @@ void PeerConnection::OnTransportControllerGatheringState(
}
// Runs on network_thread().
-void PeerConnection::ReportTransportStats() {
+void PeerConnection::ReportTransportStats(
+ std::vector<RtpTransceiverProxyRefPtr> transceivers) {
TRACE_EVENT0("webrtc", "PeerConnection::ReportTransportStats");
rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
std::map<std::string, std::set<cricket::MediaType>>
media_types_by_transport_name;
- if (ConfiguredForMedia()) {
- for (const auto& transceiver :
- rtp_manager()->transceivers()->UnsafeList()) {
- if (transceiver->internal()->channel()) {
- std::string transport_name(
- transceiver->internal()->channel()->transport_name());
- media_types_by_transport_name[transport_name].insert(
- transceiver->media_type());
- }
+ for (const auto& transceiver : transceivers) {
+ if (transceiver->internal()->channel()) {
+ std::string transport_name(
+ transceiver->internal()->channel()->transport_name());
+ media_types_by_transport_name[transport_name].insert(
+ transceiver->media_type());
}
}
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index 850142b9584a9f2e5b29b337b2bcd433d4b0224d..69b2ca7925eceb636aa4d22b9397cb25a7637051 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -569,7 +569,8 @@ class PeerConnection : public PeerConnectionInternal,
// Invoked when TransportController connection completion is signaled.
// Reports stats for all transports in use.
- void ReportTransportStats() RTC_RUN_ON(network_thread());
+ void ReportTransportStats(std::vector<RtpTransceiverProxyRefPtr> transceivers)
+ RTC_RUN_ON(network_thread());
// Gather the usage of IPv4/IPv6 as best connection.
static void ReportBestConnectionState(const cricket::TransportStats& stats);
diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc
index 1d1bec3e93e0e87bb0b1da13c13ed11712ad0480..c373e2f643b33dea4e619e38dfc8d1007f2cedad 100644
--- a/pc/peer_connection_integrationtest.cc
+++ b/pc/peer_connection_integrationtest.cc
@@ -1831,6 +1831,10 @@ TEST_P(PeerConnectionIntegrationTest,
EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
callee()->ice_connection_state(), kDefaultTimeout);
+ // Part of reporting the stats will occur on the network thread, so flush it
+ // before checking NumEvents.
+ SendTask(network_thread(), [] {});
+
EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
"WebRTC.PeerConnection.CandidatePairType_UDP",
webrtc::kIceCandidatePairHostNameHostName));
@@ -1959,6 +1963,10 @@ TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
callee()->ice_connection_state(), kDefaultTimeout);
+ // Part of reporting the stats will occur on the network thread, so flush it
+ // before checking NumEvents.
+ SendTask(network_thread(), [] {});
+
// TODO(bugs.webrtc.org/9456): Fix it.
const int num_best_ipv4 = webrtc::metrics::NumEvents(
"WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);

View File

@@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Philipp Hancke <phancke@microsoft.com>
Date: Thu, 15 Jun 2023 07:21:56 +0200
Subject: sdp: reject duplicate ssrcs in ssrc-groups
while not really covered by
https://www.rfc-editor.org/rfc/rfc5576.html#section-4.2
and using the same SSRC for RTX and primary payload may work
since payload type demuxing *could* be used is not a good idea.
This also applies to flexfec's FEC-FR.
For the nonstandard SIM ssrc-group duplicates make no sense.
This rejects duplicates for unknown ssrc-groups as well.
BUG=chromium:1454860
(cherry picked from commit 6a38a3eb38f732b89ca0d8e36c43a434670c4ef5)
No-Try: true
Change-Id: I3e86101dbd5d6c4099f2fdb7b4a52d5cd0809c5f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/308820
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Philipp Hancke <phancke@microsoft.com>
Cr-Original-Commit-Position: refs/heads/main@{#40292}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/309601
Cr-Commit-Position: refs/branch-heads/5735@{#4}
Cr-Branched-From: df7df199abd619e75b9f1d9a7e12fc3f3f748775-refs/heads/main@{#39949}
diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc
index 6d041ff0a1c8ce731a0e4fc20731129663924374..4beb6b0faa0eb78a794cd91507fb476821e94b7c 100644
--- a/pc/webrtc_sdp.cc
+++ b/pc/webrtc_sdp.cc
@@ -3542,6 +3542,11 @@ bool ParseSsrcGroupAttribute(absl::string_view line,
if (!GetValueFromString(line, fields[i], &ssrc, error)) {
return false;
}
+ // Reject duplicates. While not forbidden by RFC 5576,
+ // they don't make sense.
+ if (absl::c_linear_search(ssrcs, ssrc)) {
+ return ParseFailed(line, "Duplicate SSRC in ssrc-group", error);
+ }
ssrcs.push_back(ssrc);
}
ssrc_groups->push_back(SsrcGroup(semantics, ssrcs));
diff --git a/pc/webrtc_sdp_unittest.cc b/pc/webrtc_sdp_unittest.cc
index 37464425c6d88a097140d04fa0a44af5410a64b5..d6a851a2974c348200bf8347aaa16b585f4b9fab 100644
--- a/pc/webrtc_sdp_unittest.cc
+++ b/pc/webrtc_sdp_unittest.cc
@@ -5058,3 +5058,29 @@ TEST_F(WebRtcSdpTest, RejectSessionLevelMediaLevelExtmapMixedUsage) {
JsepSessionDescription jdesc(kDummyType);
EXPECT_FALSE(SdpDeserialize(sdp, &jdesc));
}
+
+TEST_F(WebRtcSdpTest, RejectDuplicateSsrcInSsrcGroup) {
+ std::string sdp =
+ "v=0\r\n"
+ "o=- 0 3 IN IP4 127.0.0.1\r\n"
+ "s=-\r\n"
+ "t=0 0\r\n"
+ "a=group:BUNDLE 0\r\n"
+ "a=fingerprint:sha-1 "
+ "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n"
+ "a=setup:actpass\r\n"
+ "a=ice-ufrag:ETEn\r\n"
+ "a=ice-pwd:OtSK0WpNtpUjkY4+86js7Z/l\r\n"
+ "m=video 9 UDP/TLS/RTP/SAVPF 96 97\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=rtcp-mux\r\n"
+ "a=sendonly\r\n"
+ "a=mid:0\r\n"
+ "a=rtpmap:96 VP8/90000\r\n"
+ "a=rtpmap:97 rtx/90000\r\n"
+ "a=fmtp:97 apt=96\r\n"
+ "a=ssrc-group:FID 1234 1234\r\n"
+ "a=ssrc:1234 cname:test\r\n";
+ JsepSessionDescription jdesc(kDummyType);
+ EXPECT_FALSE(SdpDeserialize(sdp, &jdesc));
+}

View File

@@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jan Grulich <grulja@gmail.com>
Date: Fri, 12 May 2023 20:59:06 +0200
Subject: PipeWire capturer: fix fcntl call when duplicating a file descriptor
The fcntl() call has variable arguments, therefore we need to pass 0 to
specify there are no other arguments for this call, otherwise we might
end up with an argument that is random garbage.
Bug: webrtc:15174
Change-Id: I34f16a942d80913b667d8ade7eed557b0233be01
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/305120
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
Commit-Queue: Jan Grulich <grulja@gmail.com>
Cr-Commit-Position: refs/heads/main@{#40060}
diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
index d31f86772e348b7b6c103289180bdca3bf182a94..0aab2dd22466bc6b6d4e8e43fab8eb716512df5b 100644
--- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
+++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
@@ -447,7 +447,7 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream(
if (fd >= 0) {
pw_core_ = pw_context_connect_fd(
- pw_context_, fcntl(fd, F_DUPFD_CLOEXEC), nullptr, 0);
+ pw_context_, fcntl(fd, F_DUPFD_CLOEXEC, 0), nullptr, 0);
} else {
pw_core_ = pw_context_connect(pw_context_, nullptr, 0);
}

View File

@@ -0,0 +1,47 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jan Grulich <grulja@gmail.com>
Date: Mon, 10 Jul 2023 10:07:38 +0200
Subject: PipeWire capturer: increase buffer size to avoid buffer overflow
Recently added framerate option can cause a buffer overflow and make
PipeWire to fail on negotiation, which effectively makes screen sharing
not to work.
Bug: webrtc:15346
Change-Id: I4a68e26c8f85ca287b06a25da500b6a7009e075f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/311541
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
Commit-Queue: Jan Grulich <grulja@gmail.com>
Cr-Commit-Position: refs/heads/main@{#40413}
diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
index 0aab2dd22466bc6b6d4e8e43fab8eb716512df5b..5b1cd10e9d903bcebf0389ec5c985fbc7ddff6a8 100644
--- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
+++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
@@ -276,7 +276,7 @@ void SharedScreenCastStreamPrivate::OnStreamParamChanged(
that->stream_size_ = DesktopSize(width, height);
- uint8_t buffer[1024] = {};
+ uint8_t buffer[2048] = {};
auto builder = spa_pod_builder{buffer, sizeof(buffer)};
// Setup buffers and meta header for new format.
@@ -361,7 +361,7 @@ void SharedScreenCastStreamPrivate::OnRenegotiateFormat(void* data, uint64_t) {
{
PipeWireThreadLoopLock thread_loop_lock(that->pw_main_loop_);
- uint8_t buffer[2048] = {};
+ uint8_t buffer[4096] = {};
spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)};
@@ -479,7 +479,7 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream(
pw_stream_add_listener(pw_stream_, &spa_stream_listener_,
&pw_stream_events_, this);
- uint8_t buffer[2048] = {};
+ uint8_t buffer[4096] = {};
spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)};

View File

@@ -1,6 +1,6 @@
param([string]$gomaDir=$PWD)
$cmdPath = Join-Path -Path $gomaDir -ChildPath "goma_ctl.py"
Start-Process -FilePath cmd -ArgumentList "/C", "python", "$cmdPath", "ensure_start"
Start-Process -FilePath cmd -ArgumentList "/C", "python3", "$cmdPath", "ensure_start"
$timedOut = $false; $waitTime = 0; $waitIncrement = 5; $timeout=120;
Do { sleep $waitIncrement; $timedOut = (($waitTime+=$waitIncrement) -gt $timeout); iex "$gomaDir\gomacc.exe port 2" > $null; } Until(($LASTEXITCODE -eq 0) -or $timedOut)
if ($timedOut) {

View File

@@ -50,10 +50,10 @@
namespace {
// Initialize Node.js cli options to pass to Node.js
// Preparse Node.js cli options to pass to Node.js
// See https://nodejs.org/api/cli.html#cli_options
int SetNodeCliFlags() {
// Options that are unilaterally disallowed
void ExitIfContainsDisallowedFlags(const std::vector<std::string>& argv) {
// Options that are unilaterally disallowed.
static constexpr auto disallowed = base::MakeFixedFlatSet<base::StringPiece>({
"--enable-fips",
"--force-fips",
@@ -62,40 +62,18 @@ int SetNodeCliFlags() {
"--use-openssl-ca",
});
const auto argv = base::CommandLine::ForCurrentProcess()->argv();
std::vector<std::string> args;
// TODO(codebytere): We need to set the first entry in args to the
// process name owing to src/node_options-inl.h#L286-L290 but this is
// redundant and so should be refactored upstream.
args.reserve(argv.size() + 1);
args.emplace_back("electron");
for (const auto& arg : argv) {
#if BUILDFLAG(IS_WIN)
const auto& option = base::WideToUTF8(arg);
#else
const auto& option = arg;
#endif
const auto stripped = base::StringPiece(option).substr(0, option.find('='));
if (disallowed.contains(stripped)) {
LOG(ERROR) << "The Node.js cli flag " << stripped
const auto key = base::StringPiece(arg).substr(0, arg.find('='));
if (disallowed.contains(key)) {
LOG(ERROR) << "The Node.js cli flag " << key
<< " is not supported in Electron";
// Node.js returns 9 from ProcessGlobalArgs for any errors encountered
// when setting up cli flags and env vars. Since we're outlawing these
// flags (making them errors) return 9 here for consistency.
return 9;
} else {
args.push_back(option);
// flags (making them errors) exit with the same error code for
// consistency.
exit(9);
}
}
std::vector<std::string> errors;
// Node.js itself will output parsing errors to
// console so we don't need to handle that ourselves
return ProcessGlobalArgs(&args, nullptr, &errors,
node::kDisallowedInEnvironment);
}
#if IS_MAS_BUILD()
@@ -116,7 +94,11 @@ v8::Local<v8::Value> GetParameters(v8::Isolate* isolate) {
}
int NodeMain(int argc, char* argv[]) {
base::CommandLine::Init(argc, argv);
bool initialized = base::CommandLine::Init(argc, argv);
if (!initialized) {
LOG(ERROR) << "Failed to initialize CommandLine";
exit(1);
}
#if BUILDFLAG(IS_WIN)
v8_crashpad_support::SetUp();
@@ -153,15 +135,13 @@ int NodeMain(int argc, char* argv[]) {
// Explicitly register electron's builtin bindings.
NodeBindings::RegisterBuiltinBindings();
// Parse and set Node.js cli flags.
int flags_exit_code = SetNodeCliFlags();
if (flags_exit_code != 0)
exit(flags_exit_code);
// Hack around with the argv pointer. Used for process.title = "blah".
argv = uv_setup_args(argc, argv);
// Parse Node.js cli flags and strip out disallowed options.
std::vector<std::string> args(argv, argv + argc);
ExitIfContainsDisallowedFlags(args);
std::unique_ptr<node::InitializationResult> result =
node::InitializeOncePerProcess(
args,

View File

@@ -10,6 +10,7 @@
#include <vector>
#include "base/command_line.h"
#include "base/containers/fixed_flat_map.h"
#include "base/containers/span.h"
#include "base/environment.h"
#include "base/files/file_path.h"
@@ -473,51 +474,38 @@ IconLoader::IconSize GetIconSizeByString(const std::string& size) {
}
// Return the path constant from string.
int GetPathConstant(const std::string& name) {
if (name == "appData")
return DIR_APP_DATA;
else if (name == "sessionData")
return DIR_SESSION_DATA;
else if (name == "userData")
return chrome::DIR_USER_DATA;
else if (name == "cache")
constexpr int GetPathConstant(base::StringPiece name) {
// clang-format off
constexpr auto Lookup = base::MakeFixedFlatMap<base::StringPiece, int>({
{"appData", DIR_APP_DATA},
#if BUILDFLAG(IS_POSIX)
return base::DIR_CACHE;
{"cache", base::DIR_CACHE},
#else
return base::DIR_ROAMING_APP_DATA;
{"cache", base::DIR_ROAMING_APP_DATA},
#endif
else if (name == "userCache")
return DIR_USER_CACHE;
else if (name == "logs")
return DIR_APP_LOGS;
else if (name == "crashDumps")
return DIR_CRASH_DUMPS;
else if (name == "home")
return base::DIR_HOME;
else if (name == "temp")
return base::DIR_TEMP;
else if (name == "userDesktop" || name == "desktop")
return base::DIR_USER_DESKTOP;
else if (name == "exe")
return base::FILE_EXE;
else if (name == "module")
return base::FILE_MODULE;
else if (name == "documents")
return chrome::DIR_USER_DOCUMENTS;
else if (name == "downloads")
return chrome::DIR_DEFAULT_DOWNLOADS;
else if (name == "music")
return chrome::DIR_USER_MUSIC;
else if (name == "pictures")
return chrome::DIR_USER_PICTURES;
else if (name == "videos")
return chrome::DIR_USER_VIDEOS;
{"crashDumps", DIR_CRASH_DUMPS},
{"desktop", base::DIR_USER_DESKTOP},
{"documents", chrome::DIR_USER_DOCUMENTS},
{"downloads", chrome::DIR_DEFAULT_DOWNLOADS},
{"exe", base::FILE_EXE},
{"home", base::DIR_HOME},
{"logs", DIR_APP_LOGS},
{"module", base::FILE_MODULE},
{"music", chrome::DIR_USER_MUSIC},
{"pictures", chrome::DIR_USER_PICTURES},
#if BUILDFLAG(IS_WIN)
else if (name == "recent")
return electron::DIR_RECENT;
{"recent", electron::DIR_RECENT},
#endif
else
return -1;
{"sessionData", DIR_SESSION_DATA},
{"temp", base::DIR_TEMP},
{"userCache", DIR_USER_CACHE},
{"userData", chrome::DIR_USER_DATA},
{"userDesktop", base::DIR_USER_DESKTOP},
{"videos", chrome::DIR_USER_VIDEOS},
});
// clang-format on
const auto* iter = Lookup.find(name);
return iter != Lookup.end() ? iter->second : -1;
}
bool NotificationCallbackWrapper(

View File

@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/task/single_thread_task_runner.h"
#include "electron/buildflags/buildflags.h"
#include "gin/dictionary.h"
@@ -760,8 +761,7 @@ void BaseWindow::SetBrowserView(
}
void BaseWindow::AddBrowserView(gin::Handle<BrowserView> browser_view) {
auto iter = browser_views_.find(browser_view->ID());
if (iter == browser_views_.end()) {
if (!base::Contains(browser_views_, browser_view->ID())) {
// If we're reparenting a BrowserView, ensure that it's detached from
// its previous owner window.
BaseWindow* owner_window = browser_view->owner_window();
@@ -782,8 +782,8 @@ void BaseWindow::AddBrowserView(gin::Handle<BrowserView> browser_view) {
void BaseWindow::RemoveBrowserView(gin::Handle<BrowserView> browser_view) {
auto iter = browser_views_.find(browser_view->ID());
if (iter != browser_views_.end()) {
window_->RemoveBrowserView(browser_view->view());
window_->RemoveDraggableRegionProvider(browser_view.get());
window_->RemoveBrowserView(browser_view->view());
browser_view->SetOwnerWindow(nullptr);
iter->second.Reset();
browser_views_.erase(iter);

View File

@@ -134,6 +134,10 @@ void BrowserView::WebContentsDestroyed() {
Unpin();
}
void BrowserView::OnCloseContents() {
api_web_contents_ = nullptr;
}
// static
gin::Handle<BrowserView> BrowserView::New(gin_helper::ErrorThrower thrower,
gin::Arguments* args) {

View File

@@ -71,6 +71,9 @@ class BrowserView : public gin::Wrappable<BrowserView>,
// content::WebContentsObserver:
void WebContentsDestroyed() override;
// ExtendedWebContentsObserver:
void OnCloseContents() override;
private:
void SetAutoResize(AutoResizeFlags flags);
void SetBounds(const gfx::Rect& bounds);

View File

@@ -181,6 +181,41 @@ DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {}
DesktopCapturer::~DesktopCapturer() = default;
DesktopCapturer::DesktopListListener::DesktopListListener(
OnceCallback update_callback,
OnceCallback failure_callback,
bool skip_thumbnails)
: update_callback_(std::move(update_callback)),
failure_callback_(std::move(failure_callback)),
have_thumbnail_(skip_thumbnails) {}
DesktopCapturer::DesktopListListener::~DesktopListListener() = default;
void DesktopCapturer::DesktopListListener::OnDelegatedSourceListSelection() {
if (have_thumbnail_) {
std::move(update_callback_).Run();
} else {
have_selection_ = true;
}
}
void DesktopCapturer::DesktopListListener::OnSourceThumbnailChanged(int index) {
if (have_selection_) {
// This is called every time a thumbnail is refreshed. Reset variable to
// ensure that the callback is not run again.
have_selection_ = false;
// PipeWire returns a single source, so index is not relevant.
std::move(update_callback_).Run();
} else {
have_thumbnail_ = true;
}
}
void DesktopCapturer::DesktopListListener::OnDelegatedSourceListDismissed() {
std::move(failure_callback_).Run();
}
void DesktopCapturer::StartHandling(bool capture_window,
bool capture_screen,
const gfx::Size& thumbnail_size,
@@ -199,6 +234,33 @@ void DesktopCapturer::StartHandling(bool capture_window,
// clear any existing captured sources.
captured_sources_.clear();
if (capture_window && capture_screen) {
// Some capturers like PipeWire suppport a single capturer for both screens
// and windows. Use it if possible, treating both as window capture
if (auto capturer = webrtc::DesktopCapturer::CreateGenericCapturer(
content::desktop_capture::CreateDesktopCaptureOptions());
capturer && capturer->GetDelegatedSourceListController()) {
capture_screen_ = false;
capture_window_ = capture_window;
window_capturer_ = std::make_unique<NativeDesktopMediaList>(
DesktopMediaList::Type::kWindow, std::move(capturer));
window_capturer_->SetThumbnailSize(thumbnail_size);
OnceCallback update_callback = base::BindOnce(
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
window_capturer_.get());
OnceCallback failure_callback = base::BindOnce(
&DesktopCapturer::HandleFailure, weak_ptr_factory_.GetWeakPtr());
window_listener_ = std::make_unique<DesktopListListener>(
std::move(update_callback), std::move(failure_callback),
thumbnail_size.IsEmpty());
window_capturer_->StartUpdating(window_listener_.get());
return;
}
}
// Start listening for captured sources.
capture_window_ = capture_window;
capture_screen_ = capture_screen;
@@ -212,11 +274,22 @@ void DesktopCapturer::StartHandling(bool capture_window,
window_capturer_ = std::make_unique<NativeDesktopMediaList>(
DesktopMediaList::Type::kWindow, std::move(capturer));
window_capturer_->SetThumbnailSize(thumbnail_size);
window_capturer_->Update(
base::BindOnce(&DesktopCapturer::UpdateSourcesList,
weak_ptr_factory_.GetWeakPtr(),
window_capturer_.get()),
/* refresh_thumbnails = */ true);
OnceCallback update_callback = base::BindOnce(
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
window_capturer_.get());
if (window_capturer_->IsSourceListDelegated()) {
OnceCallback failure_callback = base::BindOnce(
&DesktopCapturer::HandleFailure, weak_ptr_factory_.GetWeakPtr());
window_listener_ = std::make_unique<DesktopListListener>(
std::move(update_callback), std::move(failure_callback),
thumbnail_size.IsEmpty());
window_capturer_->StartUpdating(window_listener_.get());
} else {
window_capturer_->Update(std::move(update_callback),
/* refresh_thumbnails = */ true);
}
}
}
@@ -226,11 +299,22 @@ void DesktopCapturer::StartHandling(bool capture_window,
screen_capturer_ = std::make_unique<NativeDesktopMediaList>(
DesktopMediaList::Type::kScreen, std::move(capturer));
screen_capturer_->SetThumbnailSize(thumbnail_size);
screen_capturer_->Update(
base::BindOnce(&DesktopCapturer::UpdateSourcesList,
weak_ptr_factory_.GetWeakPtr(),
screen_capturer_.get()),
/* refresh_thumbnails = */ true);
OnceCallback update_callback = base::BindOnce(
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
screen_capturer_.get());
if (screen_capturer_->IsSourceListDelegated()) {
OnceCallback failure_callback = base::BindOnce(
&DesktopCapturer::HandleFailure, weak_ptr_factory_.GetWeakPtr());
screen_listener_ = std::make_unique<DesktopListListener>(
std::move(update_callback), std::move(failure_callback),
thumbnail_size.IsEmpty());
screen_capturer_->StartUpdating(screen_listener_.get());
} else {
screen_capturer_->Update(std::move(update_callback),
/* refresh_thumbnails = */ true);
}
}
}
}
@@ -270,12 +354,7 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
// |media_list_sources|.
if (!webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
&device_names)) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope scope(isolate);
gin_helper::CallMethod(this, "_onerror", "Failed to get sources.");
Unpin();
HandleFailure();
return;
}
@@ -325,6 +404,14 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
}
}
void DesktopCapturer::HandleFailure() {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope scope(isolate);
gin_helper::CallMethod(this, "_onerror", "Failed to get sources.");
Unpin();
}
// static
gin::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
auto handle = gin::CreateHandle(isolate, new DesktopCapturer(isolate));

View File

@@ -62,8 +62,37 @@ class DesktopCapturer : public gin::Wrappable<DesktopCapturer>,
void OnDelegatedSourceListDismissed() override {}
private:
void UpdateSourcesList(DesktopMediaList* list);
using OnceCallback = base::OnceClosure;
class DesktopListListener : public DesktopMediaListObserver {
public:
DesktopListListener(OnceCallback update_callback,
OnceCallback failure_callback,
bool skip_thumbnails);
~DesktopListListener() override;
protected:
void OnSourceAdded(int index) override {}
void OnSourceRemoved(int index) override {}
void OnSourceMoved(int old_index, int new_index) override {}
void OnSourceNameChanged(int index) override {}
void OnSourceThumbnailChanged(int index) override;
void OnSourcePreviewChanged(size_t index) override {}
void OnDelegatedSourceListSelection() override;
void OnDelegatedSourceListDismissed() override;
private:
OnceCallback update_callback_;
OnceCallback failure_callback_;
bool have_selection_ = false;
bool have_thumbnail_ = false;
};
void UpdateSourcesList(DesktopMediaList* list);
void HandleFailure();
std::unique_ptr<DesktopListListener> window_listener_;
std::unique_ptr<DesktopListListener> screen_listener_;
std::unique_ptr<DesktopMediaList> window_capturer_;
std::unique_ptr<DesktopMediaList> screen_capturer_;
std::vector<DesktopCapturer::Source> captured_sources_;

View File

@@ -62,8 +62,7 @@ GlobalShortcut::~GlobalShortcut() {
}
void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
if (accelerator_callback_map_.find(accelerator) ==
accelerator_callback_map_.end()) {
if (!base::Contains(accelerator_callback_map_, accelerator)) {
// This should never occur, because if it does, GlobalShortcutListener
// notifies us with wrong accelerator.
NOTREACHED();

View File

@@ -6,6 +6,7 @@
#include <string>
#include "base/containers/contains.h"
#include "base/functional/callback_helpers.h"
#include "content/public/browser/device_service.h"
#include "gin/dictionary.h"
@@ -106,8 +107,8 @@ bool PowerSaveBlocker::Stop(int id) {
return success;
}
bool PowerSaveBlocker::IsStarted(int id) {
return wake_lock_types_.find(id) != wake_lock_types_.end();
bool PowerSaveBlocker::IsStarted(int id) const {
return base::Contains(wake_lock_types_, id);
}
// static

View File

@@ -37,7 +37,7 @@ class PowerSaveBlocker : public gin::Wrappable<PowerSaveBlocker> {
void UpdatePowerSaveBlocker();
int Start(device::mojom::WakeLockType type);
bool Stop(int id);
bool IsStarted(int id);
bool IsStarted(int id) const;
device::mojom::WakeLock* GetWakeLock();

View File

@@ -9,6 +9,7 @@
#include "shell/browser/api/electron_api_system_preferences.h"
#include "base/containers/fixed_flat_map.h"
#include "base/win/core_winrt_util.h"
#include "base/win/windows_types.h"
#include "base/win/wrapped_window_proc.h"
@@ -97,73 +98,45 @@ std::string SystemPreferences::GetAccentColor() {
std::string SystemPreferences::GetColor(gin_helper::ErrorThrower thrower,
const std::string& color) {
int id;
if (color == "3d-dark-shadow") {
id = COLOR_3DDKSHADOW;
} else if (color == "3d-face") {
id = COLOR_3DFACE;
} else if (color == "3d-highlight") {
id = COLOR_3DHIGHLIGHT;
} else if (color == "3d-light") {
id = COLOR_3DLIGHT;
} else if (color == "3d-shadow") {
id = COLOR_3DSHADOW;
} else if (color == "active-border") {
id = COLOR_ACTIVEBORDER;
} else if (color == "active-caption") {
id = COLOR_ACTIVECAPTION;
} else if (color == "active-caption-gradient") {
id = COLOR_GRADIENTACTIVECAPTION;
} else if (color == "app-workspace") {
id = COLOR_APPWORKSPACE;
} else if (color == "button-text") {
id = COLOR_BTNTEXT;
} else if (color == "caption-text") {
id = COLOR_CAPTIONTEXT;
} else if (color == "desktop") {
id = COLOR_DESKTOP;
} else if (color == "disabled-text") {
id = COLOR_GRAYTEXT;
} else if (color == "highlight") {
id = COLOR_HIGHLIGHT;
} else if (color == "highlight-text") {
id = COLOR_HIGHLIGHTTEXT;
} else if (color == "hotlight") {
id = COLOR_HOTLIGHT;
} else if (color == "inactive-border") {
id = COLOR_INACTIVEBORDER;
} else if (color == "inactive-caption") {
id = COLOR_INACTIVECAPTION;
} else if (color == "inactive-caption-gradient") {
id = COLOR_GRADIENTINACTIVECAPTION;
} else if (color == "inactive-caption-text") {
id = COLOR_INACTIVECAPTIONTEXT;
} else if (color == "info-background") {
id = COLOR_INFOBK;
} else if (color == "info-text") {
id = COLOR_INFOTEXT;
} else if (color == "menu") {
id = COLOR_MENU;
} else if (color == "menu-highlight") {
id = COLOR_MENUHILIGHT;
} else if (color == "menubar") {
id = COLOR_MENUBAR;
} else if (color == "menu-text") {
id = COLOR_MENUTEXT;
} else if (color == "scrollbar") {
id = COLOR_SCROLLBAR;
} else if (color == "window") {
id = COLOR_WINDOW;
} else if (color == "window-frame") {
id = COLOR_WINDOWFRAME;
} else if (color == "window-text") {
id = COLOR_WINDOWTEXT;
} else {
thrower.ThrowError("Unknown color: " + color);
return "";
}
static constexpr auto Lookup =
base::MakeFixedFlatMap<base::StringPiece, int>({
{"3d-dark-shadow", COLOR_3DDKSHADOW},
{"3d-face", COLOR_3DFACE},
{"3d-highlight", COLOR_3DHIGHLIGHT},
{"3d-light", COLOR_3DLIGHT},
{"3d-shadow", COLOR_3DSHADOW},
{"active-border", COLOR_ACTIVEBORDER},
{"active-caption", COLOR_ACTIVECAPTION},
{"active-caption-gradient", COLOR_GRADIENTACTIVECAPTION},
{"app-workspace", COLOR_APPWORKSPACE},
{"button-text", COLOR_BTNTEXT},
{"caption-text", COLOR_CAPTIONTEXT},
{"desktop", COLOR_DESKTOP},
{"disabled-text", COLOR_GRAYTEXT},
{"highlight", COLOR_HIGHLIGHT},
{"highlight-text", COLOR_HIGHLIGHTTEXT},
{"hotlight", COLOR_HOTLIGHT},
{"inactive-border", COLOR_INACTIVEBORDER},
{"inactive-caption", COLOR_INACTIVECAPTION},
{"inactive-caption-gradient", COLOR_GRADIENTINACTIVECAPTION},
{"inactive-caption-text", COLOR_INACTIVECAPTIONTEXT},
{"info-background", COLOR_INFOBK},
{"info-text", COLOR_INFOTEXT},
{"menu", COLOR_MENU},
{"menu-highlight", COLOR_MENUHILIGHT},
{"menu-text", COLOR_MENUTEXT},
{"menubar", COLOR_MENUBAR},
{"scrollbar", COLOR_SCROLLBAR},
{"window", COLOR_WINDOW},
{"window-frame", COLOR_WINDOWFRAME},
{"window-text", COLOR_WINDOWTEXT},
});
return ToRGBHex(color_utils::GetSysSkColor(id));
if (const auto* iter = Lookup.find(color); iter != Lookup.end())
return ToRGBHex(color_utils::GetSysSkColor(iter->second));
thrower.ThrowError("Unknown color: " + color);
return "";
}
std::string SystemPreferences::GetMediaAccessStatus(

View File

@@ -10,6 +10,7 @@
#include <utility>
#include <vector>
#include "base/containers/fixed_flat_map.h"
#include "base/no_destructor.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
@@ -412,62 +413,46 @@ gin::Handle<SimpleURLLoaderWrapper> SimpleURLLoaderWrapper::Create(
request->trusted_params->has_user_activation = has_user_activation;
}
std::string mode;
if (opts.Get("mode", &mode) && !mode.empty()) {
if (mode == "navigate") {
request->mode = network::mojom::RequestMode::kNavigate;
} else if (mode == "cors") {
request->mode = network::mojom::RequestMode::kCors;
} else if (mode == "no-cors") {
request->mode = network::mojom::RequestMode::kNoCors;
} else if (mode == "same-origin") {
request->mode = network::mojom::RequestMode::kSameOrigin;
}
if (std::string mode; opts.Get("mode", &mode)) {
using Val = network::mojom::RequestMode;
static constexpr auto Lookup =
base::MakeFixedFlatMap<base::StringPiece, Val>({
{"cors", Val::kCors},
{"navigate", Val::kNavigate},
{"no-cors", Val::kNoCors},
{"same-origin", Val::kSameOrigin},
});
if (auto* iter = Lookup.find(mode); iter != Lookup.end())
request->mode = iter->second;
}
std::string destination;
if (opts.Get("destination", &destination) && !destination.empty()) {
if (destination == "empty") {
request->destination = network::mojom::RequestDestination::kEmpty;
} else if (destination == "audio") {
request->destination = network::mojom::RequestDestination::kAudio;
} else if (destination == "audioworklet") {
request->destination = network::mojom::RequestDestination::kAudioWorklet;
} else if (destination == "document") {
request->destination = network::mojom::RequestDestination::kDocument;
} else if (destination == "embed") {
request->destination = network::mojom::RequestDestination::kEmbed;
} else if (destination == "font") {
request->destination = network::mojom::RequestDestination::kFont;
} else if (destination == "frame") {
request->destination = network::mojom::RequestDestination::kFrame;
} else if (destination == "iframe") {
request->destination = network::mojom::RequestDestination::kIframe;
} else if (destination == "image") {
request->destination = network::mojom::RequestDestination::kImage;
} else if (destination == "manifest") {
request->destination = network::mojom::RequestDestination::kManifest;
} else if (destination == "object") {
request->destination = network::mojom::RequestDestination::kObject;
} else if (destination == "paintworklet") {
request->destination = network::mojom::RequestDestination::kPaintWorklet;
} else if (destination == "report") {
request->destination = network::mojom::RequestDestination::kReport;
} else if (destination == "script") {
request->destination = network::mojom::RequestDestination::kScript;
} else if (destination == "serviceworker") {
request->destination = network::mojom::RequestDestination::kServiceWorker;
} else if (destination == "style") {
request->destination = network::mojom::RequestDestination::kStyle;
} else if (destination == "track") {
request->destination = network::mojom::RequestDestination::kTrack;
} else if (destination == "video") {
request->destination = network::mojom::RequestDestination::kVideo;
} else if (destination == "worker") {
request->destination = network::mojom::RequestDestination::kWorker;
} else if (destination == "xslt") {
request->destination = network::mojom::RequestDestination::kXslt;
}
if (std::string destination; opts.Get("destination", &destination)) {
using Val = network::mojom::RequestDestination;
static constexpr auto Lookup =
base::MakeFixedFlatMap<base::StringPiece, Val>({
{"audio", Val::kAudio},
{"audioworklet", Val::kAudioWorklet},
{"document", Val::kDocument},
{"embed", Val::kEmbed},
{"empty", Val::kEmpty},
{"font", Val::kFont},
{"frame", Val::kFrame},
{"iframe", Val::kIframe},
{"image", Val::kImage},
{"manifest", Val::kManifest},
{"object", Val::kObject},
{"paintworklet", Val::kPaintWorklet},
{"report", Val::kReport},
{"script", Val::kScript},
{"serviceworker", Val::kServiceWorker},
{"style", Val::kStyle},
{"track", Val::kTrack},
{"video", Val::kVideo},
{"worker", Val::kWorker},
{"xslt", Val::kXslt},
});
if (auto* iter = Lookup.find(destination); iter != Lookup.end())
request->destination = iter->second;
}
bool credentials_specified =

View File

@@ -12,6 +12,7 @@
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/containers/id_map.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
@@ -729,8 +730,8 @@ std::map<std::string, std::string> GetAddedFileSystemPaths(
bool IsDevToolsFileSystemAdded(content::WebContents* web_contents,
const std::string& file_system_path) {
auto file_system_paths = GetAddedFileSystemPaths(web_contents);
return file_system_paths.find(file_system_path) != file_system_paths.end();
return base::Contains(GetAddedFileSystemPaths(web_contents),
file_system_path);
}
void SetBackgroundColor(content::RenderWidgetHostView* rwhv, SkColor color) {
@@ -768,12 +769,7 @@ WebContents::WebContents(v8::Isolate* isolate,
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
type_(Type::kRemote),
id_(GetAllWebContents().Add(this)),
devtools_file_system_indexer_(
base::MakeRefCounted<DevToolsFileSystemIndexer>()),
exclusive_access_manager_(std::make_unique<ExclusiveAccessManager>(this)),
file_task_runner_(
base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}))
id_(GetAllWebContents().Add(this))
#if BUILDFLAG(ENABLE_PRINTING)
,
print_task_runner_(CreatePrinterHandlerTaskRunner())
@@ -806,12 +802,7 @@ WebContents::WebContents(v8::Isolate* isolate,
Type type)
: content::WebContentsObserver(web_contents.get()),
type_(type),
id_(GetAllWebContents().Add(this)),
devtools_file_system_indexer_(
base::MakeRefCounted<DevToolsFileSystemIndexer>()),
exclusive_access_manager_(std::make_unique<ExclusiveAccessManager>(this)),
file_task_runner_(
base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}))
id_(GetAllWebContents().Add(this))
#if BUILDFLAG(ENABLE_PRINTING)
,
print_task_runner_(CreatePrinterHandlerTaskRunner())
@@ -827,12 +818,7 @@ WebContents::WebContents(v8::Isolate* isolate,
WebContents::WebContents(v8::Isolate* isolate,
const gin_helper::Dictionary& options)
: id_(GetAllWebContents().Add(this)),
devtools_file_system_indexer_(
base::MakeRefCounted<DevToolsFileSystemIndexer>()),
exclusive_access_manager_(std::make_unique<ExclusiveAccessManager>(this)),
file_task_runner_(
base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}))
: id_(GetAllWebContents().Add(this))
#if BUILDFLAG(ENABLE_PRINTING)
,
print_task_runner_(CreatePrinterHandlerTaskRunner())
@@ -1339,7 +1325,9 @@ void WebContents::CloseContents(content::WebContents* source) {
for (ExtendedWebContentsObserver& observer : observers_)
observer.OnCloseContents();
Destroy();
// This is handled by the embedder frame.
if (!IsGuest())
Destroy();
}
void WebContents::ActivateContents(content::WebContents* source) {
@@ -1394,7 +1382,7 @@ bool WebContents::PlatformHandleKeyboardEvent(
content::KeyboardEventProcessingResult WebContents::PreHandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) {
if (exclusive_access_manager_->HandleUserKeyEvent(event))
if (exclusive_access_manager_.HandleUserKeyEvent(event))
return content::KeyboardEventProcessingResult::HANDLED;
if (event.GetType() == blink::WebInputEvent::Type::kRawKeyDown ||
@@ -1482,7 +1470,7 @@ void WebContents::OnEnterFullscreenModeForTab(
owner_window()->set_fullscreen_transition_type(
NativeWindow::FullScreenTransitionType::HTML);
exclusive_access_manager_->fullscreen_controller()->EnterFullscreenModeForTab(
exclusive_access_manager_.fullscreen_controller()->EnterFullscreenModeForTab(
requesting_frame, options.display_id);
SetHtmlApiFullscreen(true);
@@ -1500,7 +1488,7 @@ void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
// This needs to be called before we exit fullscreen on the native window,
// or the controller will incorrectly think we weren't fullscreen and bail.
exclusive_access_manager_->fullscreen_controller()->ExitFullscreenModeForTab(
exclusive_access_manager_.fullscreen_controller()->ExitFullscreenModeForTab(
source);
SetHtmlApiFullscreen(false);
@@ -1559,7 +1547,7 @@ void WebContents::RequestExclusivePointerAccess(
bool last_unlocked_by_target,
bool allowed) {
if (allowed) {
exclusive_access_manager_->mouse_lock_controller()->RequestToLockMouse(
exclusive_access_manager_.mouse_lock_controller()->RequestToLockMouse(
web_contents, user_gesture, last_unlocked_by_target);
} else {
web_contents->GotResponseToLockMouseRequest(
@@ -1579,18 +1567,18 @@ void WebContents::RequestToLockMouse(content::WebContents* web_contents,
}
void WebContents::LostMouseLock() {
exclusive_access_manager_->mouse_lock_controller()->LostMouseLock();
exclusive_access_manager_.mouse_lock_controller()->LostMouseLock();
}
void WebContents::RequestKeyboardLock(content::WebContents* web_contents,
bool esc_key_locked) {
exclusive_access_manager_->keyboard_lock_controller()->RequestKeyboardLock(
exclusive_access_manager_.keyboard_lock_controller()->RequestKeyboardLock(
web_contents, esc_key_locked);
}
void WebContents::CancelKeyboardLockRequest(
content::WebContents* web_contents) {
exclusive_access_manager_->keyboard_lock_controller()
exclusive_access_manager_.keyboard_lock_controller()
->CancelKeyboardLockRequest(web_contents);
}
@@ -1961,7 +1949,8 @@ void WebContents::MessageSync(
void WebContents::MessageTo(int32_t web_contents_id,
const std::string& channel,
blink::CloneableMessage arguments) {
blink::CloneableMessage arguments,
content::RenderFrameHost* render_frame_host) {
TRACE_EVENT1("electron", "WebContents::MessageTo", "channel", channel);
auto* target_web_contents = FromID(web_contents_id);
@@ -1977,8 +1966,10 @@ void WebContents::MessageTo(int32_t web_contents_id,
return;
int32_t sender_id = ID();
bool sender_is_main_frame = render_frame_host->GetParent() == nullptr;
web_frame_main->GetRendererApi()->Message(false /* internal */, channel,
std::move(arguments), sender_id);
std::move(arguments), sender_id,
sender_is_main_frame);
}
}

View File

@@ -14,9 +14,11 @@
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/task/thread_pool.h"
#include "chrome/browser/devtools/devtools_eye_dropper.h"
#include "chrome/browser/devtools/devtools_file_system_indexer.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_context.h" // nogncheck
#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "content/common/frame.mojom.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/keyboard_event_processing_result.h"
@@ -75,8 +77,6 @@ namespace gin {
class Arguments;
}
class ExclusiveAccessManager;
class SkRegion;
namespace electron {
@@ -418,7 +418,8 @@ class WebContents : public ExclusiveAccessContext,
content::RenderFrameHost* render_frame_host);
void MessageTo(int32_t web_contents_id,
const std::string& channel,
blink::CloneableMessage arguments);
blink::CloneableMessage arguments,
content::RenderFrameHost* render_frame_host);
void MessageHost(const std::string& channel,
blink::CloneableMessage arguments,
content::RenderFrameHost* render_frame_host);
@@ -790,9 +791,10 @@ class WebContents : public ExclusiveAccessContext,
// Whether window is fullscreened by window api.
bool native_fullscreen_ = false;
scoped_refptr<DevToolsFileSystemIndexer> devtools_file_system_indexer_;
const scoped_refptr<DevToolsFileSystemIndexer> devtools_file_system_indexer_ =
base::MakeRefCounted<DevToolsFileSystemIndexer>();
std::unique_ptr<ExclusiveAccessManager> exclusive_access_manager_;
ExclusiveAccessManager exclusive_access_manager_{this};
std::unique_ptr<DevToolsEyeDropper> eye_dropper_;
@@ -814,10 +816,11 @@ class WebContents : public ExclusiveAccessContext,
DevToolsIndexingJobsMap;
DevToolsIndexingJobsMap devtools_indexing_jobs_;
scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
const scoped_refptr<base::SequencedTaskRunner> file_task_runner_ =
base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()});
#if BUILDFLAG(ENABLE_PRINTING)
scoped_refptr<base::TaskRunner> print_task_runner_;
const scoped_refptr<base::TaskRunner> print_task_runner_;
#endif
// Stores the frame thats currently in fullscreen, nullptr if there is none.

View File

@@ -185,7 +185,8 @@ void WebFrameMain::Send(v8::Isolate* isolate,
return;
GetRendererApi()->Message(internal, channel, std::move(message),
0 /* sender_id */);
0 /* sender_id */,
false /* sender_is_main_frame */);
}
const mojo::Remote<mojom::ElectronRenderer>& WebFrameMain::GetRendererApi() {

View File

@@ -8,6 +8,7 @@
#include <string>
#include <utility>
#include "base/containers/contains.h"
#include "base/stl_util.h"
#include "base/task/sequenced_task_runner.h"
#include "base/values.h"
@@ -294,7 +295,7 @@ bool WebRequest::RequestFilter::MatchesURL(const GURL& url) const {
bool WebRequest::RequestFilter::MatchesType(
extensions::WebRequestResourceType type) const {
return types_.empty() || types_.find(type) != types_.end();
return types_.empty() || base::Contains(types_, type);
}
bool WebRequest::RequestFilter::MatchesRequest(

View File

@@ -8,6 +8,7 @@
#include <unordered_set>
#include <utility>
#include "base/containers/contains.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "gin/arguments.h"
@@ -221,7 +222,7 @@ std::vector<blink::MessagePortChannel> MessagePort::DisentanglePorts(
// or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec).
for (unsigned i = 0; i < ports.size(); ++i) {
auto* port = ports[i].get();
if (!port || port->IsNeutered() || visited.find(port) != visited.end()) {
if (!port || port->IsNeutered() || base::Contains(visited, port)) {
std::string type;
if (!port)
type = "null";

View File

@@ -25,6 +25,8 @@
#include "components/proxy_config/proxy_config_dictionary.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/network_quality_observer_factory.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/common/content_switches.h"
#include "electron/fuses.h"
#include "extensions/common/constants.h"
@@ -130,6 +132,10 @@ void BrowserProcessImpl::PreCreateThreads() {
SystemNetworkContextManager::CreateInstance(local_state_.get());
}
void BrowserProcessImpl::PreMainMessageLoopRun() {
CreateNetworkQualityObserver();
}
void BrowserProcessImpl::PostMainMessageLoopRun() {
if (local_state_)
local_state_->CommitPendingWrite();
@@ -324,3 +330,18 @@ printing::PrintJobManager* BrowserProcessImpl::print_job_manager() {
StartupData* BrowserProcessImpl::startup_data() {
return nullptr;
}
network::NetworkQualityTracker* BrowserProcessImpl::GetNetworkQualityTracker() {
if (!network_quality_tracker_) {
network_quality_tracker_ = std::make_unique<network::NetworkQualityTracker>(
base::BindRepeating(&content::GetNetworkService));
}
return network_quality_tracker_.get();
}
void BrowserProcessImpl::CreateNetworkQualityObserver() {
DCHECK(!network_quality_observer_);
network_quality_observer_ =
content::CreateNetworkQualityObserver(GetNetworkQualityTracker());
DCHECK(network_quality_observer_);
}

View File

@@ -18,6 +18,7 @@
#include "components/prefs/pref_service.h"
#include "components/prefs/value_map_pref_store.h"
#include "printing/buildflags/buildflags.h"
#include "services/network/public/cpp/network_quality_tracker.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "shell/browser/net/system_network_context_manager.h"
@@ -46,6 +47,7 @@ class BrowserProcessImpl : public BrowserProcess {
GetBreadcrumbPersistentStorageManager() override;
void PostEarlyInitialization();
void PreCreateThreads();
void PreMainMessageLoopRun();
void PostDestroyThreads() {}
void PostMainMessageLoopRun();
@@ -109,12 +111,19 @@ class BrowserProcessImpl : public BrowserProcess {
StartupData* startup_data() override;
private:
void CreateNetworkQualityObserver();
network::NetworkQualityTracker* GetNetworkQualityTracker();
#if BUILDFLAG(ENABLE_PRINTING)
std::unique_ptr<printing::PrintJobManager> print_job_manager_;
#endif
std::unique_ptr<PrefService> local_state_;
std::string locale_;
std::string system_locale_;
std::unique_ptr<network::NetworkQualityTracker> network_quality_tracker_;
std::unique_ptr<
network::NetworkQualityTracker::RTTAndThroughputEstimatesObserver>
network_quality_observer_;
};
#endif // ELECTRON_SHELL_BROWSER_BROWSER_PROCESS_IMPL_H_

View File

@@ -82,7 +82,8 @@ void ElectronApiIPCHandlerImpl::MessageTo(int32_t web_contents_id,
blink::CloneableMessage arguments) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->MessageTo(web_contents_id, channel, std::move(arguments));
api_web_contents->MessageTo(web_contents_id, channel, std::move(arguments),
GetRenderFrameHost());
}
}

View File

@@ -778,32 +778,6 @@ base::FilePath ElectronBrowserClient::GetLoggingFileName(
return logging::GetLogFileName(cmd_line);
}
void ElectronBrowserClient::SiteInstanceDeleting(
content::SiteInstance* site_instance) {
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
// Don't do anything if we're shutting down.
if (content::BrowserMainRunner::ExitedMainMessageLoop())
return;
auto* browser_context =
static_cast<ElectronBrowserContext*>(site_instance->GetBrowserContext());
if (!browser_context->IsOffTheRecord()) {
// If this isn't an extension renderer there's nothing to do.
extensions::ExtensionRegistry* registry =
extensions::ExtensionRegistry::Get(browser_context);
const extensions::Extension* extension =
registry->enabled_extensions().GetExtensionOrAppByURL(
site_instance->GetSiteURL());
if (!extension)
return;
extensions::ProcessMap::Get(browser_context)
->Remove(extension->id(), site_instance->GetProcess()->GetID(),
site_instance->GetId());
}
#endif
}
std::unique_ptr<net::ClientCertStore>
ElectronBrowserClient::CreateClientCertStore(
content::BrowserContext* browser_context) {

View File

@@ -166,7 +166,6 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
std::vector<std::string>* additional_schemes) override;
void GetAdditionalWebUISchemes(
std::vector<std::string>* additional_schemes) override;
void SiteInstanceDeleting(content::SiteInstance* site_instance) override;
std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
content::BrowserContext* browser_context) override;
std::unique_ptr<device::LocationProvider> OverrideSystemLocationProvider()

View File

@@ -210,11 +210,11 @@ ElectronBrowserMainParts* ElectronBrowserMainParts::self_ = nullptr;
ElectronBrowserMainParts::ElectronBrowserMainParts()
: fake_browser_process_(std::make_unique<BrowserProcessImpl>()),
browser_(std::make_unique<Browser>()),
node_bindings_(
NodeBindings::Create(NodeBindings::BrowserEnvironment::kBrowser)),
electron_bindings_(
std::make_unique<ElectronBindings>(node_bindings_->uv_loop())) {
node_bindings_{
NodeBindings::Create(NodeBindings::BrowserEnvironment::kBrowser)},
electron_bindings_{
std::make_unique<ElectronBindings>(node_bindings_->uv_loop())},
browser_{std::make_unique<Browser>()} {
DCHECK(!self_) << "Cannot have two ElectronBrowserMainParts";
self_ = this;
}
@@ -525,6 +525,8 @@ int ElectronBrowserMainParts::PreMainMessageLoopRun() {
// Notify observers that main thread message loop was initialized.
Browser::Get()->PreMainMessageLoopRun();
fake_browser_process_->PreMainMessageLoopRun();
return GetExitCode();
}

View File

@@ -165,11 +165,20 @@ class ElectronBrowserMainParts : public content::BrowserMainParts {
// Before then, we just exit() without any intermediate steps.
absl::optional<int> exit_code_;
std::unique_ptr<JavascriptEnvironment> js_env_;
std::unique_ptr<Browser> browser_;
std::unique_ptr<NodeBindings> node_bindings_;
// depends-on: node_bindings_
std::unique_ptr<ElectronBindings> electron_bindings_;
// depends-on: node_bindings_
std::unique_ptr<JavascriptEnvironment> js_env_;
// depends-on: js_env_'s isolate
std::unique_ptr<NodeEnvironment> node_env_;
// depends-on: js_env_'s isolate
std::unique_ptr<Browser> browser_;
std::unique_ptr<IconManager> icon_manager_;
std::unique_ptr<base::FieldTrialList> field_trial_list_;

View File

@@ -149,8 +149,7 @@ void HidChooserController::OnDeviceAdded(
void HidChooserController::OnDeviceRemoved(
const device::mojom::HidDeviceInfo& device) {
auto id = PhysicalDeviceIdFromDeviceInfo(device);
auto items_it = std::find(items_.begin(), items_.end(), id);
if (items_it == items_.end())
if (!base::Contains(items_, id))
return;
api::Session* session = GetSession();
if (session) {

View File

@@ -8,6 +8,7 @@
#include <string>
#include <vector>
#include "base/containers/contains.h"
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
@@ -197,10 +198,6 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) {
SetSizeConstraints(size_constraints);
}
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
bool resizable;
if (options.Get(options::kResizable, &resizable)) {
SetResizable(resizable);
}
bool closable;
if (options.Get(options::kClosable, &closable)) {
SetClosable(closable);
@@ -222,6 +219,7 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) {
if (options.Get(options::kAlwaysOnTop, &top) && top) {
SetAlwaysOnTop(ui::ZOrderLevel::kFloatingWindow);
}
bool fullscreenable = true;
bool fullscreen = false;
if (options.Get(options::kFullscreen, &fullscreen) && !fullscreen) {
@@ -230,12 +228,18 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) {
fullscreenable = false;
#endif
}
// Overridden by 'fullscreenable'.
options.Get(options::kFullScreenable, &fullscreenable);
SetFullScreenable(fullscreenable);
if (fullscreen) {
if (fullscreen)
SetFullScreen(true);
bool resizable;
if (options.Get(options::kResizable, &resizable)) {
SetResizable(resizable);
}
bool skip;
if (options.Get(options::kSkipTaskbar, &skip)) {
SetSkipTaskbar(skip);
@@ -725,9 +729,7 @@ int NativeWindow::NonClientHitTest(const gfx::Point& point) {
void NativeWindow::AddDraggableRegionProvider(
DraggableRegionProvider* provider) {
if (std::find(draggable_region_providers_.begin(),
draggable_region_providers_.end(),
provider) == draggable_region_providers_.end()) {
if (!base::Contains(draggable_region_providers_, provider)) {
draggable_region_providers_.push_back(provider);
}
}

View File

@@ -148,6 +148,7 @@ class NativeWindow : public base::SupportsUserData,
virtual std::string GetAlwaysOnTopLevel() = 0;
virtual void SetActive(bool is_key) = 0;
virtual bool IsActive() const = 0;
virtual void RemoveChildFromParentWindow() = 0;
virtual void RemoveChildWindow(NativeWindow* child) = 0;
virtual void AttachChildren() = 0;
virtual void DetachChildren() = 0;

View File

@@ -157,7 +157,7 @@ class NativeWindowMac : public NativeWindow,
bool IsActive() const override;
// Remove the specified child window without closing it.
void RemoveChildWindow(NativeWindow* child) override;
void RemoveChildFromParentWindow(NativeWindow* child);
void RemoveChildFromParentWindow() override;
// Attach child windows, if the window is visible.
void AttachChildren() override;
// Detach window from parent without destroying it.

View File

@@ -163,6 +163,47 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
[self setFrame:[[self superview] bounds]];
}
// -[NSWindow orderWindow] does not handle reordering for children
// windows. Their order is fixed to the attachment order (the last attached
// window is on the top). Therefore, work around it by re-parenting in our
// desired order.
void ReorderChildWindowAbove(NSWindow* child_window, NSWindow* other_window) {
NSWindow* parent = [child_window parentWindow];
DCHECK(parent);
// `ordered_children` sorts children windows back to front.
NSArray<NSWindow*>* children = [[child_window parentWindow] childWindows];
std::vector<std::pair<NSInteger, NSWindow*>> ordered_children;
for (NSWindow* child in children)
ordered_children.push_back({[child orderedIndex], child});
std::sort(ordered_children.begin(), ordered_children.end(), std::greater<>());
// If `other_window` is nullptr, place `child_window` in front of
// all other children windows.
if (other_window == nullptr)
other_window = ordered_children.back().second;
if (child_window == other_window)
return;
for (NSWindow* child in children)
[parent removeChildWindow:child];
const bool relative_to_parent = parent == other_window;
if (relative_to_parent)
[parent addChildWindow:child_window ordered:NSWindowAbove];
// Re-parent children windows in the desired order.
for (auto [ordered_index, child] : ordered_children) {
if (child != child_window && child != other_window) {
[parent addChildWindow:child ordered:NSWindowAbove];
} else if (child == other_window && !relative_to_parent) {
[parent addChildWindow:other_window ordered:NSWindowAbove];
[parent addChildWindow:child_window ordered:NSWindowAbove];
}
}
}
} // namespace
NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
@@ -390,7 +431,12 @@ void NativeWindowMac::Close() {
}
// Ensure we're detached from the parent window before closing.
RemoveChildFromParentWindow(this);
RemoveChildFromParentWindow();
while (!child_windows_.empty()) {
auto* child = child_windows_.back();
child->RemoveChildFromParentWindow();
}
// If a sheet is attached to the window when we call
// [window_ performClose:nil], the window won't close properly
@@ -409,13 +455,20 @@ void NativeWindowMac::Close() {
}
void NativeWindowMac::CloseImmediately() {
RemoveChildFromParentWindow(this);
// Ensure we're detached from the parent window before closing.
RemoveChildFromParentWindow();
// Retain the child window before closing it. If the last reference to the
// NSWindow goes away inside -[NSWindow close], then bad stuff can happen.
// See e.g. http://crbug.com/616701.
base::scoped_nsobject<NSWindow> child_window(window_,
base::scoped_policy::RETAIN);
while (!child_windows_.empty()) {
auto* child = child_windows_.back();
child->RemoveChildFromParentWindow();
}
[window_ close];
}
@@ -604,9 +657,11 @@ void NativeWindowMac::RemoveChildWindow(NativeWindow* child) {
[window_ removeChildWindow:child->GetNativeWindow().GetNativeNSWindow()];
}
void NativeWindowMac::RemoveChildFromParentWindow(NativeWindow* child) {
if (parent())
parent()->RemoveChildWindow(child);
void NativeWindowMac::RemoveChildFromParentWindow() {
if (parent() && !is_modal()) {
parent()->RemoveChildWindow(this);
NativeWindow::SetParentWindow(nullptr);
}
}
void NativeWindowMac::AttachChildren() {
@@ -760,19 +815,41 @@ bool NativeWindowMac::MoveAbove(const std::string& sourceId) {
if (!webrtc::GetWindowOwnerPid(window_id))
return false;
[window_ orderWindow:NSWindowAbove relativeTo:id.id];
if (!parent() || is_modal()) {
[window_ orderWindow:NSWindowAbove relativeTo:window_id];
} else {
NSWindow* other_window = [NSApp windowWithWindowNumber:window_id];
ReorderChildWindowAbove(window_, other_window);
}
return true;
}
void NativeWindowMac::MoveTop() {
[window_ orderWindow:NSWindowAbove relativeTo:0];
if (!parent() || is_modal()) {
[window_ orderWindow:NSWindowAbove relativeTo:0];
} else {
ReorderChildWindowAbove(window_, nullptr);
}
}
void NativeWindowMac::SetResizable(bool resizable) {
ScopedDisableResize disable_resize;
SetStyleMask(resizable, NSWindowStyleMaskResizable);
bool was_fullscreenable = IsFullScreenable();
// Right now, resizable and fullscreenable are decoupled in
// documentation and on Windows/Linux. Chromium disables
// fullscreen collection behavior as well as the maximize traffic
// light in SetCanResize if resizability is false on macOS unless
// the window is both resizable and maximizable. We want consistent
// cross-platform behavior, so if resizability is disabled we disable
// the maximize button and ensure fullscreenability matches user setting.
SetCanResize(resizable);
SetFullScreenable(was_fullscreenable);
[[window_ standardWindowButton:NSWindowZoomButton]
setEnabled:resizable ? was_fullscreenable : false];
}
bool NativeWindowMac::IsResizable() {
@@ -1801,12 +1878,13 @@ void NativeWindowMac::InternalSetParentWindow(NativeWindow* new_parent,
return;
// Remove current parent window.
RemoveChildFromParentWindow(this);
RemoveChildFromParentWindow();
// Set new parent window.
if (new_parent && attach) {
if (new_parent) {
new_parent->add_child_window(this);
new_parent->AttachChildren();
if (attach)
new_parent->AttachChildren();
}
NativeWindow::SetParentWindow(new_parent);

View File

@@ -13,6 +13,7 @@
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/cxx17_backports.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -233,6 +234,10 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
if (title_bar_style_ != TitleBarStyle::kNormal)
set_has_frame(false);
// If the taskbar is re-created after we start up, we have to rebuild all of
// our buttons.
taskbar_created_message_ = RegisterWindowMessage(TEXT("TaskbarCreated"));
#endif
if (enable_larger_than_screen())
@@ -1439,8 +1444,7 @@ bool NativeWindowViews::IsVisibleOnAllWorkspaces() {
std::vector<x11::Atom> wm_states;
GetArrayProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
x11::GetAtom("_NET_WM_STATE"), &wm_states);
return std::find(wm_states.begin(), wm_states.end(), sticky_atom) !=
wm_states.end();
return base::Contains(wm_states, sticky_atom);
}
#endif
return false;

View File

@@ -315,6 +315,10 @@ class NativeWindowViews : public NativeWindow,
// Controls Overlay if enabled on Windows.
SkColor overlay_button_color_;
SkColor overlay_symbol_color_;
// The message ID of the "TaskbarCreated" message, sent to us when we need to
// reset our thumbar buttons.
UINT taskbar_created_message_ = 0;
#endif
// Handles unhandled keyboard messages coming back from the renderer process.

View File

@@ -221,6 +221,12 @@ bool NativeWindowViews::PreHandleMSG(UINT message,
return true;
}
if (message == taskbar_created_message_) {
// We need to reset all of our buttons because the taskbar went away.
taskbar_host_.RestoreThumbarButtons(GetAcceleratedWidget());
return true;
}
switch (message) {
// Screen readers send WM_GETOBJECT in order to get the accessibility
// object, so take this opportunity to push Chromium into accessible

View File

@@ -64,6 +64,11 @@ void CocoaNotification::Show(const NotificationOptions& options) {
options.reply_placeholder)];
}
// We need to explicitly set this to false if there are no
// actions, otherwise a Show button will appear by default.
if (options.actions.size() == 0)
[notification_ setHasActionButton:false];
int i = 0;
action_index_ = UINT_MAX;
NSMutableArray* additionalActions =
@@ -75,7 +80,6 @@ void CocoaNotification::Show(const NotificationOptions& options) {
// become additional actions.
if (!options.has_reply && action_index_ == UINT_MAX) {
// First button observed is the displayed action
[notification_ setHasActionButton:true];
[notification_
setActionButtonTitle:base::SysUTF16ToNSString(action.text)];
action_index_ = i;

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