Compare commits

..

76 Commits

Author SHA1 Message Date
trop[bot]
5955d53c48 build: fix telemetry error when using autoninja (#43571)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-09-05 12:01:25 +02:00
trop[bot]
3a5479aab6 fix: -Wunsafe-buffer-usage warnings in IsUrlArg() (#43541)
* fix: -Wunsafe-buffer-usage warnings in IsUrlArg()

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

* chore: improve code comments for CheckCommandLineArguments()

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

* chore: reduce diffs from main

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

* refactor: CheckCommandLineArguments takes a StringVector arg

Fixes another buffer warning!

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

* chore: use base::CommandLine::StringPieceType

base:CommandLine::StringViewType has not been invented yet

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-09-04 21:27:18 -05:00
trop[bot]
7b3143cc84 build: don't run symbol generation on PS (#43558)
fix: don't run symbol generation on PS

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
2024-09-04 20:19:33 -05:00
trop[bot]
d7816993b9 build: free up macos disk space as soon as possible (#43545)
* chore: free up macos disk space as soon as possible

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

* build: free up disk space on gn check too

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-09-04 08:33:56 -04:00
trop[bot]
01f11a9169 chore: speed up cache only reclient for fork PRs (#43503)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-08-30 20:25:30 -04:00
trop[bot]
d53ed0bcd7 chore: remove unused method asar::ClearArchives() (#43467)
chore: remove unused asar::ClearArchives()

last use removed in Jun 2021 (b1d1ac65, #29293)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-08-23 17:15:59 -05:00
trop[bot]
999860f569 fix: touch bar functionality on BaseWindow (#43419)
* fix: touch bar functionality on BaseWindow

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

* test: add test for BaseWindow.setTouchBar

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>
2024-08-22 15:43:51 +02:00
trop[bot]
b8a8fe115f refactor: move impl functions into private namespace (#43407)
* refactor: move into unnamed namespace: IsKillURL()

refactor: move into unnamed namespace: ResolvePossiblyRelativeURL()

refactor: move into unnamed namespace: AllowFileAccess()

refactor: move into unnamed namespace: PrepareURLForNavigation()

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

* refactor: move into unnamed namespace: GetMonitors()

refactor: move into unnamed namespace: GetEDIDProperty()

refactor: move into unnamed namespace: MonitorAtomIdToDisplayId()

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

* refactor: move into unnamed namespace: GetPermissionInfos() } refactor: move into unnamed namespace: GetPermissionAliases()

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

* refactor: move into unnamed namespace: OnOpenExternal()

refactor: move into unnamed namespace: HandleExternalProtocolInUI()

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

* refactor: move into unnamed namespace: BindMimeHandlerService()

refactor: move into unnamed namespace: BindBeforeUnloadControl()

refactor: move into unnamed namespace: BindBadgeServiceForServiceWorker()

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

* refactor: move into unnamed namespace: GetClientIdPath()

refactor: move into unnamed namespace: ReadClientId()

refactor: move into unnamed namespace: WriteClientId()

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

* refactor: move into unnamed namespace: HasExplicitLogFile()

refactor: move into unnamed namespace: DetermineLoggingDestination()

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

* refactor: move into unnamed namespace: GetArchiveCache()

refactor: move into unnamed namespace: GetArchiveCacheLock()

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

* refactor: move into unnamed namespace: GetParameters()

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

* refactor: move into unnamed namespace: GetDoomed()

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

* refactor: move into unnamed namespace: EncodeToken()

refactor: move into unnamed namespace: PortInfoToValue()

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>
2024-08-21 19:42:40 -05:00
trop[bot]
c50fa5486e chore: remove unused method Erase() (#43394)
chore: remove unused method Erase() (#43348)

Last use removed in Mar 2018 by 4b39d17e

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-08-21 12:29:25 -05:00
trop[bot]
3ad0eb0027 refactor: remove unused SetWMSpecState (#43395)
refactor: remove unused SetWMSpecState (#43347)

last use removed in Aug 2022 by 53cd2315 #35179

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-08-21 14:21:06 +02:00
trop[bot]
6619ad79d0 refactor: NodeBindings::Create() returns a unique_ptr (#43391)
refactor: NodeBindings::Create() returns a unique_ptr (#43361)

* refactor: NodeBindings::Create() returns a unique_ptr

* empty commit

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-08-21 14:20:40 +02:00
Keeley Hammond
b74089153a chore: cherry-pick 9797576 from v8 (#43387)
* chore: cherry-pick 9797576 from v8 (#43376)

* chore: update patches

---------

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-08-20 17:06:07 -07:00
Shelley Vohr
9fec618788 build: use smaller instances for gn-check (#43360)
build: use smaller instances for gn-check (#43187)

Co-authored-by: Samuel Attard <sam@electronjs.org>
2024-08-20 12:01:34 +02:00
electron-roller[bot]
55fd99488f chore: bump node to v20.16.0 (30-x-y) (#43025)
chore: bump node to v20.16.0

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-08-19 14:04:13 +02:00
trop[bot]
ff3d3e6944 feat: emit an event when accessing restricted path in File System Access API (#43162)
* fix: show a dialog when accessing restricted path in File System Access API

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

* fix: allow overriding initial blocked paths

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

* docs: fix doc

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

* Update docs/api/session.md

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

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

* fix: change block to deny for consistency

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>
2024-08-13 12:47:53 -04:00
trop[bot]
e39c0f9dae chore: remove unused Notification fields icon_path_, has_icon_ (#43296)
Last use of `icon_path_` was removed on May 29, 2017 (c741b584)
Last use of `has_icon_` was removed on May 30, 2017 (5048425e)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-08-12 12:56:00 +02:00
trop[bot]
35b75e2285 fix: accidental handle copying in a range loop (#43282)
fix: accidental handle copying

Xref: https://github.com/electron/electron/pull/37857

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-08-10 09:59:32 +02:00
trop[bot]
5e9a959eae fix: check screen capture permissions in desktopCapturer (#43272)
fix: check screen capture permissions in desktopCapturer

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-08-09 19:08:20 +02:00
trop[bot]
0a340b7f31 fix: system-context-menu with frameless BrowserWindows (#43275)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-08-09 19:05:08 +02:00
trop[bot]
b3e5978c27 docs: Document ideal iconPath size (#43240)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Felix Rieseberg <fr@makenotion.com>
2024-08-07 11:57:20 +02:00
trop[bot]
bce144aaf3 perf: avoid redundant calls to GetView() (#43230)
* perf: avoid double-calls to GetView()

There are a lot of places where we call the virtual method GetView()
twice in succession: the first to check if the view exists, and the
second to use. This PR holds the view in a temp variable instead, e.g.:

if (auto* view = foo->GetView())
  view->DoSomething();

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

* perf: avoid discarded GetView() call

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>
2024-08-06 19:23:51 -05:00
trop[bot]
5910d3f090 refactor: simplify window moveAbove/moveTop impl on macOS (#43203)
refactor: simplify window moveAbove/moveTop impl on macOS

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-08-06 16:42:19 -04:00
Pedro Pontes
b91a920128 chore: cherry-pick 1 changes from 1-M127 (#43167)
* chore: [30-x-y] cherry-pick 1 changes from 1-M127

* d9f7652c867c from chromium

* chore: e patches all

to make GH actions happy

---------

Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-08-06 12:07:49 -04:00
trop[bot]
a1342720ec perf: don't build unused vectors in HidChooserContext (#43212)
* refactor: remove unused code in HidChooserContext::DeviceRemoved()

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

* refactor: remove unused code in HidChooserContext::OnHidManagerConnectionError()

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

* refactor: use structured bindings for readability

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>
2024-08-05 12:54:21 -05:00
trop[bot]
53a6765fd6 fix: gin_helper::MicrotasksScope instantiation (#43208)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-08-05 10:16:22 -05:00
Pedro Pontes
3b45a30d2a chore: cherry-pick 3 changes from 0-M127 (#43159)
* chore: [30-x-y] cherry-pick 3 changes from 0-M127

* 44b7fbf35b10 from chromium
* c9815acd5a88 from dawn
* 9463ce9cd8d9 from DirectXShaderCompiler

* chore: e patches all

to make GH actions happy

---------

Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-08-02 14:54:14 +02:00
Keeley Hammond
1ec867c8a1 chore: cherry-pick 11 changes from 3-M126 (#43141)
* chore: [30-x-y] cherry-pick 11 changes from 3-M126

* d54105311590 from chromium
* 43b8b682d05c from chromium
* c5dd8839bfaf from chromium
* cdbc1d9684a3 from v8
* 38e4483e47f9 from chromium
* 70d2fe6b7c47 from v8
* 901377bb2f3b from v8
* 1b9040817119 from chromium
* bb28367eed73 from v8
* 99cafbf4b4b9 from chromium
* bc545b15a0ee from v8

* chore: update patches

* 5639725: [wasm] Fix scanning of wasm-to-js params | https://chromium-review.googlesource.com/c/v8/v8/+/5639725

* 5672472: [M120-LTS] Prevent script injection on reload when racing with a navigation | https://chromium-review.googlesource.com/c/chromium/src/+/5672472
2024-08-02 10:11:51 +02:00
trop[bot]
ec272f1e53 fix: take bluetooth serial ports into account in serial.getPorts() (#43171)
* fix: take bluetooth serial ports into account in serial.getPorts()

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

* chore: remove port.path.LossyDisplayName()

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>
2024-08-01 23:10:41 -07:00
trop[bot]
1914b92b8e chore: remove unused internal env.unSetVar() (#43174)
chore: remove unused unSetVar JS binding

Added in Oct 2020 (b33f2260, #25623) but never used

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-08-01 21:32:55 -05:00
trop[bot]
59e3c0b9aa fix: handle failing to enter fullscreen on macOS (#43151)
* fix: handle failing to enter/exit fullscreen on macOS

On macOS, failing to enter/exit fullscreen can fail. If this happens,
properly restore the original window state.

Co-authored-by: cptpcrd <31829097+cptpcrd@users.noreply.github.com>

* refactor: remove fail to exit fullscreen handlers

Seem to be unnecessary since the window exits fullscreen anyway.

Co-authored-by: cptpcrd <31829097+cptpcrd@users.noreply.github.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: cptpcrd <31829097+cptpcrd@users.noreply.github.com>
2024-08-01 14:50:48 +02:00
trop[bot]
67e49b202c fix: File System Access API should remember last picked directory (#43155)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-08-01 14:48:43 +02:00
Shelley Vohr
549e1a22e2 feat: add transparency checking to nativeTheme (#43138)
feat: add transparency checking to nativeTheme
2024-08-01 12:14:04 +02:00
trop[bot]
6a5ab8aa35 chore: remove unused KeyWeakMap JS bindings (#43145)
The last three pieces of code that used it were removed in:

- Oct 2020 (8df4faa8 #25711)
- Jun 2020 (e1e73fa5 #24115)
- Jun 2020 (c0182bca #24116).

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-07-31 19:37:31 -05:00
trop[bot]
81dbdeb832 docs: update Node.js stable release policy (#43135)
* docs: update Node.js stable release policy

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

* Update docs/tutorial/electron-timelines.md

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

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>
2024-07-31 10:03:22 -05:00
trop[bot]
0dd76c79a8 build: fixup ffmpeg release on x64 macOS (#43118)
chore: fixup arch on x64 macOS ffmpeg

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-07-30 19:28:19 -05:00
trop[bot]
b362e26261 chore: remove unused & undocumented function v8Util.deleteHiddenValue() (#43117)
chore: remove unused v8Util.deleteHiddenValue()

Its last use was removed in Nov 2020 by c8d77cae4a (#26659)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-07-30 18:19:11 -05:00
trop[bot]
d8b20376f9 chore: remove unused class electron::ObjectLifeMonitor (#43108)
chore: remove unused class `electron::ObjectLifeMonitor` (#43089)

The last users were removed in June 2020 e1e73fa5f (#24115)
and May 2020 9d7ba982 (#23592).

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-07-30 14:23:31 -05:00
trop[bot]
e5237eb2ce fix: always terminate active Node Streams (#43072)
`.destroy()` is an important method in the lifecycle of a Node.js
Readable stream. It is typically called to reclaim the resources
(e.g., close file descriptor). The only situations where calling
it manually isn't necessary are when the following events are
emitted first:

- `end`: natural end of a stream
- `error`: stream terminated due to a failure

Prior to this commit the ended state was incorrectly tracked together
with a pending internal error. It led to situations where the request
could get aborted during a read and then get marked as ended (having
pending error).

With this change we disentangle pending "error" and "destroyed" cases to
always properly terminate an active Node.js Readable stream.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
2024-07-27 14:46:47 -05:00
trop[bot]
fb5aa4660b chore: avoid crash while notification removal (#43059)
* avoid crash of operation on an invalid entry while erase set iterator.

Co-authored-by: bill.shen <shenyb32768@gmail.com>

* fix notification removal crash due to the nullptr presenter

Co-authored-by: bill.shen <shenyb32768@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: bill.shen <shenyb32768@gmail.com>
2024-07-26 19:40:34 -05:00
trop[bot]
78279119e2 docs: note macOS fullscreen events in fullscreen query (#43015)
docs: note macOS fullscreen events in fs query

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-07-23 16:57:40 -04:00
trop[bot]
bc12c6938a docs: improve desktop capture example (#43004)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-07-23 12:35:13 +02:00
Charles Kerr
b21d314d61 fix: dangling raw_ptr<Session> in UserDataLink (#42944)
fix: dangling raw_ptr<Session> in UserDataLink (#42786)

* fix: dangling raw_ptr<Session> in UserDataLink

* chore: make linter happy
2024-07-18 13:13:59 +02:00
trop[bot]
3c8b3fcff4 fix: crash when resolving proxy due to network service restart (#42896)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2024-07-17 16:27:33 -04:00
trop[bot]
daae931f40 feat: add getPercentComplete / getCurrentBytesPerSecond / getEndTime to DownloadItem (#42914)
feat: getCurrentSpeed / getPercentComplete / getEndTime on DownloadItem

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Theo Gravity <theo@suteki.nu>
2024-07-17 09:50:50 -07:00
trop[bot]
ff8c72d9ef fix: crash with creating OffScreenWebContentsView (#42939)
On the Mac platform, OffScreenWebContentsView uses Automatic Reference
Counting (ARC) to handle the lifecycle of offScreenView_. However, this
private member variable is not initialized and its value is undefined.
In some cases, it is initialized to a garbage value, which may cause ARC
to release the value incorrectly, resulting in a crash.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jinli Wu <wujinli@bytedance.com>
2024-07-17 17:51:22 +02:00
trop[bot]
0b067eae23 build: remove CircleCI (#42912)
build: remove CircleCI (#42844)

* build: remove CircleCI

* chore: remove remaining CircleCI references

(cherry picked from commit c006e129b3)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2024-07-17 09:49:45 -04:00
trop[bot]
3454ffb61e fix: getUserMedia needs macOS system permissions check (#42938)
fix: getUserMedia needs macOS system permissions check

Closes https://github.com/electron/electron/issues/42714
Closes https://github.com/electron/electron/issues/29861

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-07-17 15:18:03 +02:00
electron-roller[bot]
2298a3ac08 chore: bump node to v20.15.1 (30-x-y) (#42838)
* chore: bump node in DEPS to v20.15.1

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-07-17 13:20:20 +02:00
trop[bot]
627b46141c fix: iteration issues in hid RevokeEphemeralDevicePermission (#42902)
fix: iteration issues in hid RevokeEphemeralDevicePermission

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-07-16 12:33:15 +02:00
trop[bot]
7b777f949a build: update build-tools for GHA (#42874)
* chore: update build-tools for GHA

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

* build: fixup GHA running on fork PRs (#42880)

* chore: update build-tools for GHA

* chore: don't rely on environment variables for source cache location

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-07-15 12:40:07 -04:00
trop[bot]
d02f940039 chore: speed up azcopy on src cache (#42849)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-07-15 10:56:07 -04:00
Samuel Attard
1c3608c93b build: use new arc runner names (#42887)
build: use new arc runner names (#42881)
2024-07-13 12:12:42 -07:00
trop[bot]
9e9700fe60 ci: fix Nan test failure on Linux (#42866)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-07-11 16:20:33 -04:00
Shelley Vohr
900d328eac build: remove all publish & build on macOS (#42828)
* build: remove all publish & build on macOS

* ci: fix CircleCI config (#42829)

* ci: fix CircleCI config

* ci: fix syntax error

---------

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2024-07-11 16:10:52 -04:00
Shelley Vohr
52326a5ec7 refactor: run Windows SelectFileDialog out of process (#42826)
refactor: run Windows SelectFileDialog out of process
2024-07-10 15:35:17 +02:00
trop[bot]
c1741b90d7 build: fix release, add newVersion for tagging (#42846)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
2024-07-09 16:10:34 -07:00
trop[bot]
5271a49fe8 fix: video and audio capture should be separate (#42807)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-07-09 11:44:22 +02:00
trop[bot]
df6a3583cb fix: setTopBrowserView focus issue with reordering (#42735)
* fix: reorder top browser view instead of adding/removing

Co-authored-by: Alice Zhao <alice@makenotion.com>

* fix: update browserViews order

Co-authored-by: Alice Zhao <alice@makenotion.com>

* test: add a test for setTopBrowserView

Co-authored-by: Alice Zhao <alice@makenotion.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Alice Zhao <alice@makenotion.com>
2024-07-09 11:24:00 +02:00
trop[bot]
c85e4f01a9 fix: multiple move() calls on the same unique_ptr (#42819)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-07-09 10:35:36 +02:00
trop[bot]
83962f0604 feat: enable Windows Control Overlay on Linux (#42683)
* feat: enable Windows Control Overlay on Linux

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

* docs: update documentation for Linux WCO

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

* fix: initial symbol painting

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

* test: enable WCO tests for Linux

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

* fix: add missing Layer include

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

* chore: fix gn-check failure

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

* fix: enable BrowserWindow.setTitleBarOverlay on Linux

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

* test: fix test for maximize event on Linux

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

* fix: geometry updating on BrowserWindow.setTitleBarOverlay

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

* fix: crash when invalid titleBarStyle set

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

* chore: clean up ordering and comments

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

* Update docs/api/structures/base-window-options.md

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

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

* feat: enable customizing symbolColor

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

* docs: correct symbolColor reference

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

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>

* chore: remove Chrome-specific padding

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

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-07-04 11:28:44 +02:00
trop[bot]
a11c975a2d build: strip linux release binaries (#42743)
build: strip linux release binaries (#42675)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2024-07-02 13:54:30 +02:00
Keeley Hammond
7b7ac29f14 build: remove MacOS x64 from CircleCI (#42738) 2024-07-01 13:40:34 -04:00
Keeley Hammond
6fb815bc3c build: migrate to GitHub Actions (#42721)
* build: migrate to GitHub Actions

* build: use old clang-format binary path
2024-07-01 06:34:07 -04:00
Pedro Pontes
ccd682e837 chore: cherry-pick 5 changes from 2-M126 (#42693)
* chore: [30-x-y] cherry-pick 5 changes from 2-M126

* 5d4df51d1d7d from angle
* 771e74ab497d from DirectXShaderCompiler
* 8f07d39227f6 from DirectXShaderCompiler
* b3c64851765c from DirectXShaderCompiler
* d5217a718925 from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-07-01 09:56:33 +02:00
trop[bot]
332d7d5cda build: remove fs-extra devdep (#42711)
* build: remove fs-extra devdep

* build: remove fs-extra dependency from script/gen-filenames.ts

* build: remove fs-extra dependency from script/spec-runner.js

* build: remove fs-extra dependency from script/gn-asar.js

* build: remove fs-extra dependency from spec/api-autoupdater-darwin-spec.ts

* build: remove fs-extra dependency from spec/api-safe-storage-spec.ts

* build: remove fs-extra dependency from spec/lib/codesign-helpers.ts

* build: remove fs-extra dependency from spec/api-app-spec.ts

* build: remove fs-extra dependency from spec/esm-spec.ts

* build: remove fs-extra dependency from spec/lib/fs-helpers.ts

* build: remove fs-extra dependency from spec/lib/api-shell-spec.ts

* build: remove fs-extra dependency from spec/api-context-bridge-spec.ts

* build: remove fs-extra dependency from spec/asar-integrity-spec.ts

* build: remove fs-extra dependency from spec/node-spec.ts

* build: remove fs-extra devdiv

* fixup! build: remove fs-extra dependency from spec/api-context-bridge-spec.ts

* fix: use force: true when removing directories

* chore: reduce diffs to main

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

* empty commit to re-trigger appveyor

* empty commit to re-trigger appveyor

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2024-06-29 13:08:22 -05:00
trop[bot]
9c03e02608 build: remove klaw dependency (#42702)
* refactor: remove klaw dependency

Node 20 added recursive readdir() so klaw is not needed

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

* fixup! refactor: remove klaw dependency

findMatchingFiles returns a Promise<string[]>

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>
2024-06-28 12:22:29 -05:00
Charles Kerr
209a555a50 fix: potential null dereference in normalizeSpawnArguments() patch (#42698)
fix: potential null dereference in normalizeSpawnArguments() patch (#42260)

fix: potential null deref in normalizeSpawnArguments() patch

Use upstream's practice of using `env = options.env || process.env`.
Previously, we were unconditionally assigning CRASHDUMP_SIGNAL_FD
and CRASHPAD_HANDLER_PID to options.env.
2024-06-28 10:25:55 +02:00
Shelley Vohr
32ce192596 fix: defaultPath should apply on all dialog types in Linux Portal (#42687) 2024-06-27 19:49:53 +02:00
electron-roller[bot]
8b06e8a049 chore: bump node to v20.15.0 (30-x-y) (#42613)
* chore: bump node in DEPS to v20.15.0

* doc: Add OpenSSL errors to API docs

https://github.com/nodejs/node/pull/34213

* test: crypto-rsa-dsa testing for dynamic openssl

https://github.com/nodejs/node/pull/52781

* src: allow preventing debug signal handler start

https://github.com/nodejs/node/pull/46681

* cli: allow running wasm in limited vmemory with --disable-wasm-trap-handler

https://github.com/nodejs/node/pull/52766

* chore: fixup patch indices

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-06-27 15:58:45 +02:00
trop[bot]
803d1c687a fix: param passed to showSaveDialogSync on Linux (#42676)
fix: pass correct param to sync functions on Linux

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-06-27 14:38:53 +02:00
trop[bot]
f3cc8cb8a5 fix: utilityProcess exit codes (#42395)
* fix: utilityProcess exit codes

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

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-06-25 19:01:18 +02:00
Pedro Pontes
427b4aa273 chore: cherry-pick 3 changes from 1-M126 (#42617)
* chore: [30-x-y] cherry-pick 3 changes from 1-M126

* 8b400f9b7d66 from v8
* ba6cab40612d from v8
* 93c3cf1c787f from DirectXShaderCompiler

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-06-24 15:05:52 +02:00
Pedro Pontes
6a9ae16d76 chore: [30-x-y] cherry-pick 3 changes from 0-M126 (#42602)
* chore: [30-x-y] cherry-pick 3 changes from 0-M126

* 33051b084850 from DirectXShaderCompiler
* b845fed99111 from DirectXShaderCompiler
* 9c6534f82db3 from dawn

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-06-21 11:21:02 -04:00
trop[bot]
5dd6c0a51d feat: expose system preferences to utility process (#42600)
* chore: expose  system preferences to utility process

* chore: add tests, doc changes and module-list update

* relative link

* use @

* fix test

* chore: disable linux test

* kick

* noop on windows utility process

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: George Xu <33054982+georgexu99@users.noreply.github.com>
2024-06-20 16:32:34 -04:00
Pedro Pontes
9c293834f1 chore: [30-x-y] cherry-pick 2 changes from 3-M125 (#42590)
* d3cc351e0294 from libaom
 * ad697557950c from libaom
2024-06-20 20:27:48 +02:00
trop[bot]
f6966f6e35 fix: fetch-dependent interfaces in Web Workers (#42596)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-06-20 20:27:35 +02:00
254 changed files with 9316 additions and 4139 deletions

View File

@@ -1 +0,0 @@
config-staging

View File

@@ -1,79 +0,0 @@
version: 2.1
# Required for dynamic configuration
setup: true
# Orbs
orbs:
path-filtering: circleci/path-filtering@0.1.0
continuation: circleci/continuation@0.2.0
# All input parameters to pass to build config
parameters:
run-docs-only:
type: boolean
default: false
upload-to-storage:
type: string
default: '1'
run-build-linux:
type: boolean
default: false
run-build-mac:
type: boolean
default: false
run-linux-publish:
type: boolean
default: false
linux-publish-arch-limit:
type: enum
default: all
enum: ["all", "arm", "arm64", "x64", "ia32"]
run-macos-publish:
type: boolean
default: false
macos-publish-arch-limit:
type: enum
default: all
enum: ["all", "osx-x64", "osx-arm64", "mas-x64", "mas-arm64"]
jobs:
generate-config:
docker:
- image: cimg/node:16.14
steps:
- checkout
- path-filtering/set-parameters:
base-revision: main
mapping: |
^((?!docs/).)*$ run-build-mac true
^((?!docs/).)*$ run-build-linux true
docs/.* run-docs-only true
^((?!docs/).)*$ run-docs-only false
- run:
command: |
cd .circleci/config
yarn
export CIRCLECI_BINARY="$HOME/circleci"
curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/main/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
# Initial setup workflow
workflows:
setup:
jobs:
- generate-config

File diff suppressed because it is too large Load Diff

View File

@@ -1,34 +0,0 @@
const cp = require('child_process');
const fs = require('fs-extra');
const path = require('path');
const yaml = require('js-yaml');
const STAGING_DIR = path.resolve(__dirname, '..', 'config-staging');
function copyAndExpand(dir = './') {
const absDir = path.resolve(__dirname, dir);
const targetDir = path.resolve(STAGING_DIR, dir);
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir);
}
for (const file of fs.readdirSync(absDir)) {
if (!file.endsWith('.yml')) {
if (fs.statSync(path.resolve(absDir, file)).isDirectory()) {
copyAndExpand(path.join(dir, file));
}
continue;
}
fs.writeFileSync(path.resolve(targetDir, file), yaml.dump(yaml.load(fs.readFileSync(path.resolve(absDir, file), 'utf8')), {
noRefs: true,
}));
}
}
if (fs.pathExists(STAGING_DIR)) fs.removeSync(STAGING_DIR);
copyAndExpand();
const output = cp.spawnSync(process.env.CIRCLECI_BINARY || 'circleci', ['config', 'pack', STAGING_DIR]);
fs.writeFileSync(path.resolve(STAGING_DIR, 'built.yml'), output.stdout.toString());

View File

@@ -1,10 +0,0 @@
{
"name": "@electron/circleci-config",
"version": "0.0.0",
"private": true,
"license": "MIT",
"dependencies": {
"fs-extra": "^10.1.0",
"js-yaml": "^4.1.0"
}
}

View File

@@ -1,12 +0,0 @@
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

@@ -1,43 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
fs-extra@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
universalify "^2.0.0"
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
jsonfile@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
dependencies:
universalify "^2.0.0"
optionalDependencies:
graceful-fs "^4.1.6"
universalify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==

View File

@@ -1,8 +0,0 @@
#!/bin/bash
set -e
mkdir -p ~/.ssh
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

@@ -40,7 +40,6 @@
"dbaeumer.vscode-eslint",
"shakram02.bash-beautify",
"marshallofsound.gnls-electron",
"CircleCI.circleci"
],
"settings": {
"editor.tabSize": 2,

View File

@@ -2,5 +2,4 @@
# See docs/development/releasing.md
APPVEYOR_CLOUD_TOKEN=
CIRCLE_TOKEN=
ELECTRON_GITHUB_TOKEN=

View File

@@ -0,0 +1,220 @@
name: 'Build Electron'
description: 'Builds Electron & Friends'
inputs:
target-arch:
description: 'Target arch'
required: true
target-platform:
description: 'Target platform'
required: true
artifact-platform:
description: 'Artifact platform, should be linux, darwin or mas'
required: true
step-suffix:
description: 'Suffix for build steps'
required: false
default: ''
is-release:
description: 'Is release build'
required: true
strip-binaries:
description: 'Strip binaries (Linux only)'
required: false
generate-symbols:
description: 'Generate symbols'
required: true
upload-to-storage:
description: 'Upload to storage'
required: true
is-asan:
description: 'The ASan Linux build'
required: false
runs:
using: "composite"
steps:
- name: Set GN_EXTRA_ARGS for MacOS x64 Builds
shell: bash
if: ${{ inputs.target-arch == 'x64' && inputs.target-platform == 'macos' }}
run: |
GN_APPENDED_ARGS="$GN_EXTRA_ARGS target_cpu=\"x64\" v8_snapshot_toolchain=\"//build/toolchain/mac:clang_x64\""
echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
- name: Build Electron ${{ inputs.step-suffix }}
shell: bash
run: |
rm -rf "src/out/Default/Electron Framework.framework"
rm -rf src/out/Default/Electron*.app
cd src/electron
# TODO(codebytere): remove this once we figure out why .git/packed-refs is initially missing
git pack-refs
cd ..
if [ "`uname`" = "Darwin" ]; then
ulimit -n 10000
sudo launchctl limit maxfiles 65536 200000
fi
NINJA_SUMMARIZE_BUILD=1 e build -j $NUMBER_OF_NINJA_PROCESSES
cp out/Default/.ninja_log out/electron_ninja_log
node electron/script/check-symlinks.js
- name: Strip Electron Binaries ${{ inputs.step-suffix }}
shell: bash
if: ${{ inputs.strip-binaries == 'true' }}
run: |
cd src
electron/script/copy-debug-symbols.py --target-cpu="${{ inputs.target-arch }}" --out-dir=out/Default/debug --compress
electron/script/strip-binaries.py --target-cpu="${{ inputs.target-arch }}"
electron/script/add-debug-link.py --target-cpu="${{ inputs.target-arch }}" --debug-dir=out/Default/debug
- name: Build Electron dist.zip ${{ inputs.step-suffix }}
shell: bash
run: |
cd src
e build electron:electron_dist_zip -j $NUMBER_OF_NINJA_PROCESSES
if [ "${{ inputs.is-asan }}" != "true" ]; then
target_os=${{ inputs.target-platform == 'linux' && 'linux' || 'mac'}}
if [ "${{ inputs.artifact-platform }}" = "mas" ]; then
target_os="${target_os}_mas"
fi
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.${{ inputs.target-arch }}.manifest
fi
- name: Build Mksnapshot ${{ inputs.step-suffix }}
shell: bash
run: |
cd src
e build electron:electron_mksnapshot -j $NUMBER_OF_NINJA_PROCESSES
gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
# Remove unused args from mksnapshot_args
SEDOPTION="-i"
if [ "`uname`" = "Darwin" ]; then
SEDOPTION="-i ''"
fi
sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
sed $SEDOPTION '/The gn arg use_goma=true .*/d' out/Default/mksnapshot_args
if [ "`uname`" = "Linux" ]; then
if [ "${{ inputs.target-arch }}" = "arm" ]; then
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x86_v8_arm/mksnapshot
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x86_v8_arm/v8_context_snapshot_generator
elif [ "${{ inputs.target-arch }}" = "arm64" ]; then
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x64_v8_arm64/mksnapshot
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x64_v8_arm64/v8_context_snapshot_generator
else
electron/script/strip-binaries.py --file $PWD/out/Default/mksnapshot
electron/script/strip-binaries.py --file $PWD/out/Default/v8_context_snapshot_generator
fi
fi
e build electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
(cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
- name: Generate Cross-Arch Snapshot (arm/arm64) ${{ inputs.step-suffix }}
shell: bash
if: ${{ (inputs.target-arch == 'arm' || inputs.target-arch == 'arm64') && inputs.target-platform == 'linux' }}
run: |
cd src
if [ "${{ inputs.target-arch }}" = "arm" ]; then
MKSNAPSHOT_PATH="clang_x86_v8_arm"
elif [ "${{ inputs.target-arch }}" = "arm64" ]; then
MKSNAPSHOT_PATH="clang_x64_v8_arm64"
fi
cp "out/Default/$MKSNAPSHOT_PATH/mksnapshot" out/Default
cp "out/Default/$MKSNAPSHOT_PATH/v8_context_snapshot_generator" out/Default
cp "out/Default/$MKSNAPSHOT_PATH/libffmpeg.so" out/Default
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
mkdir cross-arch-snapshots
cp out/Default-mksnapshot-test/*.bin cross-arch-snapshots
# Clean up so that ninja does not get confused
rm -f out/Default/libffmpeg.so
- name: Build Chromedriver ${{ inputs.step-suffix }}
shell: bash
run: |
cd src
e build electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
e build electron:electron_chromedriver_zip
- name: Build Node.js headers ${{ inputs.step-suffix }}
shell: bash
run: |
cd src
e build electron:node_headers
- name: Generate & Zip Symbols ${{ inputs.step-suffix }}
shell: bash
run: |
# Generate breakpad symbols on release builds
if [ "${{ inputs.generate-symbols }}" = "true" ]; then
e build electron:electron_symbols
fi
cd src
export BUILD_PATH="$(pwd)/out/Default"
e build electron:licenses
e build electron:electron_version_file
if [ "${{ inputs.is-release }}" = "true" ]; then
DELETE_DSYMS_AFTER_ZIP=1 electron/script/zip-symbols.py -b $BUILD_PATH
else
electron/script/zip-symbols.py -b $BUILD_PATH
fi
- name: Generate FFMpeg ${{ inputs.step-suffix }}
shell: bash
if: ${{ inputs.is-release == 'true' }}
run: |
cd src
gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true $GN_EXTRA_ARGS"
autoninja -C out/ffmpeg electron:electron_ffmpeg_zip -j $NUMBER_OF_NINJA_PROCESSES
- name: Generate Hunspell Dictionaries ${{ inputs.step-suffix }}
shell: bash
if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'linux' }}
run: |
cd src
autoninja -C out/Default electron:hunspell_dictionaries_zip -j $NUMBER_OF_NINJA_PROCESSES
- name: Generate Libcxx ${{ inputs.step-suffix }}
shell: bash
if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'linux' }}
run: |
cd src
autoninja -C out/Default electron:libcxx_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
autoninja -C out/Default electron:libcxxabi_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
autoninja -C out/Default electron:libcxx_objects_zip -j $NUMBER_OF_NINJA_PROCESSES
- name: Generate TypeScript Definitions ${{ inputs.step-suffix }}
if: ${{ inputs.is-release == 'true' }}
shell: bash
run: |
cd src/electron
node script/yarn create-typescript-definitions
- name: Publish Electron Dist ${{ inputs.step-suffix }}
if: ${{ inputs.is-release == 'true' }}
shell: bash
run: |
rm -rf src/out/Default/obj
cd src/electron
if [ "${{ inputs.upload-to-storage }}" = "1" ]; then
echo 'Uploading Electron release distribution to Azure'
script/release/uploaders/upload.py --verbose --upload_to_storage
else
echo 'Uploading Electron release distribution to GitHub releases'
script/release/uploaders/upload.py --verbose
fi
- name: Generate Artifact Key
shell: bash
run: |
if [ "${{ inputs.is-asan }}" = "true" ]; then
ARTIFACT_KEY=${{ inputs.artifact-platform }}_${{ inputs.target-arch }}_asan
else
ARTIFACT_KEY=${{ inputs.artifact-platform }}_${{ inputs.target-arch }}
fi
echo "ARTIFACT_KEY=$ARTIFACT_KEY" >> $GITHUB_ENV
# The current generated_artifacts_<< artifact.key >> name was taken from CircleCI
# to ensure we don't break anything, but we may be able to improve that.
- name: Move all Generated Artifacts to Upload Folder ${{ inputs.step-suffix }}
shell: bash
run: ./src/electron/script/actions/move-artifacts.sh
- name: Upload Generated Artifacts ${{ inputs.step-suffix }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
with:
name: generated_artifacts_${{ env.ARTIFACT_KEY }}
path: ./generated_artifacts_${{ inputs.artifact-platform }}_${{ inputs.target-arch }}
- name: Upload Src Artifacts ${{ inputs.step-suffix }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
with:
name: src_artifacts_${{ env.ARTIFACT_KEY }}
path: ./src_artifacts_${{ inputs.artifact-platform }}_${{ inputs.target-arch }}

155
.github/actions/checkout/action.yml vendored Normal file
View File

@@ -0,0 +1,155 @@
name: 'Checkout'
description: 'Checks out Electron and stores it in the AKS Cache'
inputs:
generate-sas-token:
description: 'Whether to generate and persist a SAS token for the item in the cache'
required: false
default: 'false'
runs:
using: "composite"
steps:
- name: Set GIT_CACHE_PATH to make gclient to use the cache
shell: bash
run: |
echo "GIT_CACHE_PATH=$(pwd)/git-cache" >> $GITHUB_ENV
- name: Install Dependencies
shell: bash
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Get Depot Tools
shell: bash
run: |
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
# Remove swift-format dep from cipd on macOS until we send a patch upstream.
cd depot_tools
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
touch .disable_auto_update
- name: Add Depot Tools to PATH
shell: bash
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Generate DEPS Hash
shell: bash
run: |
node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
echo "DEPSHASH=v1-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')" >> $GITHUB_ENV
- name: Generate SAS Key
if: ${{ inputs.generate-sas-token == 'true' }}
shell: bash
run: |
curl --unix-socket /var/run/sas/sas.sock --fail "http://foo/$DEPSHASH.tar" > sas-token
- name: Save SAS Key
if: ${{ inputs.generate-sas-token == 'true' }}
uses: actions/cache/save@v4
with:
path: |
sas-token
key: sas-key-${{ github.run_number }}-${{ github.run_attempt }}
- name: Check If Cache Exists
id: check-cache
shell: bash
run: |
cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
echo "Using cache key: $DEPSHASH"
echo "Checking for cache in: $cache_path"
if [ ! -f "$cache_path" ]; then
echo "cache_exists=false" >> $GITHUB_OUTPUT
echo "Cache Does Not Exist for $DEPSHASH"
else
echo "cache_exists=true" >> $GITHUB_OUTPUT
echo "Cache Already Exists for $DEPSHASH, Skipping.."
fi
- name: Gclient Sync
if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash
run: |
gclient config \
--name "src/electron" \
--unmanaged \
${GCLIENT_EXTRA_ARGS} \
"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY"
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags -vvvvv
if [ "${{ inputs.is-release }}" != "true" ]; then
# Re-export all the patches to check if there were changes.
python3 src/electron/script/export_all_patches.py src/electron/patches/config.json
cd src/electron
git update-index --refresh || true
if ! git diff-index --quiet HEAD --; then
# There are changes to the patches. Make a git commit with the updated patches
git add patches
GIT_COMMITTER_NAME="PatchUp" GIT_COMMITTER_EMAIL="73610968+patchup[bot]@users.noreply.github.com" git commit -m "chore: update patches" --author="PatchUp <73610968+patchup[bot]@users.noreply.github.com>"
# Export it
mkdir -p ../../patches
git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
if (node ./script/push-patch.js 2> /dev/null > /dev/null); then
echo
echo "======================================================================"
echo "Changes to the patches when applying, we have auto-pushed the diff to the current branch"
echo "A new CI job will kick off shortly"
echo "======================================================================"
exit 1
else
echo
echo "======================================================================"
echo "There were changes to the patches when applying."
echo "Check the CI artifacts for a patch you can apply to fix it."
echo "======================================================================"
cat ../../patches/update-patches.patch
exit 1
fi
fi
fi
# delete all .git directories under src/ except for
# third_party/angle/ and third_party/dawn/ because of build time generation of files
# gen/angle/commit.h depends on third_party/angle/.git/HEAD
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
# and dawn/common/Version_autogen.h depends on third_party/dawn/.git/HEAD
# https://dawn-review.googlesource.com/c/dawn/+/83901
# TODO: maybe better to always leave out */.git/HEAD file for all targets ?
- name: Delete .git directories under src to free space
if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash
run: |
cd src
( find . -type d -name ".git" -not -path "./third_party/angle/*" -not -path "./third_party/dawn/*" -not -path "./electron/*" ) | xargs rm -rf
- name: Minimize Cache Size for Upload
if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash
run: |
rm -rf src/android_webview
rm -rf src/ios/chrome
rm -rf src/third_party/blink/web_tests
rm -rf src/third_party/blink/perf_tests
rm -rf src/chrome/test/data/xr/webvr_info
rm -rf src/third_party/angle/third_party/VK-GL-CTS/src
rm -rf src/third_party/swift-toolchain
rm -rf src/third_party/swiftshader/tests/regres/testlists
rm -rf src/electron
- name: Compress Src Directory
if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash
run: |
echo "Uncompressed src size: $(du -sh src | cut -f1 -d' ')"
tar -cf $DEPSHASH.tar src
echo "Compressed src to $(du -sh $DEPSHASH.tar | cut -f1 -d' ')"
cp ./$DEPSHASH.tar /mnt/cross-instance-cache/
- name: Persist Src Cache
if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash
run: |
final_cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
echo "Using cache key: $DEPSHASH"
echo "Checking path: $final_cache_path"
if [ ! -f "$final_cache_path" ]; then
echo "Cache key not found"
exit 1
else
echo "Cache key persisted in $final_cache_path"
fi

View File

@@ -0,0 +1,61 @@
name: 'Fix Sync macOS'
description: 'Checks out Electron and stores it in the AKS Cache'
runs:
using: "composite"
steps:
- name: Fix Sync
shell: bash
# This step is required to correct for differences between "gclient sync"
# on Linux and the expected state on macOS. This requires:
# 1. Fixing Clang Install (wrong binary)
# 2. Fixing esbuild (wrong binary)
# 3. Fixing rustc (wrong binary)
# 4. Fixing gn (wrong binary)
# 5. Fix reclient (wrong binary)
# 6. Fixing dsymutil (wrong binary)
# 7. Ensuring we are using the correct ninja and adding it to PATH
# 8. Fixing angle (wrong remote)
run : |
SEDOPTION="-i ''"
rm -rf src/third_party/llvm-build
python3 src/tools/clang/scripts/update.py
echo 'infra/3pp/tools/esbuild/${platform}' `gclient getdep --deps-file=src/third_party/devtools-frontend/src/DEPS -r 'third_party/esbuild:infra/3pp/tools/esbuild/${platform}'` > esbuild_ensure_file
# Remove extra output from calling gclient getdep which always calls update_depot_tools
sed -i '' "s/Updating depot_tools... //g" esbuild_ensure_file
cipd ensure --root src/third_party/devtools-frontend/src/third_party/esbuild -ensure-file esbuild_ensure_file
rm -rf src/third_party/rust-toolchain
python3 src/tools/rust/update_rust.py
# Prevent calling gclient getdep which always calls update_depot_tools
echo 'gn/gn/mac-${arch}' `gclient getdep --deps-file=src/DEPS -r 'src/buildtools/mac:gn/gn/mac-${arch}'` > gn_ensure_file
sed -i '' "s/Updating depot_tools... //g" gn_ensure_file
cipd ensure --root src/buildtools/mac -ensure-file gn_ensure_file
# Prevent calling gclient getdep which always calls update_depot_tools
echo 'infra/rbe/client/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/buildtools/reclient:infra/rbe/client/${platform}'` > gn_ensure_file
sed -i '' "s/Updating depot_tools... //g" gn_ensure_file
cipd ensure --root src/buildtools/reclient -ensure-file gn_ensure_file
python3 src/buildtools/reclient_cfgs/configure_reclient_cfgs.py --rbe_instance "projects/rbe-chrome-untrusted/instances/default_instance" --reproxy_cfg_template reproxy.cfg.template --rewrapper_cfg_project "" --skip_remoteexec_cfg_fetch
if [ "${{ env.TARGET_ARCH }}" == "arm64" ]; then
DSYM_SHA_FILE=src/tools/clang/dsymutil/bin/dsymutil.arm64.sha1
else
DSYM_SHA_FILE=src/tools/clang/dsymutil/bin/dsymutil.x64.sha1
fi
python3 src/third_party/depot_tools/download_from_google_storage.py --no_resume --no_auth --bucket chromium-browser-clang -s $DSYM_SHA_FILE -o src/tools/clang/dsymutil/bin/dsymutil
echo 'infra/3pp/tools/ninja/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/third_party/ninja:infra/3pp/tools/ninja/${platform}'` > ninja_ensure_file
sed $SEDOPTION "s/Updating depot_tools... //g" ninja_ensure_file
cipd ensure --root src/third_party/ninja -ensure-file ninja_ensure_file
echo "$(pwd)/src/third_party/ninja" >> $GITHUB_PATH
cd src/third_party/angle
rm -f .git/objects/info/alternates
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
cp .git/config .git/config.backup
git remote remove origin
mv .git/config.backup .git/config
git fetch

View File

@@ -0,0 +1,65 @@
name: 'Free Space macOS'
description: 'Checks out Electron and stores it in the AKS Cache'
runs:
using: "composite"
steps:
- name: Free Space on MacOS
shell: bash
run: |
sudo mkdir -p $TMPDIR/del-target
tmpify() {
if [ -d "$1" ]; then
sudo mv "$1" $TMPDIR/del-target/$(echo $1|shasum -a 256|head -n1|cut -d " " -f1)
fi
}
strip_universal_deep() {
opwd=$(pwd)
cd $1
f=$(find . -perm +111 -type f)
for fp in $f
do
if [[ $(file "$fp") == *"universal binary"* ]]; then
if [ "`arch`" == "arm64" ]; then
if [[ $(file "$fp") == *"x86_64"* ]]; then
sudo lipo -remove x86_64 "$fp" -o "$fp" || true
fi
else
if [[ $(file "$fp") == *"arm64e)"* ]]; then
sudo lipo -remove arm64e "$fp" -o "$fp" || true
fi
if [[ $(file "$fp") == *"arm64)"* ]]; then
sudo lipo -remove arm64 "$fp" -o "$fp" || true
fi
fi
fi
done
cd $opwd
}
tmpify /Library/Developer/CoreSimulator
tmpify ~/Library/Developer/CoreSimulator
tmpify $(xcode-select -p)/Platforms/AppleTVOS.platform
tmpify $(xcode-select -p)/Platforms/iPhoneOS.platform
tmpify $(xcode-select -p)/Platforms/WatchOS.platform
tmpify $(xcode-select -p)/Platforms/WatchSimulator.platform
tmpify $(xcode-select -p)/Platforms/AppleTVSimulator.platform
tmpify $(xcode-select -p)/Platforms/iPhoneSimulator.platform
tmpify $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/metal/ios
tmpify $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift
tmpify $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.0
tmpify ~/.rubies
tmpify ~/Library/Caches/Homebrew
tmpify /usr/local/Homebrew
sudo rm -rf $TMPDIR/del-target
sudo rm -rf /Applications/Safari.app
sudo rm -rf ~/project/src/third_party/catapult/tracing/test_data
sudo rm -rf ~/project/src/third_party/angle/third_party/VK-GL-CTS
# lipo off some huge binaries arm64 versions to save space
strip_universal_deep $(xcode-select -p)/../SharedFrameworks
# strip_arm_deep /System/Volumes/Data/Library/Developer/CommandLineTools/usr

View File

@@ -0,0 +1,11 @@
name: 'Install Build Tools'
description: 'Installs an exact SHA of build tools'
runs:
using: "composite"
steps:
- name: Install Build Tools
shell: bash
run: |
export BUILD_TOOLS_SHA=d5b87591842be19058e8d75d2c5b7f1fabe9f450
npm i -g @electron/build-tools
e auto-update disable

View File

@@ -0,0 +1,36 @@
name: 'Restore Cache AKS'
description: 'Restores Electron src cache via AKS'
runs:
using: "composite"
steps:
- name: Restore and Ensure Src Cache
shell: bash
run: |
cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
echo "Using cache key: $DEPSHASH"
echo "Checking for cache in: $cache_path"
if [ ! -f "$cache_path" ]; then
echo "Cache Does Not Exist for $DEPSHASH - exiting"
exit 1
else
echo "Found Cache for $DEPSHASH at $cache_path"
fi
echo "Persisted cache is $(du -sh $cache_path | cut -f1)"
mkdir temp-cache
tar -xf $cache_path -C temp-cache
echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"
if [ -d "temp-cache/src" ]; then
echo "Relocating Cache"
rm -rf src
mv temp-cache/src src
fi
if [ ! -d "src/third_party/blink" ]; then
echo "Cache was not correctly restored - exiting"
exit 1
fi
echo "Wiping Electron Directory"
rm -rf src/electron

View File

@@ -0,0 +1,66 @@
name: 'Restore Cache AZCopy'
description: 'Restores Electron src cache via AZCopy'
runs:
using: "composite"
steps:
- name: Obtain SAS Key
continue-on-error: true
uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
with:
path: |
sas-token
key: sas-key-${{ github.run_number }}-1
- name: Obtain SAS Key
continue-on-error: true
uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
with:
path: |
sas-token
key: sas-key-${{ github.run_number }}-${{ github.run_attempt }}
- name: Download Src Cache from AKS
# The cache will always exist here as a result of the checkout job
# Either it was uploaded to Azure in the checkout job for this commit
# or it was uploaded in the checkout job for a previous commit.
uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0
with:
timeout_minutes: 30
max_attempts: 3
retry_on: error
command: |
sas_token=$(cat sas-token)
if [ -z $sas-token ]; then
echo "SAS Token not found; exiting src cache download early..."
exit 1
fi
azcopy copy --log-level=ERROR \
"https://${{ env.AZURE_AKS_CACHE_STORAGE_ACCOUNT }}.file.core.windows.net/${{ env.AZURE_AKS_CACHE_SHARE_NAME }}/${{ env.CACHE_PATH }}?$sas_token" $DEPSHASH.tar
env:
AZURE_AKS_CACHE_STORAGE_ACCOUNT: f723719aa87a34622b5f7f3
AZURE_AKS_CACHE_SHARE_NAME: pvc-f6a4089f-b082-4bee-a3f9-c3e1c0c02d8f
- name: Clean SAS Key
shell: bash
run: rm -f sas-token
- name: Unzip and Ensure Src Cache
shell: bash
run: |
echo "Downloaded cache is $(du -sh $DEPSHASH.tar | cut -f1)"
mkdir temp-cache
tar -xf $DEPSHASH.tar -C temp-cache
echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"
if [ -d "temp-cache/src" ]; then
echo "Relocating Cache"
rm -rf src
mv temp-cache/src src
echo "Deleting zip file"
rm -rf $DEPSHASH.tar
fi
if [ ! -d "src/third_party/blink" ]; then
echo "Cache was not correctly restored - exiting"
exit 1
fi
echo "Wiping Electron Directory"
rm -rf src/electron

251
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,251 @@
name: Build
on:
workflow_dispatch:
inputs:
build-image-sha:
type: string
description: 'SHA for electron/build image'
default: 'cf814a4d2501e8e843caea071a6b70a48e78b855'
required: true
skip-macos:
type: boolean
description: 'Skip macOS builds'
default: false
required: false
skip-linux:
type: boolean
description: 'Skip Linux builds'
default: false
required: false
skip-lint:
type: boolean
description: 'Skip lint check'
default: false
required: false
push:
branches:
- main
- '[1-9][0-9]-x-y'
pull_request:
jobs:
setup:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
docs: ${{ steps.filter.outputs.docs }}
src: ${{ steps.filter.outputs.src }}
build-image-sha: ${{ steps.set-output.outputs.build-image-sha }}
docs-only: ${{ steps.set-output.outputs.docs-only }}
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.0.2
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
filters: |
docs:
- 'docs/**'
src:
- '!docs/**'
- name: Set Outputs for Build Image SHA & Docs Only
id: set-output
run: |
if [ -z "${{ inputs.build-image-sha }}" ]; then
echo "build-image-sha=cf814a4d2501e8e843caea071a6b70a48e78b855" >> "$GITHUB_OUTPUT"
else
echo "build-image-sha=${{ inputs.build-image-sha }}" >> "$GITHUB_OUTPUT"
fi
echo "docs-only=${{ steps.filter.outputs.docs == 'true' && steps.filter.outputs.src == 'false' }}" >> "$GITHUB_OUTPUT"
# Lint Jobs
lint:
needs: setup
if: ${{ !inputs.skip-lint }}
uses: ./.github/workflows/pipeline-electron-lint.yml
with:
container: '{"image":"ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}","options":"--user root"}'
secrets: inherit
# Docs Only Jobs
docs-only:
needs: setup
if: ${{ needs.setup.outputs.docs-only == 'true' }}
uses: ./.github/workflows/pipeline-electron-docs-only.yml
with:
container: '{"image":"ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}","options":"--user root"}'
secrets: inherit
# Checkout Jobs
checkout-macos:
needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-macos}}
runs-on: electron-arc-linux-amd64-32core
container:
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
- /var/run/sas:/var/run/sas
env:
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
outputs:
build-image-sha: ${{ needs.setup.outputs.build-image-sha }}
steps:
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Checkout & Sync & Save
uses: ./src/electron/.github/actions/checkout
with:
generate-sas-token: 'true'
checkout-linux:
needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-linux}}
runs-on: electron-arc-linux-amd64-32core
container:
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
- /var/run/sas:/var/run/sas
env:
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
outputs:
build-image-sha: ${{ needs.setup.outputs.build-image-sha}}
steps:
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Checkout & Sync & Save
uses: ./src/electron/.github/actions/checkout
# Build Jobs - These cascade into testing jobs
macos-x64:
permissions:
contents: read
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-macos
with:
build-runs-on: macos-14-xlarge
check-runs-on: macos-14
test-runs-on: macos-13
target-platform: macos
target-arch: x64
is-release: false
gn-build-type: testing
generate-symbols: false
upload-to-storage: '0'
secrets: inherit
macos-arm64:
permissions:
contents: read
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-macos
with:
build-runs-on: macos-14-xlarge
check-runs-on: macos-14
test-runs-on: macos-14
target-platform: macos
target-arch: arm64
is-release: false
gn-build-type: testing
generate-symbols: false
upload-to-storage: '0'
secrets: inherit
linux-x64:
permissions:
contents: read
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test-and-nan.yml
needs: checkout-linux
with:
build-runs-on: electron-arc-linux-amd64-32core
check-runs-on: electron-arc-linux-amd64-8core
test-runs-on: electron-arc-linux-amd64-4core
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
target-platform: linux
target-arch: x64
is-release: false
gn-build-type: testing
generate-symbols: false
upload-to-storage: '0'
secrets: inherit
linux-x64-asan:
permissions:
contents: read
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-linux
with:
build-runs-on: electron-arc-linux-amd64-32core
check-runs-on: electron-arc-linux-amd64-8core
test-runs-on: electron-arc-linux-amd64-4core
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
target-platform: linux
target-arch: x64
is-release: false
gn-build-type: testing
generate-symbols: false
upload-to-storage: '0'
is-asan: true
secrets: inherit
linux-arm:
permissions:
contents: read
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-linux
with:
build-runs-on: electron-arc-linux-amd64-32core
check-runs-on: electron-arc-linux-amd64-8core
test-runs-on: electron-arc-linux-arm64-4core
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/test:arm32v7-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init","volumes":["/home/runner/externals:/mnt/runner-externals"]}'
target-platform: linux
target-arch: arm
is-release: false
gn-build-type: testing
generate-symbols: false
upload-to-storage: '0'
secrets: inherit
linux-arm64:
permissions:
contents: read
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-linux
with:
build-runs-on: electron-arc-linux-amd64-32core
check-runs-on: electron-arc-linux-amd64-8core
test-runs-on: electron-arc-linux-arm64-4core
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/test:arm64v8-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
target-platform: linux
target-arch: arm64
is-release: false
gn-build-type: testing
generate-symbols: false
upload-to-storage: '0'
secrets: inherit

14
.github/workflows/config/gclient.diff vendored Normal file
View File

@@ -0,0 +1,14 @@
diff --git a/gclient.py b/gclient.py
index 59e2b4c5197928bdba1ef69bdbe637d7dfe471c1..b4bae5e48c83c84bd867187afaf40eed16e69851 100755
--- a/gclient.py
+++ b/gclient.py
@@ -783,7 +783,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
not condition or "non_git_source" not in condition):
continue
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,

86
.github/workflows/linux-publish.yml vendored Normal file
View File

@@ -0,0 +1,86 @@
name: Publish Linux
on:
workflow_dispatch:
inputs:
build-image-sha:
type: string
description: 'SHA for electron/build image'
default: 'cf814a4d2501e8e843caea071a6b70a48e78b855'
upload-to-storage:
description: 'Uploads to Azure storage'
required: false
default: '1'
type: string
run-linux-publish:
description: 'Run the publish jobs vs just the build jobs'
type: boolean
default: false
jobs:
checkout-linux:
runs-on: electron-arc-linux-amd64-32core
container:
image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
- /var/run/sas:/var/run/sas
env:
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Checkout & Sync & Save
uses: ./src/electron/.github/actions/checkout
publish-x64:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
needs: checkout-linux
with:
environment: production-release
build-runs-on: electron-arc-linux-amd64-32core
build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
target-platform: linux
target-arch: x64
is-release: true
gn-build-type: release
generate-symbols: true
strip-binaries: true
upload-to-storage: ${{ inputs.upload-to-storage }}
secrets: inherit
publish-arm:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
needs: checkout-linux
with:
environment: production-release
build-runs-on: electron-arc-linux-amd64-32core
build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
target-platform: linux
target-arch: arm
is-release: true
gn-build-type: release
generate-symbols: true
strip-binaries: true
upload-to-storage: ${{ inputs.upload-to-storage }}
secrets: inherit
publish-arm64:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
needs: checkout-linux
with:
environment: production-release
build-runs-on: electron-arc-linux-amd64-32core
build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
target-platform: linux
target-arch: arm64
is-release: true
gn-build-type: release
generate-symbols: true
strip-binaries: true
upload-to-storage: ${{ inputs.upload-to-storage }}
secrets: inherit

69
.github/workflows/macos-publish.yml vendored Normal file
View File

@@ -0,0 +1,69 @@
name: Publish MacOS
on:
workflow_dispatch:
inputs:
build-image-sha:
type: string
description: 'SHA for electron/build image'
default: 'cf814a4d2501e8e843caea071a6b70a48e78b855'
required: true
upload-to-storage:
description: 'Uploads to Azure storage'
required: false
default: '1'
type: string
run-macos-publish:
description: 'Run the publish jobs vs just the build jobs'
type: boolean
default: false
jobs:
checkout-macos:
runs-on: electron-arc-linux-amd64-32core
container:
image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
- /var/run/sas:/var/run/sas
env:
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
steps:
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Checkout & Sync & Save
uses: ./src/electron/.github/actions/checkout
with:
generate-sas-token: 'true'
publish-x64:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
needs: checkout-macos
with:
environment: production-release
build-runs-on: macos-14-xlarge
target-platform: macos
target-arch: x64
is-release: true
gn-build-type: release
generate-symbols: true
upload-to-storage: ${{ inputs.upload-to-storage }}
secrets: inherit
publish-arm64:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
needs: checkout-macos
with:
environment: production-release
build-runs-on: macos-14-xlarge
target-platform: macos
target-arch: arm64
is-release: true
gn-build-type: release
generate-symbols: true
upload-to-storage: ${{ inputs.upload-to-storage }}
secrets: inherit

View File

@@ -0,0 +1,107 @@
name: Electron Build & Test (+ Node + NaN) Pipeline
on:
workflow_call:
inputs:
target-platform:
type: string
description: 'Platform to run on, can be macos or linux'
required: true
target-arch:
type: string
description: 'Arch to build for, can be x64, arm64 or arm'
required: true
build-runs-on:
type: string
description: 'What host to run the build'
required: true
check-runs-on:
type: string
description: 'What host to run the gn-check'
required: true
test-runs-on:
type: string
description: 'What host to run the tests on'
required: true
build-container:
type: string
description: 'JSON container information for aks runs-on'
required: false
default: '{"image":null}'
test-container:
type: string
description: 'JSON container information for testing'
required: false
default: '{"image":null}'
is-release:
description: 'Whether this build job is a release job'
required: true
type: boolean
default: false
gn-build-type:
description: 'The gn build type - testing or release'
required: true
type: string
default: testing
generate-symbols:
description: 'Whether or not to generate symbols'
required: true
type: boolean
default: false
upload-to-storage:
description: 'Whether or not to upload build artifacts to external storage'
required: true
type: string
default: '0'
is-asan:
description: 'Building the Address Sanitizer (ASan) Linux build'
required: false
type: boolean
default: false
concurrency:
group: electron-build-and-test-and-nan-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
jobs:
build:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
with:
build-runs-on: ${{ inputs.build-runs-on }}
build-container: ${{ inputs.build-container }}
target-platform: ${{ inputs.target-platform }}
target-arch: ${{ inputs.target-arch }}
is-release: ${{ inputs.is-release }}
gn-build-type: ${{ inputs.gn-build-type }}
generate-symbols: ${{ inputs.generate-symbols }}
upload-to-storage: ${{ inputs.upload-to-storage }}
secrets: inherit
gn-check:
uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
with:
target-platform: ${{ inputs.target-platform }}
target-arch: ${{ inputs.target-arch }}
check-runs-on: ${{ inputs.check-runs-on }}
check-container: ${{ inputs.build-container }}
gn-build-type: ${{ inputs.gn-build-type }}
is-asan: ${{ inputs.is-asan }}
secrets: inherit
test:
uses: ./.github/workflows/pipeline-segment-electron-test.yml
needs: build
with:
target-arch: ${{ inputs.target-arch }}
target-platform: ${{ inputs.target-platform }}
test-runs-on: ${{ inputs.test-runs-on }}
test-container: ${{ inputs.test-container }}
secrets: inherit
nn-test:
uses: ./.github/workflows/pipeline-segment-node-nan-test.yml
needs: build
with:
target-arch: ${{ inputs.target-arch }}
target-platform: ${{ inputs.target-platform }}
test-runs-on: ${{ inputs.test-runs-on }}
test-container: ${{ inputs.test-container }}
gn-build-type: ${{ inputs.gn-build-type }}
secrets: inherit

View File

@@ -0,0 +1,104 @@
name: Electron Build & Test Pipeline
on:
workflow_call:
inputs:
target-platform:
type: string
description: 'Platform to run on, can be macos or linux'
required: true
target-arch:
type: string
description: 'Arch to build for, can be x64, arm64 or arm'
required: true
build-runs-on:
type: string
description: 'What host to run the build'
required: true
check-runs-on:
type: string
description: 'What host to run the gn-check'
required: true
test-runs-on:
type: string
description: 'What host to run the tests on'
required: true
build-container:
type: string
description: 'JSON container information for aks runs-on'
required: false
default: '{"image":null}'
test-container:
type: string
description: 'JSON container information for testing'
required: false
default: '{"image":null}'
is-release:
description: 'Whether this build job is a release job'
required: true
type: boolean
default: false
gn-build-type:
description: 'The gn build type - testing or release'
required: true
type: string
default: testing
generate-symbols:
description: 'Whether or not to generate symbols'
required: true
type: boolean
default: false
upload-to-storage:
description: 'Whether or not to upload build artifacts to external storage'
required: true
type: string
default: '0'
is-asan:
description: 'Building the Address Sanitizer (ASan) Linux build'
required: false
type: boolean
default: false
concurrency:
group: electron-build-and-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
permissions:
contents: read
issues: read
pull-requests: read
jobs:
build:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
with:
build-runs-on: ${{ inputs.build-runs-on }}
build-container: ${{ inputs.build-container }}
target-platform: ${{ inputs.target-platform }}
target-arch: ${{ inputs.target-arch }}
is-release: ${{ inputs.is-release }}
gn-build-type: ${{ inputs.gn-build-type }}
generate-symbols: ${{ inputs.generate-symbols }}
upload-to-storage: ${{ inputs.upload-to-storage }}
is-asan: ${{ inputs.is-asan}}
secrets: inherit
gn-check:
uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
with:
target-platform: ${{ inputs.target-platform }}
target-arch: ${{ inputs.target-arch }}
check-runs-on: ${{ inputs.check-runs-on }}
check-container: ${{ inputs.build-container }}
gn-build-type: ${{ inputs.gn-build-type }}
is-asan: ${{ inputs.is-asan }}
secrets: inherit
test:
uses: ./.github/workflows/pipeline-segment-electron-test.yml
needs: build
with:
target-arch: ${{ inputs.target-arch }}
target-platform: ${{ inputs.target-platform }}
test-runs-on: ${{ inputs.test-runs-on }}
test-container: ${{ inputs.test-container }}
is-asan: ${{ inputs.is-asan}}
secrets: inherit

View File

@@ -0,0 +1,43 @@
name: Electron Docs Compile
on:
workflow_call:
inputs:
container:
required: true
description: 'Container to run the docs-only ts compile in'
type: string
concurrency:
group: electron-docs-only-${{ github.ref }}
cancel-in-progress: true
jobs:
docs-only:
name: Docs Only Compile
runs-on: electron-arc-linux-amd64-4core
timeout-minutes: 20
container: ${{ fromJSON(inputs.container) }}
steps:
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Install Dependencies
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Run TS/JS compile
shell: bash
run: |
cd src/electron
node script/yarn create-typescript-definitions
node script/yarn tsc -p tsconfig.default_app.json --noEmit
for f in build/webpack/*.js
do
out="${f:29}"
if [ "$out" != "base.js" ]; then
node script/yarn webpack --config $f --output-filename=$out --output-path=./.tmp --env mode=development
fi
done

View File

@@ -1,40 +1,65 @@
executor:
name: linux-docker
size: medium
steps:
- checkout:
path: src/electron
- run:
name: Setup third_party Depot Tools
command: |
name: Electron Lint
on:
workflow_call:
inputs:
container:
required: true
description: 'Container to run lint in'
type: string
concurrency:
group: electron-lint-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
jobs:
lint:
name: Lint
runs-on: electron-arc-linux-amd64-4core
timeout-minutes: 20
container: ${{ fromJSON(inputs.container) }}
steps:
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Install Dependencies
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Setup third_party Depot Tools
shell: bash
run: |
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git src/third_party/depot_tools
echo 'export PATH="$PATH:'"$PWD"'/src/third_party/depot_tools"' >> $BASH_ENV
- run:
name: Download GN Binary
command: |
echo "$(pwd)/src/third_party/depot_tools" >> $GITHUB_PATH
- name: Download GN Binary
shell: bash
run: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
gn_version="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep gn_version | head -n1 | cut -d\' -f4)"
cipd ensure -ensure-file - -root . \<<-CIPD
cipd ensure -ensure-file - -root . <<-CIPD
\$ServiceURL https://chrome-infra-packages.appspot.com/
@Subdir src/buildtools/linux64
gn/gn/linux-amd64 $gn_version
CIPD
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/src/buildtools"' >> $BASH_ENV
- run:
name: Download clang-format Binary
command: |
buildtools_path="$(pwd)/src/buildtools"
echo "CHROMIUM_BUILDTOOLS_PATH=$buildtools_path" >> $GITHUB_ENV
- name: Download clang-format Binary
shell: bash
run: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
sha1_path='buildtools/linux64/clang-format.sha1'
curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/${sha1_path}?format=TEXT" | base64 -d > "src/${sha1_path}"
download_from_google_storage.py --no_resume --no_auth --bucket chromium-clang-format -s "src/${sha1_path}"
- run:
name: Run Lint
command: |
- name: Run Lint
shell: bash
run: |
# gn.py tries to find a gclient root folder starting from the current dir.
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
touch .gclient
@@ -44,8 +69,9 @@ steps:
cd src/electron
node script/yarn install --frozen-lockfile
node script/yarn lint
- run:
name: Run Script Typechecker
command: |
- name: Run Script Typechecker
shell: bash
run: |
cd src/electron
node script/yarn tsc -p tsconfig.script.json

View File

@@ -0,0 +1,217 @@
name: Pipeline Segment - Electron Build
on:
workflow_call:
inputs:
environment:
description: using the production or testing environment
required: false
type: string
target-platform:
type: string
description: 'Platform to run on, can be macos or linux'
required: true
target-arch:
type: string
description: 'Arch to build for, can be x64, arm64 or arm'
required: true
build-runs-on:
type: string
description: 'What host to run the build'
required: true
build-container:
type: string
description: 'JSON container information for aks runs-on'
required: false
default: '{"image":null}'
is-release:
description: 'Whether this build job is a release job'
required: true
type: boolean
default: false
gn-build-type:
description: 'The gn build type - testing or release'
required: true
type: string
default: testing
generate-symbols:
description: 'Whether or not to generate symbols'
required: true
type: boolean
default: false
upload-to-storage:
description: 'Whether or not to upload build artifacts to external storage'
required: true
type: string
default: '0'
strip-binaries:
description: 'Strip the binaries before release (Linux only)'
required: false
type: boolean
default: false
is-asan:
description: 'Building the Address Sanitizer (ASan) Linux build'
required: false
type: boolean
default: false
concurrency:
group: electron-build-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
env:
ELECTRON_ARTIFACTS_BLOB_STORAGE: ${{ secrets.ELECTRON_ARTIFACTS_BLOB_STORAGE }}
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
ELECTRON_GITHUB_TOKEN: ${{ secrets.ELECTRON_GITHUB_TOKEN }}
GCLIENT_EXTRA_ARGS: ${{ inputs.target-platform == 'macos' && '--custom-var=checkout_mac=True --custom-var=host_os=mac' || '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' }}
ELECTRON_OUT_DIR: Default
jobs:
build:
runs-on: ${{ inputs.build-runs-on }}
container: ${{ fromJSON(inputs.build-container) }}
environment: ${{ inputs.environment }}
env:
TARGET_ARCH: ${{ inputs.target-arch }}
steps:
- name: Create src dir
run: mkdir src
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Free up space (macOS)
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/free-space-macos
- name: Check disk space after freeing up space
if: ${{ inputs.target-platform == 'macos' }}
run: df -h
- name: Setup Node.js/npm
if: ${{ inputs.target-platform == 'macos' }}
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8
with:
node-version: 20.11.x
cache: yarn
cache-dependency-path: src/electron/yarn.lock
- name: Install Dependencies
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Install AZCopy
if: ${{ inputs.target-platform == 'macos' }}
run: brew install azcopy
- name: Set GN_EXTRA_ARGS for Linux
if: ${{ inputs.target-platform == 'linux' }}
run: |
if [ "${{ inputs.target-arch }}" = "arm" ]; then
if [ "${{ inputs.is-release }}" = true ]; then
GN_EXTRA_ARGS='target_cpu="arm" build_tflite_with_xnnpack=false symbol_level=1'
else
GN_EXTRA_ARGS='target_cpu="arm" build_tflite_with_xnnpack=false'
fi
elif [ "${{ inputs.target-arch }}" = "arm64" ]; then
GN_EXTRA_ARGS='target_cpu="arm64" fatal_linker_warnings=false enable_linux_installer=false'
elif [ "${{ inputs.is-asan }}" = true ]; then
GN_EXTRA_ARGS='is_asan=true'
fi
echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV
- name: Get Depot Tools
timeout-minutes: 5
run: |
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
SEDOPTION="-i"
if [ "`uname`" = "Darwin" ]; then
SEDOPTION="-i ''"
fi
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
sed $SEDOPTION '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
if [ "`uname`" = "Linux" ]; then
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
fi
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Generate DEPS Hash
run: |
node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
DEPSHASH=v1-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
- name: Restore src cache via AZCopy
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/restore-cache-azcopy
- name: Restore src cache via AKS
if: ${{ inputs.target-platform == 'linux' }}
uses: ./src/electron/.github/actions/restore-cache-aks
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools
- name: Init Build Tools
run: |
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }} --only-sdk
- name: Run Electron Only Hooks
run: |
gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
- name: Regenerate DEPS Hash
run: |
(cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
echo "DEPSHASH=$(shasum src/electron/.depshash | cut -f1 -d' ')" >> $GITHUB_ENV
- name: Add CHROMIUM_BUILDTOOLS_PATH to env
run: echo "CHROMIUM_BUILDTOOLS_PATH=$(pwd)/src/buildtools" >> $GITHUB_ENV
- name: Fix Sync (macOS)
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/fix-sync-macos
- name: Install build-tools & Setup RBE
run: |
echo "NUMBER_OF_NINJA_PROCESSES=${{ inputs.target-platform == 'linux' && '300' || '200' }}" >> $GITHUB_ENV
cd ~/.electron_build_tools
npx yarn --ignore-engines
# Pull down credential helper and print status
node -e "require('./src/utils/reclient.js').downloadAndPrepare({})"
HELPER=$(node -p "require('./src/utils/reclient.js').helperPath({})")
$HELPER login
echo 'RBE_service='`node -e "console.log(require('./src/utils/reclient.js').serviceAddress)"` >> $GITHUB_ENV
echo 'RBE_experimental_credentials_helper='`node -e "console.log(require('./src/utils/reclient.js').helperPath({}))"` >> $GITHUB_ENV
echo 'RBE_experimental_credentials_helper_args=print' >> $GITHUB_ENV
- name: Free up space (macOS)
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/free-space-macos
- name: Build Electron
uses: ./src/electron/.github/actions/build-electron
with:
target-arch: ${{ inputs.target-arch }}
target-platform: ${{ inputs.target-platform }}
artifact-platform: ${{ inputs.target-platform == 'linux' && 'linux' || 'darwin' }}
is-release: '${{ inputs.is-release }}'
generate-symbols: '${{ inputs.generate-symbols }}'
strip-binaries: '${{ inputs.strip-binaries }}'
upload-to-storage: '${{ inputs.upload-to-storage }}'
is-asan: '${{ inputs.is-asan }}'
- name: Set GN_EXTRA_ARGS for MAS Build
if: ${{ inputs.target-platform == 'macos' }}
run: |
echo "MAS_BUILD=true" >> $GITHUB_ENV
GN_EXTRA_ARGS='is_mas_build=true'
echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV
- name: Build Electron (MAS)
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/build-electron
with:
target-arch: ${{ inputs.target-arch }}
target-platform: ${{ inputs.target-platform }}
artifact-platform: 'mas'
is-release: '${{ inputs.is-release }}'
generate-symbols: '${{ inputs.generate-symbols }}'
upload-to-storage: '${{ inputs.upload-to-storage }}'
step-suffix: '(mas)'

View File

@@ -0,0 +1,158 @@
name: Pipeline Segment - Electron GN Check
on:
workflow_call:
inputs:
target-platform:
type: string
description: 'Platform to run on, can be macos or linux'
required: true
target-arch:
type: string
description: 'Arch to build for, can be x64, arm64 or arm'
required: true
check-runs-on:
type: string
description: 'What host to run the tests on'
required: true
check-container:
type: string
description: 'JSON container information for aks runs-on'
required: false
default: '{"image":null}'
gn-build-type:
description: 'The gn build type - testing or release'
required: true
type: string
default: testing
is-asan:
description: 'Building the Address Sanitizer (ASan) Linux build'
required: false
type: boolean
default: false
concurrency:
group: electron-gn-check-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref }}
cancel-in-progress: true
env:
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
GCLIENT_EXTRA_ARGS: ${{ inputs.target-platform == 'macos' && '--custom-var=checkout_mac=True --custom-var=host_os=mac' || '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' }}
ELECTRON_OUT_DIR: Default
TARGET_ARCH: ${{ inputs.target-arch }}
jobs:
gn-check:
# TODO(codebytere): Change this to medium VM
runs-on: ${{ inputs.check-runs-on }}
container: ${{ fromJSON(inputs.check-container) }}
env:
TARGET_ARCH: ${{ inputs.target-arch }}
steps:
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Cleanup disk space on macOS
if: ${{ inputs.target-platform == 'macos' }}
shell: bash
run: |
sudo mkdir -p $TMPDIR/del-target
tmpify() {
if [ -d "$1" ]; then
sudo mv "$1" $TMPDIR/del-target/$(echo $1|shasum -a 256|head -n1|cut -d " " -f1)
fi
}
tmpify /Library/Developer/CoreSimulator
tmpify ~/Library/Developer/CoreSimulator
sudo rm -rf $TMPDIR/del-target
- name: Check disk space after freeing up space
if: ${{ inputs.target-platform == 'macos' }}
run: df -h
- name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools
- name: Init Build Tools
run: |
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }} --only-sdk
- name: Get Depot Tools
timeout-minutes: 5
run: |
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
SEDOPTION="-i"
if [ "`uname`" = "Darwin" ]; then
SEDOPTION="-i ''"
fi
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
sed $SEDOPTION '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
if [ "`uname`" = "Linux" ]; then
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
fi
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Set GN_EXTRA_ARGS for Linux
if: ${{ inputs.target-platform == 'linux' }}
run: |
if [ "${{ inputs.target-arch }}" = "arm" ]; then
GN_EXTRA_ARGS='build_tflite_with_xnnpack=false'
elif [ "${{ inputs.target-arch }}" = "arm64" ]; then
GN_EXTRA_ARGS='fatal_linker_warnings=false enable_linux_installer=false'
fi
echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV
- name: Generate DEPS Hash
run: |
node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
DEPSHASH=v1-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
- name: Restore src cache via AZCopy
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/restore-cache-azcopy
- name: Restore src cache via AKS
if: ${{ inputs.target-platform == 'linux' }}
uses: ./src/electron/.github/actions/restore-cache-aks
- name: Run Electron Only Hooks
run: |
gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
- name: Regenerate DEPS Hash
run: |
(cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
echo "DEPSHASH=$(shasum src/electron/.depshash | cut -f1 -d' ')" >> $GITHUB_ENV
- name: Add CHROMIUM_BUILDTOOLS_PATH to env
run: echo "CHROMIUM_BUILDTOOLS_PATH=$(pwd)/src/buildtools" >> $GITHUB_ENV
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Default GN gen
run: |
cd src/electron
git pack-refs
cd ..
e build --only-gen
- name: Run GN Check
run: |
cd src
gn check out/Default //electron:electron_lib
gn check out/Default //electron:electron_app
gn check out/Default //electron/shell/common/api:mojo
# Check the hunspell filenames
node electron/script/gen-hunspell-filenames.js --check
node electron/script/gen-libc++-filenames.js --check
- name: Wait for active SSH sessions
if: always() && !cancelled()
run: |
while [ -f /var/.ssh-lock ]
do
sleep 60
done

View File

@@ -0,0 +1,196 @@
name: Pipeline Segment - Electron Test
on:
workflow_call:
inputs:
target-platform:
type: string
description: 'Platform to run on, can be macos or linux'
required: true
target-arch:
type: string
description: 'Arch to build for, can be x64, arm64 or arm'
required: true
test-runs-on:
type: string
description: 'What host to run the tests on'
required: true
test-container:
type: string
description: 'JSON container information for aks runs-on'
required: false
default: '{"image":null}'
is-asan:
description: 'Building the Address Sanitizer (ASan) Linux build'
required: false
type: boolean
default: false
concurrency:
group: electron-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
permissions:
contents: read
issues: read
pull-requests: read
env:
ELECTRON_OUT_DIR: Default
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
ELECTRON_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
test:
runs-on: ${{ inputs.test-runs-on }}
container: ${{ fromJSON(inputs.test-container) }}
strategy:
fail-fast: false
matrix:
build-type: ${{ inputs.target-platform == 'macos' && fromJSON('["darwin","mas"]') || fromJSON('["linux"]') }}
shard: ${{ inputs.target-platform == 'macos' && fromJSON('[1, 2]') || fromJSON('[1, 2, 3]') }}
env:
BUILD_TYPE: ${{ matrix.build-type }}
TARGET_ARCH: ${{ inputs.target-arch }}
ARTIFACT_KEY: ${{ matrix.build-type }}_${{ inputs.target-arch }}
steps:
- name: Fix node20 on arm32 runners
if: ${{ inputs.target-arch == 'arm' }}
run: |
cp $(which node) /mnt/runner-externals/node20/bin/
- name: Add TCC permissions on macOS
if: ${{ inputs.target-platform == 'macos' }}
run: |
configure_user_tccdb () {
local values=$1
local dbPath="$HOME/Library/Application Support/com.apple.TCC/TCC.db"
local sqlQuery="INSERT OR REPLACE INTO access VALUES($values);"
sqlite3 "$dbPath" "$sqlQuery"
}
configure_sys_tccdb () {
local values=$1
local dbPath="/Library/Application Support/com.apple.TCC/TCC.db"
local sqlQuery="INSERT OR REPLACE INTO access VALUES($values);"
sudo sqlite3 "$dbPath" "$sqlQuery"
}
userValuesArray=(
"'kTCCServiceMicrophone','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceCamera','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceBluetoothAlways','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
)
for values in "${userValuesArray[@]}"; do
# Sonoma and higher have a few extra values
# Ref: https://github.com/actions/runner-images/blob/main/images/macos/scripts/build/configure-tccdb-macos.sh
if [ "$OSTYPE" = "darwin23" ]; then
configure_user_tccdb "$values,NULL,NULL,'UNUSED',${values##*,}"
configure_sys_tccdb "$values,NULL,NULL,'UNUSED',${values##*,}"
else
configure_user_tccdb "$values"
configure_sys_tccdb "$values"
fi
done
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Install Dependencies
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Get Depot Tools
timeout-minutes: 5
run: |
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
if [ "`uname`" = "Darwin" ]; then
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
sed -i '' '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
else
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
# Remove swift-format dep from cipd on macOS until we send a patch upstream.
cd depot_tools
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
fi
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Load ASan specific environment variables
if: ${{ inputs.is-asan == true }}
run: |
echo "ARTIFACT_KEY=${{ matrix.build-type }}_${{ inputs.target-arch }}_asan" >> $GITHUB_ENV
echo "DISABLE_CRASH_REPORTER_TESTS=true" >> $GITHUB_ENV
echo "IS_ASAN=true" >> $GITHUB_ENV
- name: Download Generated Artifacts
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
with:
name: generated_artifacts_${{ env.ARTIFACT_KEY }}
path: ./generated_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }}
- name: Download Src Artifacts
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
with:
name: src_artifacts_${{ env.ARTIFACT_KEY }}
path: ./src_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }}
- name: Restore Generated Artifacts
run: ./src/electron/script/actions/restore-artifacts.sh
- name: Unzip Dist, Mksnapshot & Chromedriver
run: |
cd src/out/Default
unzip -:o dist.zip
unzip -:o chromedriver.zip
unzip -:o mksnapshot.zip
- name: Import & Trust Self-Signed Codesigning Cert on MacOS
if: ${{ inputs.target-platform == 'macos' && inputs.target-arch == 'x64' }}
run: |
sudo security authorizationdb write com.apple.trust-settings.admin allow
cd src/electron
./script/codesign/generate-identity.sh
- name: Run Electron Tests
shell: bash
env:
MOCHA_REPORTER: mocha-multi-reporters
ELECTRON_TEST_RESULTS_DIR: junit
MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
DISPLAY: ':99.0'
run: |
cd src/electron
# Get which tests are on this shard
tests_files=$(node script/split-tests ${{ matrix.shard }} ${{ inputs.target-platform == 'macos' && 2 || 3 }})
# Run tests
if [ "`uname`" = "Darwin" ]; then
echo "About to start tests"
node script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files
else
chown :builduser .. && chmod g+w ..
chown -R :builduser . && chmod -R g+w .
chmod 4755 ../out/Default/chrome-sandbox
runuser -u builduser -- git config --global --add safe.directory $(pwd)
if [ "${{ inputs.is-asan }}" == "true" ]; then
cd ..
ASAN_SYMBOLIZE="$PWD/tools/valgrind/asan/asan_symbolize.py --executable-path=$PWD/out/Default/electron"
export ASAN_OPTIONS="symbolize=0 handle_abort=1"
export G_SLICE=always-malloc
export NSS_DISABLE_ARENA_FREE_LIST=1
export NSS_DISABLE_UNLOAD=1
export LLVM_SYMBOLIZER_PATH=$PWD/third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer
export MOCHA_TIMEOUT=180000
echo "Piping output to ASAN_SYMBOLIZE ($ASAN_SYMBOLIZE)"
cd electron
runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files | $ASAN_SYMBOLIZE
else
runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files
fi
fi
- name: Wait for active SSH sessions
if: always() && !cancelled()
run: |
while [ -f /var/.ssh-lock ]
do
sleep 60
done

View File

@@ -0,0 +1,165 @@
name: Pipeline Segment - Node/Nan Test
on:
workflow_call:
inputs:
target-platform:
type: string
description: 'Platform to run on, can be macos or linux'
required: true
target-arch:
type: string
description: 'Arch to build for, can be x64, arm64 or arm'
required: true
test-runs-on:
type: string
description: 'What host to run the tests on'
required: true
test-container:
type: string
description: 'JSON container information for aks runs-on'
required: false
default: '{"image":null}'
gn-build-type:
description: 'The gn build type - testing or release'
required: true
type: string
default: testing
concurrency:
group: electron-node-nan-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
env:
ELECTRON_OUT_DIR: Default
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
jobs:
node-tests:
name: Run Node.js Tests
runs-on: electron-arc-linux-amd64-8core
timeout-minutes: 20
env:
TARGET_ARCH: ${{ inputs.target-arch }}
BUILD_TYPE: linux
container: ${{ fromJSON(inputs.test-container) }}
steps:
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools
- name: Init Build Tools
run: |
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }}
- name: Install Dependencies
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Get Depot Tools
timeout-minutes: 5
run: |
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
cd depot_tools
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Download Generated Artifacts
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
with:
name: generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
path: ./generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
- name: Download Src Artifacts
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
with:
name: src_artifacts_linux_${{ env.TARGET_ARCH }}
path: ./src_artifacts_linux_${{ env.TARGET_ARCH }}
- name: Restore Generated Artifacts
run: ./src/electron/script/actions/restore-artifacts.sh
- name: Unzip Dist
run: |
cd src/out/Default
unzip -:o dist.zip
- name: Setup Linux for Headless Testing
run: sh -e /etc/init.d/xvfb start
- name: Run Node.js Tests
run: |
cd src
node electron/script/node-spec-runner.js --default --jUnitDir=junit
- name: Wait for active SSH sessions
if: always() && !cancelled()
run: |
while [ -f /var/.ssh-lock ]
do
sleep 60
done
nan-tests:
name: Run Nan Tests
runs-on: electron-arc-linux-amd64-4core
timeout-minutes: 20
env:
TARGET_ARCH: ${{ inputs.target-arch }}
BUILD_TYPE: linux
container: ${{ fromJSON(inputs.test-container) }}
steps:
- name: Checkout Electron
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
path: src/electron
fetch-depth: 0
- name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools
- name: Init Build Tools
run: |
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }}
- name: Install Dependencies
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Get Depot Tools
timeout-minutes: 5
run: |
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
cd depot_tools
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Download Generated Artifacts
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
with:
name: generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
path: ./generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
- name: Download Src Artifacts
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
with:
name: src_artifacts_linux_${{ env.TARGET_ARCH }}
path: ./src_artifacts_linux_${{ env.TARGET_ARCH }}
- name: Restore Generated Artifacts
run: ./src/electron/script/actions/restore-artifacts.sh
- name: Unzip Dist
run: |
cd src/out/Default
unzip -:o dist.zip
- name: Setup Linux for Headless Testing
run: sh -e /etc/init.d/xvfb start
- name: Run Node.js Tests
run: |
cd src
node electron/script/nan-spec-runner.js
- name: Wait for active SSH sessions
if: always() && !cancelled()
run: |
while [ -f /var/.ssh-lock ]
do
sleep 60
done

2
DEPS
View File

@@ -4,7 +4,7 @@ vars = {
'chromium_version':
'124.0.6367.243',
'node_version':
'v20.14.0',
'v20.16.0',
'nan_version':
'e14bdcd1f72d62bca1d541b66da43130384ec213',
'squirrel.mac_version':

View File

@@ -1,6 +1,6 @@
[![Electron Logo](https://electronjs.org/images/electron-logo.svg)](https://electronjs.org)
[![CircleCI Build Status](https://circleci.com/gh/electron/electron/tree/main.svg?style=shield)](https://circleci.com/gh/electron/electron/tree/main)
[![GitHub Actions Build Status](https://github.com/electron/electron/actions/workflows/build.yml/badge.svg)](https://github.com/electron/electron/actions/workflows/build.yml)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/4lggi9dpjc1qob7k/branch/main?svg=true)](https://ci.appveyor.com/project/electron-bot/electron-ljo26/branch/main)
[![Electron Discord Invite](https://img.shields.io/discord/745037351163527189?color=%237289DA&label=chat&logo=discord&logoColor=white)](https://discord.gg/electronjs)

View File

@@ -95,6 +95,8 @@ for:
- 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: |
Set-Content -Path $pwd\depot_tools\build_telemetry.cfg -Value '{"user": "info@electronjs.org", "status": "opt-out", "countdown": 10, "version": 1}'
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (Test-Path -Path "$pwd\src\electron") {
@@ -115,6 +117,13 @@ for:
$env:RBE_experimental_credentials_helper = $env:RECLIENT_HELPER
- ps: >-
$env:RBE_experimental_credentials_helper_args = "print"
- ps: >-
if ($env:ELECTRON_RBE_JWT -eq '') {
$env:RBE_fail_early_min_action_count = "0"
$env:RBE_fail_early_min_fallback_ratio = "0"
$env:RBE_exec_strategy = "local"
$env:RBE_remote_update_cache= "false"
}
- cd ..\..
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
- ps: >-
@@ -166,8 +175,8 @@ for:
if ($env:GN_CONFIG -eq 'release') {
# Needed for msdia140.dll on 64-bit windows
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
autoninja -C out/Default electron:electron_symbols
}
- if "%GN_CONFIG%"=="release" ( autoninja -C out/Default electron:electron_symbols )
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
python3 electron\script\zip-symbols.py

View File

@@ -93,6 +93,8 @@ for:
- 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: |
Set-Content -Path $pwd\depot_tools\build_telemetry.cfg -Value '{"user": "info@electronjs.org", "status": "opt-out", "countdown": 10, "version": 1}'
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (Test-Path -Path "$pwd\src\electron") {
@@ -113,6 +115,13 @@ for:
$env:RBE_experimental_credentials_helper = $env:RECLIENT_HELPER
- ps: >-
$env:RBE_experimental_credentials_helper_args = "print"
- ps: >-
if ($env:ELECTRON_RBE_JWT -eq '') {
$env:RBE_fail_early_min_action_count = "0"
$env:RBE_fail_early_min_fallback_ratio = "0"
$env:RBE_exec_strategy = "local"
$env:RBE_remote_update_cache= "false"
}
- cd ..\..
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
- ps: >-
@@ -163,8 +172,8 @@ for:
if ($env:GN_CONFIG -eq 'release') {
# Needed for msdia140.dll on 64-bit windows
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
autoninja -C out/Default electron:electron_symbols
}
- if "%GN_CONFIG%"=="release" ( autoninja -C out/Default electron:electron_symbols )
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
python3 electron\script\zip-symbols.py

View File

@@ -106,6 +106,7 @@ static_library("chrome") {
"//chrome/browser/ui/frame/window_frame_util.h",
"//chrome/browser/ui/ui_features.cc",
"//chrome/browser/ui/ui_features.h",
"//chrome/browser/ui/view_ids.h",
"//chrome/browser/ui/views/eye_dropper/eye_dropper.cc",
"//chrome/browser/ui/views/eye_dropper/eye_dropper.h",
"//chrome/browser/ui/views/overlay/back_to_tab_label_button.cc",
@@ -149,12 +150,15 @@ static_library("chrome") {
"//chrome/browser/media/webrtc/window_icon_util_win.cc",
"//chrome/browser/process_singleton_win.cc",
"//chrome/browser/ui/frame/window_frame_util.h",
"//chrome/browser/ui/view_ids.h",
"//chrome/browser/win/chrome_process_finder.cc",
"//chrome/browser/win/chrome_process_finder.h",
"//chrome/browser/win/chrome_select_file_dialog_factory.cc",
"//chrome/browser/win/chrome_select_file_dialog_factory.h",
"//chrome/browser/win/titlebar_config.cc",
"//chrome/browser/win/titlebar_config.h",
"//chrome/browser/win/titlebar_config.h",
"//chrome/browser/win/util_win_service.cc",
"//chrome/browser/win/util_win_service.h",
"//chrome/child/v8_crashpad_support_win.cc",
"//chrome/child/v8_crashpad_support_win.h",
]
@@ -233,6 +237,7 @@ static_library("chrome") {
"//chrome/services/util_win:lib",
"//components/webapps/common:mojo_bindings",
]
deps += [ "//chrome/services/util_win/public/mojom" ]
}
if (is_mac) {

View File

@@ -1357,7 +1357,7 @@ Show the app's about panel options. These options can be overridden with `app.se
* `credits` string (optional) _macOS_ _Windows_ - Credit information.
* `authors` string[] (optional) _Linux_ - List of app authors.
* `website` string (optional) _Linux_ - The app's website.
* `iconPath` string (optional) _Linux_ _Windows_ - Path to the app's icon in a JPEG or PNG file format. On Linux, will be shown as 64x64 pixels while retaining aspect ratio.
* `iconPath` string (optional) _Linux_ _Windows_ - Path to the app's icon in a JPEG or PNG file format. On Linux, will be shown as 64x64 pixels while retaining aspect ratio. On Windows, a 48x48 PNG will result in the best visual quality.
Set the about panel options. This will override the values defined in the app's `.plist` file on macOS. See the [Apple docs][about-panel-options] for more details. On Linux, values must be set in order to be shown; there are no defaults.

View File

@@ -1370,15 +1370,16 @@ machine has a touch bar.
**Note:** The TouchBar API is currently experimental and may change or be
removed in future Electron releases.
#### `win.setTitleBarOverlay(options)` _Windows_
#### `win.setTitleBarOverlay(options)` _Windows_ _Linux_
* `options` Object
* `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled.
* `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled.
* `height` Integer (optional) _Windows_ - The height of the title bar and Window Controls Overlay in pixels.
* `color` String (optional) - The CSS color of the Window Controls Overlay when enabled.
* `symbolColor` String (optional) - The CSS color of the symbols on the Window Controls Overlay when enabled.
* `height` Integer (optional) - The height of the title bar and Window Controls Overlay in pixels.
On a Window with Window Controls Overlay already enabled, this method updates
the style of the title bar overlay.
On a Window with Window Controls Overlay already enabled, this method updates the style of the title bar overlay.
On Linux, the `symbolColor` is automatically calculated to have minimum accessible contrast to the `color` if not explicitly set.
[quick-look]: https://en.wikipedia.org/wiki/Quick_Look
[vibrancy-docs]: https://developer.apple.com/documentation/appkit/nsvisualeffectview?preferredLanguage=objc

View File

@@ -690,6 +690,8 @@ Sets whether the window should be in fullscreen mode.
Returns `boolean` - Whether the window is in fullscreen mode.
**Note:** On macOS, fullscreen transitions take place asynchronously. When querying for a BrowserWindow's fullscreen status, you should ensure that either the ['enter-full-screen'](browser-window.md#event-enter-full-screen) or ['leave-full-screen'](browser-window.md#event-leave-full-screen) events have been emitted.
#### `win.setSimpleFullScreen(flag)` _macOS_
* `flag` boolean
@@ -1641,15 +1643,16 @@ with `addBrowserView` or `setBrowserView`. The top-most BrowserView is the last
> The `BrowserView` class is deprecated, and replaced by the new
> [`WebContentsView`](web-contents-view.md) class.
#### `win.setTitleBarOverlay(options)` _Windows_
#### `win.setTitleBarOverlay(options)` _Windows_ _Linux_
* `options` Object
* `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled.
* `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled.
* `height` Integer (optional) _macOS_ _Windows_ - The height of the title bar and Window Controls Overlay in pixels.
* `color` String (optional) - The CSS color of the Window Controls Overlay when enabled.
* `symbolColor` String (optional) - The CSS color of the symbols on the Window Controls Overlay when enabled.
* `height` Integer (optional) - The height of the title bar and Window Controls Overlay in pixels.
On a Window with Window Controls Overlay already enabled, this method updates
the style of the title bar overlay.
On a window with Window Controls Overlay already enabled, this method updates the style of the title bar overlay.
On Linux, the `symbolColor` is automatically calculated to have minimum accessible contrast to the `color` if not explicitly set.
[page-visibility-api]: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
[quick-look]: https://en.wikipedia.org/wiki/Quick_Look

View File

@@ -9,80 +9,66 @@ The following example shows how to capture video from a desktop window whose
title is `Electron`:
```js
// In the main process.
const { BrowserWindow, desktopCapturer } = require('electron')
// main.js
const { app, BrowserWindow, desktopCapturer, session } = require('electron')
const mainWindow = new BrowserWindow()
app.whenReady().then(() => {
const mainWindow = new BrowserWindow()
desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => {
for (const source of sources) {
if (source.name === 'Electron') {
mainWindow.webContents.send('SET_SOURCE', source.id)
return
}
}
})
```
```js @ts-nocheck
// In the preload script.
const { ipcRenderer } = require('electron')
ipcRenderer.on('SET_SOURCE', async (event, sourceId) => {
try {
const stream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: sourceId,
minWidth: 1280,
maxWidth: 1280,
minHeight: 720,
maxHeight: 720
}
}
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
desktopCapturer.getSources({ types: ['screen'] }).then((sources) => {
// Grant access to the first screen found.
callback({ video: sources[0], audio: 'loopback' })
})
handleStream(stream)
} catch (e) {
handleError(e)
}
})
mainWindow.loadFile('index.html')
})
function handleStream (stream) {
const video = document.querySelector('video')
video.srcObject = stream
video.onloadedmetadata = (e) => video.play()
}
function handleError (e) {
console.log(e)
}
```
To capture video from a source provided by `desktopCapturer` the constraints
passed to [`navigator.mediaDevices.getUserMedia`][] must include
`chromeMediaSource: 'desktop'`, and `audio: false`.
To capture both audio and video from the entire desktop the constraints passed
to [`navigator.mediaDevices.getUserMedia`][] must include `chromeMediaSource: 'desktop'`,
for both `audio` and `video`, but should not include a `chromeMediaSourceId` constraint.
```js
const constraints = {
audio: {
mandatory: {
chromeMediaSource: 'desktop'
// renderer.js
const startButton = document.getElementById('startButton')
const stopButton = document.getElementById('stopButton')
const video = document.querySelector('video')
startButton.addEventListener('click', () => {
navigator.mediaDevices.getDisplayMedia({
audio: true,
video: {
width: 320,
height: 240,
frameRate: 30
}
},
video: {
mandatory: {
chromeMediaSource: 'desktop'
}
}
}
}).then(stream => {
video.srcObject = stream
video.onloadedmetadata = (e) => video.play()
}).catch(e => console.log(e))
})
stopButton.addEventListener('click', () => {
video.pause()
})
```
```html
<!-- index.html -->
<html>
<meta http-equiv="content-security-policy" content="script-src 'self' 'unsafe-inline'" />
<body>
<button id="startButton" class="button">Start</button>
<button id="stopButton" class="button">Stop</button>
<video width="320" height="240" autoplay></video>
<script src="renderer.js"></script>
</body>
</html>
```
See [`navigator.mediaDevices.getDisplayMedia`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia) for more information.
**Note:** `navigator.mediaDevices.getDisplayMedia` does not permit the use of `deviceId` for
selection of a source - see [specification](https://w3c.github.io/mediacapture-screen-share/#constraints).
## Methods
The `desktopCapturer` module has the following methods:

View File

@@ -145,6 +145,10 @@ Returns `string` - The file name of the download item.
disk. If user changes the file name in a prompted download saving dialog, the
actual name of saved file will be different.
#### `downloadItem.getCurrentBytesPerSecond()`
Returns `Integer` - The current download speed in bytes per second.
#### `downloadItem.getTotalBytes()`
Returns `Integer` - The total size in bytes of the download item.
@@ -155,6 +159,10 @@ If the size is unknown, it returns 0.
Returns `Integer` - The received bytes of the download item.
#### `downloadItem.getPercentComplete()`
Returns `Integer` - The download completion in percent.
#### `downloadItem.getContentDisposition()`
Returns `string` - The Content-Disposition field from the response
@@ -184,6 +192,10 @@ Returns `string` - ETag header value.
Returns `Double` - Number of seconds since the UNIX epoch when the download was
started.
#### `downloadItem.getEndTime()`
Returns `Double` - Number of seconds since the UNIX epoch when the download ended.
### Instance Properties
#### `downloadItem.savePath`

View File

@@ -72,3 +72,7 @@ or is being instructed to use an inverted color scheme.
A `boolean` indicating whether Chromium is in forced colors mode, controlled by system accessibility settings.
Currently, Windows high contrast is the only system setting that triggers forced colors mode.
### `nativeTheme.prefersReducedTransparency` _Readonly_
A `boolean` that indicates the whether the user has chosen via system accessibility settings to reduce transparency at the OS level.

View File

@@ -143,6 +143,71 @@ Returns:
Emitted after an extension is loaded and all necessary browser state is
initialized to support the start of the extension's background page.
#### Event: 'file-system-access-restricted'
Returns:
* `event` Event
* `details` Object
* `origin` string - The origin that initiated access to the blocked path.
* `isDirectory` boolean - Whether or not the path is a directory.
* `path` string - The blocked path attempting to be accessed.
* `callback` Function
* `action` string - The action to take as a result of the restricted path access attempt.
* `allow` - This will allow `path` to be accessed despite restricted status.
* `deny` - This will block the access request and trigger an [`AbortError`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort).
* `tryAgain` - This will open a new file picker and allow the user to choose another path.
```js
const { app, dialog, BrowserWindow, session } = require('electron')
async function createWindow () {
const mainWindow = new BrowserWindow()
await mainWindow.loadURL('https://buzzfeed.com')
session.defaultSession.on('file-system-access-restricted', async (e, details, callback) => {
const { origin, path } = details
const { response } = await dialog.showMessageBox({
message: `Are you sure you want ${origin} to open restricted path ${path}?`,
title: 'File System Access Restricted',
buttons: ['Choose a different folder', 'Allow', 'Cancel'],
cancelId: 2
})
if (response === 0) {
callback('tryAgain')
} else if (response === 1) {
callback('allow')
} else {
callback('deny')
}
})
mainWindow.webContents.executeJavaScript(`
window.showDirectoryPicker({
id: 'electron-demo',
mode: 'readwrite',
startIn: 'downloads',
}).catch(e => {
console.log(e)
})`, true
)
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
```
#### Event: 'preconnect'
Returns:

View File

@@ -80,14 +80,14 @@
* `followWindow` - The backdrop should automatically appear active when the window is active, and inactive when it is not. This is the default.
* `active` - The backdrop should always appear active.
* `inactive` - The backdrop should always appear inactive.
* `titleBarStyle` string (optional) _macOS_ _Windows_ - The style of window title bar.
* `titleBarStyle` string (optional) - The style of window title bar.
Default is `default`. Possible values are:
* `default` - Results in the standard title bar for macOS or Windows respectively.
* `hidden` - Results in a hidden title bar and a full size content window. On macOS, the window still has the standard window controls (“traffic lights”) in the top left. On Windows, when combined with `titleBarOverlay: true` it will activate the Window Controls Overlay (see `titleBarOverlay` for more information), otherwise no window controls will be shown.
* `hiddenInset` _macOS_ - Only on macOS, results in a hidden title bar
* `hidden` - Results in a hidden title bar and a full size content window. On macOS, the window still has the standard window controls (“traffic lights”) in the top left. On Windows and Linux, when combined with `titleBarOverlay: true` it will activate the Window Controls Overlay (see `titleBarOverlay` for more information), otherwise no window controls will be shown.
* `hiddenInset` _macOS_ - Results in a hidden title bar
with an alternative look where the traffic light buttons are slightly
more inset from the window edge.
* `customButtonsOnHover` _macOS_ - Only on macOS, results in a hidden
* `customButtonsOnHover` _macOS_ - Results in a hidden
title bar and a full size content window, the traffic light buttons will
display when being hovered over in the top left of the window.
**Note:** This option is currently experimental.

View File

@@ -3,9 +3,9 @@
* `webPreferences` [WebPreferences](web-preferences.md?inline) (optional) - Settings of web page's features.
* `paintWhenInitiallyHidden` boolean (optional) - Whether the renderer should be active when `show` is `false` and it has just been created. In order for `document.visibilityState` to work correctly on first load with `show: false` you should set this to `false`. Setting this to `false` will cause the `ready-to-show` event to not fire. Default is `true`.
* `titleBarOverlay` Object | Boolean (optional) - When using a frameless window in conjunction with `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so that the standard window controls ("traffic lights" on macOS) are visible, this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars]. Specifying `true` will result in an overlay with default system colors. Default is `false`.
* `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled. Default is the system color.
* `color` String (optional) _Windows_ _Linux_ - The CSS color of the Window Controls Overlay when enabled. Default is the system color.
* `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled. Default is the system color.
* `height` Integer (optional) _macOS_ _Windows_ - The height of the title bar and Window Controls Overlay in pixels. Default is system height.
* `height` Integer (optional) - The height of the title bar and Window Controls Overlay in pixels. Default is system height.
[overlay-css-env-vars]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables
[overlay-javascript-apis]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis

View File

@@ -2,7 +2,7 @@
> Get system preferences.
Process: [Main](../glossary.md#main-process)
Process: [Main](../glossary.md#main-process), [Utility](../glossary.md#utility-process)
```js
const { systemPreferences } = require('electron')

View File

@@ -78,8 +78,7 @@ Electron
## Structure of Other Directories
* **.circleci** - Config file for CI with CircleCI.
* **.github** - GitHub-specific config files including issues templates and CODEOWNERS.
* **.github** - GitHub-specific config files including issues templates, CI with GitHub Actions and CODEOWNERS.
* **dist** - Temporary directory created by `script/create-dist.py` script
when creating a distribution.
* **node_modules** - Third party node modules used for building.

View File

@@ -97,19 +97,12 @@ is as follows:
<img src="https://raw.githubusercontent.com/nodejs/Release/main/schedule.svg?sanitize=true" alt="Releases">
As a rule, stable branches of Electron do not receive Node.js upgrades after they have been cut.
If Electron has recently updated its `main` branch to a new major version of Node.js, the next stable
branch to be cut will be released with the new version.
Patch upgrades of Node that contain significant security or bug fixes, and are submitted
more than 2 weeks prior to a stable release date, will be accepted into an Electron alpha
or beta release branch.
Minor upgrades of Node that contain significant security or bug fixes, and are submitted
more than 2 weeks prior to a stable release date may be accepted into an Electron alpha or
beta release branch on a case-by-case basis. These requests will be reviewed and voted on
by the [Releases Working Group](https://github.com/electron/governance/tree/main/wg-releases),
to ensure minimal disruption for developers who may be consuming alpha or beta releases.
Stable release lines of Electron will receive minor and patch bumps of Node.js after they are released.
Patch bumps to Node.js will be released in patch releases of Electron, and minor bumps to Node.js will result in a minor release of Electron.
Security-only release branches will receive security-related changes from Node.js releases, but not the full release.
### Breaking API changes

View File

@@ -91,7 +91,7 @@ win.setWindowButtonVisibility(false)
> combining `frame: false` with `win.setWindowButtonVisibility(true)` will yield the same
> layout outcome as setting `titleBarStyle: 'hidden'`.
## Window Controls Overlay _macOS_ _Windows_
## Window Controls Overlay
The [Window Controls Overlay API][] is a web standard that gives web apps the ability to
customize their title bar region when installed on desktop. Electron exposes this API
@@ -115,12 +115,11 @@ const win = new BrowserWindow({
})
```
On either platform `titleBarOverlay` can also be an object. On both macOS and Windows, the height of the overlay can be specified with the `height` property. On Windows, the color of the overlay and its symbols can be specified using the `color` and `symbolColor` properties respectively. `rgba()`, `hsla()`, and `#RRGGBBAA` color formats are supported to apply transparency.
On either platform `titleBarOverlay` can also be an object. The height of the overlay can be specified with the `height` property. On Windows and Linux, the color of the overlay and can be specified using the `color` property. On Windows and Linux, the color of the overlay and its symbols can be specified using the `color` and `symbolColor` properties respectively. The `rgba()`, `hsla()`, and `#RRGGBBAA` color formats are supported to apply transparency.
If a color option is not specified, the color will default to its system color for the window control buttons. Similarly, if the height option is not specified it will default to the default height:
```js title='main.js'
// on Windows
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',

View File

@@ -350,6 +350,7 @@ auto_filenames = {
utility_bundle_deps = [
"lib/browser/api/net-fetch.ts",
"lib/browser/api/system-preferences.ts",
"lib/browser/message-port-main.ts",
"lib/common/api/net-client-request.ts",
"lib/common/define-properties.ts",

View File

@@ -44,6 +44,10 @@ filenames = {
"shell/browser/ui/status_icon_gtk.h",
"shell/browser/ui/tray_icon_linux.cc",
"shell/browser/ui/tray_icon_linux.h",
"shell/browser/ui/views/opaque_frame_view.cc",
"shell/browser/ui/views/opaque_frame_view.h",
"shell/browser/ui/views/caption_button_placeholder_container.cc",
"shell/browser/ui/views/caption_button_placeholder_container.h",
"shell/browser/ui/views/client_frame_view_linux.cc",
"shell/browser/ui/views/client_frame_view_linux.h",
"shell/common/application_info_linux.cc",
@@ -543,7 +547,6 @@ filenames = {
"shell/common/api/electron_api_clipboard.h",
"shell/common/api/electron_api_command_line.cc",
"shell/common/api/electron_api_environment.cc",
"shell/common/api/electron_api_key_weak_map.h",
"shell/common/api/electron_api_native_image.cc",
"shell/common/api/electron_api_native_image.h",
"shell/common/api/electron_api_net.cc",
@@ -555,8 +558,6 @@ filenames = {
"shell/common/api/electron_bindings.cc",
"shell/common/api/electron_bindings.h",
"shell/common/api/features.cc",
"shell/common/api/object_life_monitor.cc",
"shell/common/api/object_life_monitor.h",
"shell/common/application_info.cc",
"shell/common/application_info.h",
"shell/common/asar/archive.cc",

View File

@@ -1,5 +1,7 @@
import { EventEmitter } from 'events';
import type { BaseWindow as TLWT } from 'electron/main';
import { TouchBar } from 'electron/main';
const { BaseWindow } = process._linkedBinding('electron_browser_base_window') as { BaseWindow: typeof TLWT };
Object.setPrototypeOf(BaseWindow.prototype, EventEmitter.prototype);
@@ -15,6 +17,10 @@ BaseWindow.prototype._init = function (this: TLWT) {
}
};
BaseWindow.prototype.setTouchBar = function (touchBar) {
(TouchBar as any)._setOnWindow(touchBar, this);
};
// Properties
Object.defineProperty(BaseWindow.prototype, 'autoHideMenuBar', {

View File

@@ -1,4 +1,4 @@
import { BaseWindow, WebContents, TouchBar, BrowserView } from 'electron/main';
import { BaseWindow, WebContents, BrowserView } from 'electron/main';
import type { BrowserWindow as BWT } from 'electron/main';
const { BrowserWindow } = process._linkedBinding('electron_browser_window') as { BrowserWindow: typeof BWT };
@@ -100,10 +100,6 @@ BrowserWindow.fromBrowserView = (browserView: BrowserView) => {
return BrowserWindow.fromWebContents(browserView.webContents);
};
BrowserWindow.prototype.setTouchBar = function (touchBar) {
(TouchBar as any)._setOnWindow(touchBar, this);
};
// Forwarded to webContents:
BrowserWindow.prototype.loadURL = function (...args) {
@@ -209,7 +205,12 @@ BrowserWindow.prototype.getBrowserViews = function () {
BrowserWindow.prototype.setTopBrowserView = function (browserView: BrowserView) {
if (browserView.ownerWindow !== this) { throw new Error('Given BrowserView is not attached to the window'); }
this.addBrowserView(browserView);
const idx = this._browserViews.indexOf(browserView);
if (idx >= 0) {
this.contentView.addChildView(browserView.webContentsView);
this._browserViews.splice(idx, 1);
this._browserViews.push(browserView);
}
};
module.exports = BrowserWindow;

View File

@@ -284,7 +284,7 @@ const escapeItemSymbol = Symbol('escape item');
class TouchBar extends EventEmitter implements Electron.TouchBar {
// Bind a touch bar to a window
static _setOnWindow (touchBar: TouchBar | Electron.TouchBarConstructorOptions['items'], window: Electron.BrowserWindow) {
static _setOnWindow (touchBar: TouchBar | Electron.TouchBarConstructorOptions['items'], window: Electron.BaseWindow) {
if (window._touchBar != null) {
window._touchBar._removeFromWindow(window);
}
@@ -383,7 +383,7 @@ class TouchBar extends EventEmitter implements Electron.TouchBar {
return this[escapeItemSymbol];
}
_addToWindow (window: Electron.BrowserWindow) {
_addToWindow (window: Electron.BaseWindow) {
const { id } = window;
// Already added to window
@@ -439,7 +439,7 @@ class TouchBar extends EventEmitter implements Electron.TouchBar {
escapeItemListener(this.escapeItem);
}
_removeFromWindow (window: Electron.BrowserWindow) {
_removeFromWindow (window: Electron.BaseWindow) {
const removeListeners = this.windowListeners.get(window.id);
if (removeListeners != null) removeListeners();
}

View File

@@ -1,4 +1,5 @@
// Utility side modules, please sort alphabetically.
export const utilityNodeModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'net', loader: () => require('./net') }
{ name: 'net', loader: () => require('./net') },
{ name: 'systemPreferences', loader: () => require('@electron/internal/browser/api/system-preferences') }
];

View File

@@ -17,6 +17,14 @@ const { makeRequireFunction } = __non_webpack_require__('internal/modules/helper
global.module = new Module('electron/js2c/worker_init');
global.require = makeRequireFunction(global.module);
// See WebWorkerObserver::WorkerScriptReadyForEvaluation.
if ((globalThis as any).blinkfetch) {
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers'];
for (const key of keys) {
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
}
}
// Set the __filename to the path of html file if it is file: protocol.
// NB. 'self' isn't defined in an AudioWorklet.
if (typeof self !== 'undefined' && self.location.protocol === 'file:') {

View File

@@ -19,8 +19,6 @@
"@types/chai-as-promised": "^7.1.3",
"@types/dirty-chai": "^2.0.2",
"@types/express": "^4.17.13",
"@types/fs-extra": "^9.0.1",
"@types/klaw": "^3.0.1",
"@types/minimist": "^1.2.0",
"@types/mocha": "^7.0.2",
"@types/node": "^20.9.0",
@@ -51,10 +49,8 @@
"events": "^3.2.0",
"express": "^4.16.4",
"folder-hash": "^2.1.1",
"fs-extra": "^9.0.1",
"got": "^11.8.5",
"husky": "^8.0.1",
"klaw": "^3.0.0",
"lint": "^1.1.2",
"lint-staged": "^10.2.11",
"minimist": "^1.2.6",

View File

@@ -0,0 +1,7 @@
cherry-pick-93c3cf1c787f.patch
cherry-pick-33051b084850.patch
cherry-pick-b845fed99111.patch
cherry-pick-771e74ab497d.patch
cherry-pick-8f07d39227f6.patch
cherry-pick-b3c64851765c.patch
cherry-pick-9463ce9cd8d9.patch

View File

@@ -0,0 +1,332 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Antonio Maiorano <amaiorano@google.com>
Date: Mon, 10 Jun 2024 10:52:30 -0400
Subject: Loop exit restructurizer: don't iterate over uses while mutating them
(#6644)
The SkipBlockWithBranch function does the following:
- Splits the block into three blocks with an if-then-endif structure.
- Moves most instructions from the original block into the "then" block
- If any of those values are used outside the original block, they are
propagated through newly-constructed phis in the 'endif' block.
This algorithm had a bug where the uses of a value were being scanned
while the uses were also being updated. In some cases a downstream
out-of-block use could be skipped. That results in an invalid module
because now the original definition is now in the 'then' block, which
does not dominate the downstream out-of-block use.
Add a test that demonstrates the problem.
Bug: chromium:339171223
Change-Id: Ia34fd7a2fe84de635289f7499772d11866a28e24
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5615350
Reviewed-by: James Price <jrprice@google.com>
Reviewed-by: dan sinclair <dsinclair@google.com>
diff --git a/lib/Transforms/Scalar/DxilRemoveUnstructuredLoopExits.cpp b/lib/Transforms/Scalar/DxilRemoveUnstructuredLoopExits.cpp
index ef6718f0f22ee33e3f16f9801a64c1a6fb6c653a..70e6ccd8ddbaeabdb469710ad8529933f0286abd 100644
--- a/lib/Transforms/Scalar/DxilRemoveUnstructuredLoopExits.cpp
+++ b/lib/Transforms/Scalar/DxilRemoveUnstructuredLoopExits.cpp
@@ -322,24 +322,26 @@ static void SkipBlockWithBranch(BasicBlock *bb, Value *cond, Loop *L,
BranchInst::Create(end, body, cond, bb);
for (Instruction &inst : *body) {
- PHINode *phi = nullptr;
// For each user that's outside of 'body', replace its use of 'inst' with a
// phi created in 'end'
- for (auto it = inst.user_begin(); it != inst.user_end();) {
- Instruction *user_inst = cast<Instruction>(*(it++));
- if (user_inst == phi)
- continue;
+ SmallPtrSet<Instruction *, 8> users_in_other_blocks;
+ for (auto *user : inst.users()) {
+ Instruction *user_inst = cast<Instruction>(user);
if (user_inst->getParent() != body) {
- if (!phi) {
- phi = PHINode::Create(inst.getType(), 2, "", &*end->begin());
- phi->addIncoming(GetDefaultValue(inst.getType()), bb);
- phi->addIncoming(&inst, body);
- }
+ users_in_other_blocks.insert(user_inst);
+ }
+ }
+ if (users_in_other_blocks.size() > 0) {
+ auto *phi = PHINode::Create(inst.getType(), 2, "", &*end->begin());
+ phi->addIncoming(GetDefaultValue(inst.getType()), bb);
+ phi->addIncoming(&inst, body);
+
+ for (auto *user_inst : users_in_other_blocks) {
user_inst->replaceUsesOfWith(&inst, phi);
}
- } // For each user of inst of body
- } // For each inst in body
+ }
+ } // For each inst in body
L->addBasicBlockToLoop(body, *LI);
L->addBasicBlockToLoop(end, *LI);
diff --git a/tools/clang/test/DXC/Passes/DxilRemoveUnstructuredLoopExits/struct_exit_wrap_value_iteration_bug.ll b/tools/clang/test/DXC/Passes/DxilRemoveUnstructuredLoopExits/struct_exit_wrap_value_iteration_bug.ll
new file mode 100644
index 0000000000000000000000000000000000000000..ee912c929bdc0424959a29d16c3d5c64f885f809
--- /dev/null
+++ b/tools/clang/test/DXC/Passes/DxilRemoveUnstructuredLoopExits/struct_exit_wrap_value_iteration_bug.ll
@@ -0,0 +1,257 @@
+; RUN: %dxopt %s -hlsl-passes-resume -loop-unroll,StructurizeLoopExits=1 -S | FileCheck %s
+
+; The Loop exit structurizer will wrap the definition of %DerivFineX3 in a conditional block.
+; Its value will later be propagated into a phi, and that phi replaces all further uses
+; of %DerivFineX3.
+;
+; Tests that a bug is fixed where the code used to iterate through the uses of a value
+; while also updating those uses. The old code would fail to update the definition
+; of %g.i.2.i3 and the result would be an invalid module: %DerivFineX3 would not dominate
+; all its uses.
+
+
+; CHECK: define void @main
+; CHECK-NOT: %DerivFineX3
+; CHECK: "\01?f@@YAXXZ.exit.i":
+; CHECK-NEXT: br i1 true, label %dx.struct_exit.cond_end, label %dx.struct_exit.cond_body
+
+; CHECK: dx.struct_exit.cond_body:
+; CHECK: %DerivFineX3 = call
+; CHECK: br label %dx.struct_exit.cond_end
+
+; CHECK: dx.struct_exit.cond_end:
+; CHECK: = phi {{.*}} %DerivFineX3
+; CHECK: br
+; CHECK-NOT: %DerivFineX3
+; CHECK: ret void
+
+
+;
+;
+; void f() {
+; int l_1 = 10;
+; for (int l = 0, l_2 = 0; l < 5 && l_2 < 1; l++, l_2++) {
+; while (1 < l_1) { }
+; }
+; }
+;
+;
+; struct tint_symbol {
+; float4 value : SV_Target0;
+; };
+;
+; float4 main_inner() {
+; float4 g = float4(0.0f, 0.0f, 0.0f, 0.0f);
+; bool2 true2 = (true).xx;
+; uint2 _e8 = (0u).xx;
+; do {
+; if (_e8.x != 2u) {
+; f();
+; float4 _e15 = ddx_fine(g);
+; if (_e8[_e8.x] == 2u) {
+; g = _e15;
+; } else {
+; f();
+; }
+; switch(_e8.x) {
+; case 3u: {
+; break;
+; }
+; case 2u: {
+; g = _e15;
+; break;
+; }
+; default: {
+; g = _e15;
+; }
+; }
+; f();
+; }
+; } while(!all(true2));
+; return g;
+;}
+;
+;tint_symbol main() {
+; float4 inner_result = main_inner();
+; tint_symbol wrapper_result = (tint_symbol)0;
+; wrapper_result.value = inner_result;
+; return wrapper_result;
+;}
+
+target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
+target triple = "dxil-ms-dx"
+
+%struct.tint_symbol = type { <4 x float> }
+
+; Function Attrs: nounwind
+define void @main(<4 x float>* noalias) #0 {
+entry:
+ %1 = alloca [2 x i32], align 4
+ %2 = getelementptr inbounds [2 x i32], [2 x i32]* %1, i32 0, i32 0, !dbg !20 ; line:17 col:9
+ store i32 0, i32* %2, align 4, !dbg !20 ; line:17 col:9
+ %3 = getelementptr inbounds [2 x i32], [2 x i32]* %1, i32 0, i32 1, !dbg !20 ; line:17 col:9
+ store i32 0, i32* %3, align 4, !dbg !20 ; line:17 col:9
+ br label %do.body.i, !dbg !26 ; line:18 col:3
+
+do.body.i: ; preds = %do.cond.i, %entry
+ %g.i.0.i0 = phi float [ 0.000000e+00, %entry ], [ %g.i.3.i0, %do.cond.i ]
+ %g.i.0.i1 = phi float [ 0.000000e+00, %entry ], [ %g.i.3.i1, %do.cond.i ]
+ %g.i.0.i2 = phi float [ 0.000000e+00, %entry ], [ %g.i.3.i2, %do.cond.i ]
+ %g.i.0.i3 = phi float [ 0.000000e+00, %entry ], [ %g.i.3.i3, %do.cond.i ]
+ %4 = getelementptr inbounds [2 x i32], [2 x i32]* %1, i32 0, i32 0, !dbg !27 ; line:19 col:9
+ %5 = load i32, i32* %4, align 4, !dbg !27 ; line:19 col:9
+ %cmp.i = icmp ne i32 %5, 2, !dbg !28 ; line:19 col:15
+ br i1 %cmp.i, label %for.cond.i.i, label %do.cond.i, !dbg !27 ; line:19 col:9
+
+for.cond.i.i: ; preds = %do.body.i
+ br i1 true, label %while.cond.i.i.preheader, label %"\01?f@@YAXXZ.exit.i", !dbg !29 ; line:4 col:3
+
+while.cond.i.i.preheader: ; preds = %for.cond.i.i
+ br label %while.cond.i.i, !dbg !32 ; line:5 col:5
+
+while.cond.i.i: ; preds = %while.cond.i.i.preheader, %while.cond.i.i
+ br label %while.cond.i.i, !dbg !32 ; line:5 col:5
+
+"\01?f@@YAXXZ.exit.i": ; preds = %for.cond.i.i
+ %DerivFineX = call float @dx.op.unary.f32(i32 85, float %g.i.0.i0), !dbg !33 ; line:21 col:21 ; DerivFineX(value)
+ %DerivFineX1 = call float @dx.op.unary.f32(i32 85, float %g.i.0.i1), !dbg !33 ; line:21 col:21 ; DerivFineX(value)
+ %DerivFineX2 = call float @dx.op.unary.f32(i32 85, float %g.i.0.i2), !dbg !33 ; line:21 col:21 ; DerivFineX(value)
+ %DerivFineX3 = call float @dx.op.unary.f32(i32 85, float %g.i.0.i3), !dbg !33 ; line:21 col:21 ; DerivFineX(value)
+ %6 = getelementptr inbounds [2 x i32], [2 x i32]* %1, i32 0, i32 0, !dbg !34 ; line:22 col:15
+ %7 = load i32, i32* %6, align 4, !dbg !34 ; line:22 col:15
+ %8 = getelementptr [2 x i32], [2 x i32]* %1, i32 0, i32 %7, !dbg !35 ; line:22 col:11
+ %9 = load i32, i32* %8, !dbg !35, !tbaa !36 ; line:22 col:11
+ %cmp6.i = icmp eq i32 %9, 2, !dbg !40 ; line:22 col:22
+ br i1 %cmp6.i, label %if.end.i, label %for.cond.i.19.i, !dbg !35 ; line:22 col:11
+
+for.cond.i.19.i: ; preds = %"\01?f@@YAXXZ.exit.i"
+ br i1 true, label %while.cond.i.24.i.preheader, label %if.end.i, !dbg !41 ; line:4 col:3
+
+while.cond.i.24.i.preheader: ; preds = %for.cond.i.19.i
+ br label %while.cond.i.24.i, !dbg !43 ; line:5 col:5
+
+while.cond.i.24.i: ; preds = %while.cond.i.24.i.preheader, %while.cond.i.24.i
+ br label %while.cond.i.24.i, !dbg !43 ; line:5 col:5
+
+if.end.i: ; preds = %for.cond.i.19.i, %"\01?f@@YAXXZ.exit.i"
+ %g.i.1.i0 = phi float [ %DerivFineX, %"\01?f@@YAXXZ.exit.i" ], [ %g.i.0.i0, %for.cond.i.19.i ]
+ %g.i.1.i1 = phi float [ %DerivFineX1, %"\01?f@@YAXXZ.exit.i" ], [ %g.i.0.i1, %for.cond.i.19.i ]
+ %g.i.1.i2 = phi float [ %DerivFineX2, %"\01?f@@YAXXZ.exit.i" ], [ %g.i.0.i2, %for.cond.i.19.i ]
+ %g.i.1.i3 = phi float [ %DerivFineX3, %"\01?f@@YAXXZ.exit.i" ], [ %g.i.0.i3, %for.cond.i.19.i ]
+ %10 = getelementptr inbounds [2 x i32], [2 x i32]* %1, i32 0, i32 0, !dbg !44 ; line:27 col:14
+ %11 = load i32, i32* %10, align 4, !dbg !44 ; line:27 col:14
+ switch i32 %11, label %sw.default.i [
+ i32 3, label %for.cond.i.5.i
+ i32 2, label %sw.bb.10.i
+ ], !dbg !45 ; line:27 col:7
+
+sw.bb.10.i: ; preds = %if.end.i
+ br label %for.cond.i.5.i, !dbg !46 ; line:33 col:11
+
+sw.default.i: ; preds = %if.end.i
+ br label %for.cond.i.5.i, !dbg !47 ; line:38 col:7
+
+for.cond.i.5.i: ; preds = %if.end.i, %sw.bb.10.i, %sw.default.i
+ %g.i.2.i0 = phi float [ %DerivFineX, %sw.default.i ], [ %DerivFineX, %sw.bb.10.i ], [ %g.i.1.i0, %if.end.i ]
+ %g.i.2.i1 = phi float [ %DerivFineX1, %sw.default.i ], [ %DerivFineX1, %sw.bb.10.i ], [ %g.i.1.i1, %if.end.i ]
+ %g.i.2.i2 = phi float [ %DerivFineX2, %sw.default.i ], [ %DerivFineX2, %sw.bb.10.i ], [ %g.i.1.i2, %if.end.i ]
+ %g.i.2.i3 = phi float [ %DerivFineX3, %sw.default.i ], [ %DerivFineX3, %sw.bb.10.i ], [ %g.i.1.i3, %if.end.i ]
+ br i1 true, label %while.cond.i.10.i.preheader, label %do.cond.i, !dbg !48 ; line:4 col:3
+
+while.cond.i.10.i.preheader: ; preds = %for.cond.i.5.i
+ br label %while.cond.i.10.i, !dbg !50 ; line:5 col:5
+
+while.cond.i.10.i: ; preds = %while.cond.i.10.i.preheader, %while.cond.i.10.i
+ br label %while.cond.i.10.i, !dbg !50 ; line:5 col:5
+
+do.cond.i: ; preds = %for.cond.i.5.i, %do.body.i
+ %g.i.3.i0 = phi float [ %g.i.0.i0, %do.body.i ], [ %g.i.2.i0, %for.cond.i.5.i ]
+ %g.i.3.i1 = phi float [ %g.i.0.i1, %do.body.i ], [ %g.i.2.i1, %for.cond.i.5.i ]
+ %g.i.3.i2 = phi float [ %g.i.0.i2, %do.body.i ], [ %g.i.2.i2, %for.cond.i.5.i ]
+ %g.i.3.i3 = phi float [ %g.i.0.i3, %do.body.i ], [ %g.i.2.i3, %for.cond.i.5.i ]
+ br i1 false, label %do.body.i, label %"\01?main_inner@@YA?AV?$vector@M$03@@XZ.exit", !dbg !51 ; line:41 col:3
+
+"\01?main_inner@@YA?AV?$vector@M$03@@XZ.exit": ; preds = %do.cond.i
+ %g.i.3.i3.lcssa = phi float [ %g.i.3.i3, %do.cond.i ]
+ %g.i.3.i2.lcssa = phi float [ %g.i.3.i2, %do.cond.i ]
+ %g.i.3.i1.lcssa = phi float [ %g.i.3.i1, %do.cond.i ]
+ %g.i.3.i0.lcssa = phi float [ %g.i.3.i0, %do.cond.i ]
+ call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %g.i.3.i0.lcssa), !dbg !52 ; line:49 col:10 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
+ call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %g.i.3.i1.lcssa), !dbg !52 ; line:49 col:10 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
+ call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %g.i.3.i2.lcssa), !dbg !52 ; line:49 col:10 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
+ call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %g.i.3.i3.lcssa), !dbg !52 ; line:49 col:10 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
+ ret void, !dbg !53 ; line:49 col:3
+}
+
+; Function Attrs: nounwind
+declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #0
+
+; Function Attrs: nounwind readnone
+declare float @dx.op.unary.f32(i32, float) #1
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
+
+!llvm.module.flags = !{!0}
+!pauseresume = !{!1}
+!llvm.ident = !{!2}
+!dx.version = !{!3}
+!dx.valver = !{!4}
+!dx.shaderModel = !{!5}
+!dx.typeAnnotations = !{!6, !9}
+!dx.entryPoints = !{!16}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !{!"hlsl-dxilemit", !"hlsl-dxilload"}
+!2 = !{!"dxc(private) 1.8.0.14549 (main, 0781ded87-dirty)"}
+!3 = !{i32 1, i32 0}
+!4 = !{i32 1, i32 8}
+!5 = !{!"ps", i32 6, i32 0}
+!6 = !{i32 0, %struct.tint_symbol undef, !7}
+!7 = !{i32 16, !8}
+!8 = !{i32 6, !"value", i32 3, i32 0, i32 4, !"SV_Target0", i32 7, i32 9}
+!9 = !{i32 1, void (<4 x float>*)* @main, !10}
+!10 = !{!11, !13}
+!11 = !{i32 0, !12, !12}
+!12 = !{}
+!13 = !{i32 1, !14, !15}
+!14 = !{i32 4, !"SV_Target0", i32 7, i32 9}
+!15 = !{i32 0}
+!16 = !{void (<4 x float>*)* @main, !"main", !17, null, null}
+!17 = !{null, !18, null}
+!18 = !{!19}
+!19 = !{i32 0, !"SV_Target", i8 9, i8 16, !15, i8 0, i32 1, i8 4, i32 0, i8 0, null}
+!20 = !DILocation(line: 17, column: 9, scope: !21, inlinedAt: !24)
+!21 = !DISubprogram(name: "main_inner", scope: !22, file: !22, line: 14, type: !23, isLocal: false, isDefinition: true, scopeLine: 14, flags: DIFlagPrototyped, isOptimized: false)
+!22 = !DIFile(filename: "s2.hlsl", directory: "")
+!23 = !DISubroutineType(types: !12)
+!24 = distinct !DILocation(line: 46, column: 25, scope: !25)
+!25 = !DISubprogram(name: "main", scope: !22, file: !22, line: 45, type: !23, isLocal: false, isDefinition: true, scopeLine: 45, flags: DIFlagPrototyped, isOptimized: false, function: void (<4 x float>*)* @main)
+!26 = !DILocation(line: 18, column: 3, scope: !21, inlinedAt: !24)
+!27 = !DILocation(line: 19, column: 9, scope: !21, inlinedAt: !24)
+!28 = !DILocation(line: 19, column: 15, scope: !21, inlinedAt: !24)
+!29 = !DILocation(line: 4, column: 3, scope: !30, inlinedAt: !31)
+!30 = !DISubprogram(name: "f", scope: !22, file: !22, line: 2, type: !23, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false)
+!31 = distinct !DILocation(line: 20, column: 7, scope: !21, inlinedAt: !24)
+!32 = !DILocation(line: 5, column: 5, scope: !30, inlinedAt: !31)
+!33 = !DILocation(line: 21, column: 21, scope: !21, inlinedAt: !24)
+!34 = !DILocation(line: 22, column: 15, scope: !21, inlinedAt: !24)
+!35 = !DILocation(line: 22, column: 11, scope: !21, inlinedAt: !24)
+!36 = !{!37, !37, i64 0}
+!37 = !{!"int", !38, i64 0}
+!38 = !{!"omnipotent char", !39, i64 0}
+!39 = !{!"Simple C/C++ TBAA"}
+!40 = !DILocation(line: 22, column: 22, scope: !21, inlinedAt: !24)
+!41 = !DILocation(line: 4, column: 3, scope: !30, inlinedAt: !42)
+!42 = distinct !DILocation(line: 25, column: 9, scope: !21, inlinedAt: !24)
+!43 = !DILocation(line: 5, column: 5, scope: !30, inlinedAt: !42)
+!44 = !DILocation(line: 27, column: 14, scope: !21, inlinedAt: !24)
+!45 = !DILocation(line: 27, column: 7, scope: !21, inlinedAt: !24)
+!46 = !DILocation(line: 33, column: 11, scope: !21, inlinedAt: !24)
+!47 = !DILocation(line: 38, column: 7, scope: !21, inlinedAt: !24)
+!48 = !DILocation(line: 4, column: 3, scope: !30, inlinedAt: !49)
+!49 = distinct !DILocation(line: 39, column: 7, scope: !21, inlinedAt: !24)
+!50 = !DILocation(line: 5, column: 5, scope: !30, inlinedAt: !49)
+!51 = !DILocation(line: 41, column: 3, scope: !21, inlinedAt: !24)
+!52 = !DILocation(line: 49, column: 10, scope: !25)
+!53 = !DILocation(line: 49, column: 3, scope: !25)

View File

@@ -0,0 +1,116 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Antonio Maiorano <amaiorano@google.com>
Date: Thu, 20 Jun 2024 14:02:42 -0400
Subject: indvars: don't replace a phi when that breaks LCSSA (#6695)
Induction variable simplification (indvars) tries to rewrite exit
values; these appear as phi nodes in loop exit blocks. If the
replacement for the phi is still in the loop, then that would break the
LCSSA property. Don't do that.
Add a test for this.
Bug: chromium:345993680
Change-Id: Ib2330afa3c6f47373cb4336cfd00e851044fea3a
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5645925
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
index f5b1455d5932b63dfef699991c5eeab38e447a7d..e6ff7b3ab4d81bbb782f0bd0a7b5185a30fd1285 100644
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -24,7 +24,6 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Scalar.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
@@ -41,11 +40,13 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SimplifyIndVar.h"
@@ -698,6 +699,16 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) {
continue;
}
+ // HLSL Change Begin
+ // Avoid breaking LCSSA: Don't replace the PHI if its replacement
+ // is defined inside the loop.
+ if (auto *ExitValInst = dyn_cast<Instruction>(ExitVal)) {
+ if (L->contains(ExitValInst)) {
+ continue;
+ }
+ }
+ // HLSL Change End
+
// Collect all the candidate PHINodes to be rewritten.
RewritePhiSet.push_back(
RewritePhi(PN, i, ExitVal, HighCost, LCSSASafePhiForRAUW));
diff --git a/test/HLSL/passes/indvars/preserve-phi-when-replacement-is-in-loop.ll b/test/HLSL/passes/indvars/preserve-phi-when-replacement-is-in-loop.ll
new file mode 100644
index 0000000000000000000000000000000000000000..b550ce993837814229f8223a47b2af328cc7c87c
--- /dev/null
+++ b/test/HLSL/passes/indvars/preserve-phi-when-replacement-is-in-loop.ll
@@ -0,0 +1,49 @@
+; RUN: opt < %s -indvars -S | FileCheck %s
+
+; The inner loop (%header1) has a fixed trip count.
+; The indvars pass is tempted to delete the phi instruction %hexit,
+; and replace its uses with %add3.
+; But %hexit is used in %latch0, which is outside the inner loop and
+; its exit block. Deleting the phi %hexit would break LCSSA form.
+
+; CHECK: @main
+; CHECK: exit1:
+; CHECK-NEXT: %hexit = phi i32 [ %hnext, %header1 ]
+; CHECK-NEXT: br label %latch0
+
+; CHECK: latch0:
+
+target triple = "dxil-ms-dx"
+
+define void @main(i32 %arg) {
+entry:
+ br label %header0
+
+header0:
+ %isgt0 = icmp sgt i32 %arg, 0
+ %smax = select i1 %isgt0, i32 %arg, i32 0
+ %h0 = add i32 %smax, 1
+ %j0 = add i32 %smax, 2
+ %doinner = icmp slt i32 %j0, 1
+ br i1 %doinner, label %header1.pre, label %latch0
+
+header1.pre:
+ br label %header1
+
+header1:
+ %hi = phi i32 [ %hnext, %header1 ], [ %h0, %header1.pre ]
+ %ji = phi i32 [ %jnext, %header1 ], [ %j0, %header1.pre ]
+ %add3 = add i32 %smax, 3
+ %hnext = add i32 %hi, 1
+ %jnext = add nsw i32 %ji, 1 ; the nsw here is essential
+ %do1again = icmp slt i32 %ji, %add3
+ br i1 %do1again, label %header1, label %exit1
+
+exit1:
+ %hexit = phi i32 [ %hnext, %header1 ]
+ br label %latch0
+
+latch0:
+ %useh = phi i32 [ %h0, %header0 ], [ %hexit, %exit1 ]
+ br label %header0
+}

View File

@@ -0,0 +1,151 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Antonio Maiorano <amaiorano@google.com>
Date: Thu, 20 Jun 2024 14:49:58 -0400
Subject: Fix crash in scalarrepl-param-hlsl when dynamically indexing a GEP of
a constant indexed GEP (#6670)
When processing global values to determine when to flatten vectors, this
pass was only checking the immdiate users of the value for non-dynamic
indexing of the vector. But this would fail in the case of a dynamic
indexed GEP of a constant indexed GEP (e.g. h[0][a]) because the first
level GEP was constant indexed, but not the second. We fix this by
checking the full User tree of the value in `hasDynamicVectorIndexing`.
Bug: chromium:342428008
Change-Id: Ibf2ae3a6528cfc9b50634058385c5a45aa1d3b75
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5645927
Reviewed-by: James Price <jrprice@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp b/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
index 9b843ef0e49e554001b827e30eb6256853d90f5b..b1b38c0ee038dedb2064f5726663992a5bec736b 100644
--- a/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
@@ -1645,6 +1645,10 @@ bool hasDynamicVectorIndexing(Value *V) {
}
}
}
+ // Also recursively check the uses of this User to find a possible
+ // dynamically indexed GEP of this GEP.
+ if (hasDynamicVectorIndexing(U))
+ return true;
}
return false;
}
diff --git a/tools/clang/test/DXC/Passes/ScalarReplHLSL/scalarrepl-param-hlsl-dyn-idx-gep-of-const-idx-gep.ll b/tools/clang/test/DXC/Passes/ScalarReplHLSL/scalarrepl-param-hlsl-dyn-idx-gep-of-const-idx-gep.ll
new file mode 100644
index 0000000000000000000000000000000000000000..04fdea1500e75266a59705a1c2da98a4aef7391c
--- /dev/null
+++ b/tools/clang/test/DXC/Passes/ScalarReplHLSL/scalarrepl-param-hlsl-dyn-idx-gep-of-const-idx-gep.ll
@@ -0,0 +1,111 @@
+; RUN: %dxopt %s -hlsl-passes-resume -scalarrepl-param-hlsl -S | FileCheck %s
+
+; Produced from the following HLSL:
+; static int4 g[4] = (int4[4])0;
+; static int4 h[4] = (int4[4])0;
+;
+; [numthreads(1, 1, 1)]
+; void main() {
+; int a = 0;
+; int b = h[0][a];
+; h = g;
+; }
+;
+; This was crashing in scalarrepl-param-hlsl because it was attempting to flatten
+; global variable 'h' even though it is dynamically indexed. This was not detected
+; because the resulting IR was a dynamically indexed GEP of a constant-indexed GEP,
+; and the code was only checking the immediate users of 'h':
+;
+; %1 = getelementptr <4 x i32>, <4 x i32>* getelementptr inbounds ([4 x <4 x i32>], [4 x <4 x i32>]* @h, i32 0, i32 0), i32 0, i32 %0, !dbg !26 ; line:7 col:11
+;
+; Verify that it does not get flattened
+; CHECK: %1 = getelementptr <4 x i32>, <4 x i32>* getelementptr inbounds ([4 x <4 x i32>], [4 x <4 x i32>]* @g, i32 0, i32 0), i32 0, i32 %0
+
+;
+; Buffer Definitions:
+;
+; cbuffer $Globals
+; {
+;
+; [0 x i8] (type annotation not present)
+;
+; }
+;
+;
+; Resource Bindings:
+;
+; Name Type Format Dim ID HLSL Bind Count
+; ------------------------------ ---------- ------- ----------- ------- -------------- ------
+; $Globals cbuffer NA NA CB0 cb4294967295 1
+;
+target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
+target triple = "dxil-ms-dx"
+
+%ConstantBuffer = type opaque
+
+@h = internal global [4 x <4 x i32>] zeroinitializer, align 4
+@g = internal global [4 x <4 x i32>] zeroinitializer, align 4
+@"$Globals" = external constant %ConstantBuffer
+
+; Function Attrs: nounwind
+define void @main() #0 {
+entry:
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ store i32 0, i32* %a, align 4, !dbg !17, !tbaa !21 ; line:6 col:7
+ %0 = load i32, i32* %a, align 4, !dbg !25, !tbaa !21 ; line:7 col:16
+ %1 = getelementptr <4 x i32>, <4 x i32>* getelementptr inbounds ([4 x <4 x i32>], [4 x <4 x i32>]* @h, i32 0, i32 0), i32 0, i32 %0, !dbg !26 ; line:7 col:11
+ %2 = load i32, i32* %1, !dbg !26, !tbaa !21 ; line:7 col:11
+ store i32 %2, i32* %b, align 4, !dbg !27, !tbaa !21 ; line:7 col:7
+ %3 = bitcast [4 x <4 x i32>]* @h to i8*, !dbg !28 ; line:8 col:7
+ %4 = bitcast [4 x <4 x i32>]* @g to i8*, !dbg !28 ; line:8 col:7
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %4, i64 64, i32 1, i1 false), !dbg !28 ; line:8 col:7
+ ret void, !dbg !29 ; line:9 col:1
+}
+
+; Function Attrs: nounwind
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #0
+
+attributes #0 = { nounwind }
+
+!llvm.module.flags = !{!0}
+!pauseresume = !{!1}
+!llvm.ident = !{!2}
+!dx.version = !{!3}
+!dx.valver = !{!4}
+!dx.shaderModel = !{!5}
+!dx.typeAnnotations = !{!6}
+!dx.entryPoints = !{!10}
+!dx.fnprops = !{!14}
+!dx.options = !{!15, !16}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !{!"hlsl-hlemit", !"hlsl-hlensure"}
+!2 = !{!"dxc(private) 1.8.0.4514 (d9bd2a706-dirty)"}
+!3 = !{i32 1, i32 0}
+!4 = !{i32 1, i32 8}
+!5 = !{!"cs", i32 6, i32 0}
+!6 = !{i32 1, void ()* @main, !7}
+!7 = !{!8}
+!8 = !{i32 1, !9, !9}
+!9 = !{}
+!10 = !{void ()* @main, !"main", null, !11, null}
+!11 = !{null, null, !12, null}
+!12 = !{!13}
+!13 = !{i32 0, %ConstantBuffer* @"$Globals", !"$Globals", i32 0, i32 -1, i32 1, i32 0, null}
+!14 = !{void ()* @main, i32 5, i32 1, i32 1, i32 1}
+!15 = !{i32 64}
+!16 = !{i32 -1}
+!17 = !DILocation(line: 6, column: 7, scope: !18)
+!18 = !DISubprogram(name: "main", scope: !19, file: !19, line: 5, type: !20, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @main)
+!19 = !DIFile(filename: "/mnt/c/Users/amaiorano/Downloads/342428008/standalone_reduced.hlsl", directory: "")
+!20 = !DISubroutineType(types: !9)
+!21 = !{!22, !22, i64 0}
+!22 = !{!"int", !23, i64 0}
+!23 = !{!"omnipotent char", !24, i64 0}
+!24 = !{!"Simple C/C++ TBAA"}
+!25 = !DILocation(line: 7, column: 16, scope: !18)
+!26 = !DILocation(line: 7, column: 11, scope: !18)
+!27 = !DILocation(line: 7, column: 7, scope: !18)
+!28 = !DILocation(line: 8, column: 7, scope: !18)
+!29 = !DILocation(line: 9, column: 1, scope: !18)

View File

@@ -0,0 +1,312 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Natalie Chouinard <chouinard@google.com>
Date: Fri, 14 Jun 2024 13:29:19 +0000
Subject: Fix another UAF in SimplifyCFG (#6680)
In certain cases of unreachable code, SimplifyCFG could try to replace a
phi node with a select where the phi node itself was the select's
condition. This resulted in an ASAN use-after-free during SimplifyCFG.
The test case added isn't quite ideal because by the end of the
SimplifyCFG pass, the phi node is restored to its original state both
before and after this fix. However, an ASAN build of `dxopt` or
`check-clang-dxc` will identify a heap-use-after-free failure in the
intermediary steps of this test without this patch and succeeds with it.
This was also fixed in upstream LLVM:
https://github.com/llvm/llvm-project/commit/602ab248335e1540e82667e74fea44b7f042e112
Bug: 344639860
Change-Id: I743e96fb172de867c89cad51805edf96387c04ec
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5631796
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index 0d3ba1e00719060c1e71fa238726f0c63bd5b32f..5b364856928af6aab007e958b24f1daea32cd733 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1830,6 +1830,14 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
isa<ConstantInt>(IfCond))
return false;
+ // HLSL Change Begins: Patching in llvm/llvm-project@602ab24
+ // Don't try to fold an unreachable block. For example, the phi node itself
+ // can't be the candidate if-condition for a select that we want to form.
+ if (auto *IfCondPhiInst = dyn_cast<PHINode>(IfCond))
+ if (IfCondPhiInst->getParent() == BB)
+ return false;
+ // HLSL Change Ends.
+
// Okay, we found that we can merge this two-entry phi node into a select.
// Doing so would require us to fold *all* two entry phi nodes in this block.
// At some point this becomes non-profitable (particularly if the target
diff --git a/tools/clang/test/DXC/Passes/SimplifyCFG/simplifycfg-uaf-phi-condition.ll b/tools/clang/test/DXC/Passes/SimplifyCFG/simplifycfg-uaf-phi-condition.ll
new file mode 100644
index 0000000000000000000000000000000000000000..573745a819fd1b51e3163d644088738d5128d30c
--- /dev/null
+++ b/tools/clang/test/DXC/Passes/SimplifyCFG/simplifycfg-uaf-phi-condition.ll
@@ -0,0 +1,263 @@
+; RUN: %dxopt %s -hlsl-passes-resume -simplifycfg -S | FileCheck %s
+
+; The IR below comes from the following HLSL.
+; Compiling this HLSL with dxc was resulting in an ASAN use-after-free in
+; SimplifyCFG during FoldTwoEntryPHINode because it was deleting a PHI node
+; which was itself used as the condition for the select that replaced it.
+
+; struct a {
+; int b[2];
+; };
+;
+; cbuffer cbuffer_c : register(b0) {
+; uint4 c[1];
+; };
+;
+; void d(inout a e, inout int f) {
+; int n = f;
+; int g = asint(c[0].x);
+; int s = f;
+; bool i = (s >= 0);
+; int j = (s * n);
+; bool k = (6 > g);
+; int l = 0;
+; bool q = (s > j);
+; while (true) {
+; while (true) {
+; while (true) {
+; if (k) {
+; {
+; int t[2] = e.b;
+; t[g] = n;
+; e.b = t;
+; }
+; }
+; e.b[1] = g;
+; e.b[0] = s;
+; if (q) {
+; break;
+; }
+; }
+; switch(j) {
+; case 0: {
+; break;
+; }
+; case 9: {
+; break;
+; }
+; default: {
+; {
+; int u[2] = e.b;
+; u[g] = l;
+; e.b = u;
+; }
+; break;
+; }
+; }
+; {
+; if (q) { break; }
+; }
+; }
+; {
+; int v[2] = e.b;
+; v[g] = j;
+; e.b = v;
+; }
+; if (!(i)) {
+; break;
+; }
+; }
+; }
+;
+; [numthreads(1, 1, 1)]
+; void main() {
+; int o = 0;
+; a p = (a)0;
+; while (true) {
+; bool i = (o < asint(c[0].x));
+; if (i) {
+; bool r = !(i);
+; if (!(r)) {
+; return;
+; }
+; d(p, o);
+; }
+; o = (o + 1);
+; }
+; return;
+; }
+
+; Make sure the phi node did not get deleted by simplifycfg
+; CHECK: while.body:
+; CHECK-NEXT: %o.0 = phi i32 [ 0, %entry ], [ %add, %if.end.6 ]
+
+;
+; Buffer Definitions:
+;
+; cbuffer cbuffer_c
+; {
+;
+; struct cbuffer_c
+; {
+;
+; uint4 c[1]; ; Offset: 0
+;
+; } cbuffer_c; ; Offset: 0 Size: 16
+;
+; }
+;
+;
+; Resource Bindings:
+;
+; Name Type Format Dim ID HLSL Bind Count
+; ------------------------------ ---------- ------- ----------- ------- -------------- ------
+; cbuffer_c cbuffer NA NA CB0 cb0 1
+;
+target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
+target triple = "dxil-ms-dx"
+
+%cbuffer_c = type { [1 x <4 x i32>] }
+%dx.types.Handle = type { i8* }
+%dx.types.ResourceProperties = type { i32, i32 }
+%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
+%struct.a = type { [2 x i32] }
+
+@cbuffer_c = external constant %cbuffer_c
+@llvm.used = appending global [1 x i8*] [i8* bitcast (%cbuffer_c* @cbuffer_c to i8*)], section "llvm.metadata"
+
+; Function Attrs: nounwind
+define void @main() #0 {
+entry:
+ %0 = load %cbuffer_c, %cbuffer_c* @cbuffer_c, align 4
+ %cbuffer_c8 = call %dx.types.Handle @dx.op.createHandleForLib.cbuffer_c(i32 160, %cbuffer_c %0) ; CreateHandleForLib(Resource)
+ %1 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %cbuffer_c8, %dx.types.ResourceProperties { i32 13, i32 16 }) ; AnnotateHandle(res,props) resource: CBuffer
+ %cbuffer_c = call %dx.types.Handle @dx.op.createHandleForLib.cbuffer_c(i32 160, %cbuffer_c %0) ; CreateHandleForLib(Resource)
+ %2 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %cbuffer_c, %dx.types.ResourceProperties { i32 13, i32 16 }) ; AnnotateHandle(res,props) resource: CBuffer
+ br label %while.body, !dbg !21 ; line:69 col:3
+
+while.body: ; preds = %if.end.6, %entry
+ %o.0 = phi i32 [ 0, %entry ], [ %add, %if.end.6 ]
+ %3 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %1, i32 0), !dbg !25 ; line:70 col:25 ; CBufferLoadLegacy(handle,regIndex)
+ %4 = extractvalue %dx.types.CBufRet.i32 %3, 0, !dbg !25 ; line:70 col:25
+ %cmp = icmp slt i32 %o.0, %4, !dbg !26 ; line:70 col:17
+ br i1 %cmp, label %if.then, label %if.end.6, !dbg !27 ; line:71 col:9
+
+if.then: ; preds = %while.body
+ br i1 %cmp, label %if.then.5, label %if.end, !dbg !28 ; line:73 col:11
+
+if.then.5: ; preds = %if.then
+ ret void, !dbg !29 ; line:74 col:9
+
+if.end: ; preds = %if.then
+ %5 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %2, i32 0), !dbg !30 ; line:11 col:17 ; CBufferLoadLegacy(handle,regIndex)
+ %6 = extractvalue %dx.types.CBufRet.i32 %5, 0, !dbg !30 ; line:11 col:17
+ %cmp.i = icmp sgt i32 %o.0, -1, !dbg !33 ; line:13 col:15
+ %mul.i = mul nsw i32 %o.0, %o.0, !dbg !34 ; line:14 col:14
+ %cmp1.i = icmp slt i32 %6, 6, !dbg !35 ; line:15 col:15
+ %cmp4.i = icmp sgt i32 %o.0, %mul.i, !dbg !36 ; line:17 col:15
+ br label %while.body.10.i, !dbg !37 ; line:18 col:3
+
+while.body.10.i: ; preds = %while.end.27.i, %sw.epilog.i, %if.end.i, %if.end
+ br i1 %cmp1.i, label %if.then.i, label %if.end.i, !dbg !38 ; line:21 col:13
+
+if.then.i: ; preds = %while.body.10.i
+ br label %if.end.i, !dbg !39 ; line:27 col:9
+
+if.end.i: ; preds = %if.then.i, %while.body.10.i
+ br i1 %cmp4.i, label %while.end.i, label %while.body.10.i, !dbg !40 ; line:30 col:13
+
+while.end.i: ; preds = %if.end.i
+ switch i32 %mul.i, label %sw.default.i [
+ i32 0, label %sw.epilog.i
+ i32 9, label %sw.epilog.i
+ ], !dbg !41 ; line:34 col:7
+
+sw.default.i: ; preds = %while.end.i
+ br label %sw.epilog.i, !dbg !42 ; line:47 col:11
+
+sw.epilog.i: ; preds = %sw.default.i, %while.end.i, %while.end.i
+ br i1 %cmp4.i, label %while.end.27.i, label %while.body.10.i, !dbg !43 ; line:51 col:13
+
+while.end.27.i: ; preds = %sw.epilog.i
+ br i1 %cmp.i, label %while.body.10.i, label %if.end.6, !dbg !44 ; line:59 col:9
+
+if.end.6: ; preds = %while.end.27.i, %while.body
+ %add = add nsw i32 %o.0, 1, !dbg !45 ; line:78 col:12
+ br label %while.body, !dbg !21 ; line:69 col:3
+}
+
+; Function Attrs: nounwind readnone
+declare %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %cbuffer_c*, i32)"(i32, %cbuffer_c*, i32) #1
+
+; Function Attrs: nounwind readnone
+declare %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %cbuffer_c)"(i32, %dx.types.Handle, %dx.types.ResourceProperties, %cbuffer_c) #1
+
+; Function Attrs: nounwind readonly
+declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #2
+
+; Function Attrs: nounwind readonly
+declare %dx.types.Handle @dx.op.createHandleForLib.cbuffer_c(i32, %cbuffer_c) #2
+
+; Function Attrs: nounwind readnone
+declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
+attributes #2 = { nounwind readonly }
+
+!llvm.module.flags = !{!0}
+!pauseresume = !{!1}
+!llvm.ident = !{!2}
+!dx.version = !{!3}
+!dx.valver = !{!4}
+!dx.shaderModel = !{!5}
+!dx.resources = !{!6}
+!dx.typeAnnotations = !{!9, !14}
+!dx.entryPoints = !{!18}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !{!"hlsl-dxilemit", !"hlsl-dxilload"}
+!2 = !{!"dxc(private) 1.8.0.14620 (main, 8408ae882)"}
+!3 = !{i32 1, i32 2}
+!4 = !{i32 1, i32 8}
+!5 = !{!"cs", i32 6, i32 2}
+!6 = !{null, null, !7, null}
+!7 = !{!8}
+!8 = !{i32 0, %cbuffer_c* @cbuffer_c, !"cbuffer_c", i32 0, i32 0, i32 1, i32 16, null}
+!9 = !{i32 0, %struct.a undef, !10, %cbuffer_c undef, !12}
+!10 = !{i32 20, !11}
+!11 = !{i32 6, !"b", i32 3, i32 0, i32 7, i32 4}
+!12 = !{i32 16, !13}
+!13 = !{i32 6, !"c", i32 3, i32 0, i32 7, i32 5}
+!14 = !{i32 1, void ()* @main, !15}
+!15 = !{!16}
+!16 = !{i32 1, !17, !17}
+!17 = !{}
+!18 = !{void ()* @main, !"main", null, !6, !19}
+!19 = !{i32 4, !20}
+!20 = !{i32 1, i32 1, i32 1}
+!21 = !DILocation(line: 69, column: 3, scope: !22)
+!22 = !DISubprogram(name: "main", scope: !23, file: !23, line: 66, type: !24, isLocal: false, isDefinition: true, scopeLine: 66, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @main)
+!23 = !DIFile(filename: "/usr/local/google/home/chouinard/Downloads/standalone.hlsl", directory: "")
+!24 = !DISubroutineType(types: !17)
+!25 = !DILocation(line: 70, column: 25, scope: !22)
+!26 = !DILocation(line: 70, column: 17, scope: !22)
+!27 = !DILocation(line: 71, column: 9, scope: !22)
+!28 = !DILocation(line: 73, column: 11, scope: !22)
+!29 = !DILocation(line: 74, column: 9, scope: !22)
+!30 = !DILocation(line: 11, column: 17, scope: !31, inlinedAt: !32)
+!31 = !DISubprogram(name: "d", scope: !23, file: !23, line: 9, type: !24, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: false)
+!32 = distinct !DILocation(line: 76, column: 7, scope: !22)
+!33 = !DILocation(line: 13, column: 15, scope: !31, inlinedAt: !32)
+!34 = !DILocation(line: 14, column: 14, scope: !31, inlinedAt: !32)
+!35 = !DILocation(line: 15, column: 15, scope: !31, inlinedAt: !32)
+!36 = !DILocation(line: 17, column: 15, scope: !31, inlinedAt: !32)
+!37 = !DILocation(line: 18, column: 3, scope: !31, inlinedAt: !32)
+!38 = !DILocation(line: 21, column: 13, scope: !31, inlinedAt: !32)
+!39 = !DILocation(line: 27, column: 9, scope: !31, inlinedAt: !32)
+!40 = !DILocation(line: 30, column: 13, scope: !31, inlinedAt: !32)
+!41 = !DILocation(line: 34, column: 7, scope: !31, inlinedAt: !32)
+!42 = !DILocation(line: 47, column: 11, scope: !31, inlinedAt: !32)
+!43 = !DILocation(line: 51, column: 13, scope: !31, inlinedAt: !32)
+!44 = !DILocation(line: 59, column: 9, scope: !31, inlinedAt: !32)
+!45 = !DILocation(line: 78, column: 12, scope: !22)

View File

@@ -0,0 +1,261 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: David Neto <dneto@google.com>
Date: Tue, 16 Jul 2024 16:34:52 -0400
Subject: Add CMake option DXC_CODEGEN_EXCEPTIONS_TRAP (#6764)
When enabled, any hlsl::Exception thrown during code generation and
optimization will cause the process to trap.
Bug: 346618785
Change-Id: I9ac966d339ec3090e3455d51a9d7516cc5a3f153
HLMatrixLower: allow exceptions to propagate out (#6710)
If an exception is thrown, don't block it in the TempOverloadPool
destructor. Allow it to propagate out as a user-visible error.
Explicitly clear the TempOverloadPool before returning from the
HLMatrixLowerPass::runOnModule. In the normal case, when no exception is
thrown, that will still verify that all the overloads actually have been
lowered, and will assert out if they aren't.
Bug: 346618785
Change-Id: Id421ca324e4d799477a41abb14b966e8f39be482
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5715228
Reviewed-by: Natalie Chouinard <chouinard@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 15097b8473bf9f6c2b6c28ac095936616aa917f6..ac35ebd1a6afd55934da502ddb0e0c286da10db8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -104,6 +104,9 @@ endif()
option(DXC_DISABLE_ALLOCATOR_OVERRIDES "Disable usage of allocator overrides" OFF)
mark_as_advanced(DXC_DISABLE_ALLOCATOR_OVERRIDES)
+option(DXC_CODEGEN_EXCEPTIONS_TRAP "An exception in code generation generates a trap, ending the compiler process" OFF)
+mark_as_advanced(DXC_CODEGEN_EXCEPTIONS_TRAP)
+
# adjust link option to enable debugging from kernel mode; not compatible with incremental linking
if(NOT CMAKE_VERSION VERSION_LESS "3.13" AND WIN32 AND NOT CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64EC")
add_link_options(/DEBUGTYPE:CV,FIXUP,PDATA /INCREMENTAL:NO)
diff --git a/include/dxc/config.h.cmake b/include/dxc/config.h.cmake
index 6d7450323ec864ef5f6e8796c46423d49f278b76..7226ed75a108f63c3c894b59eb7e0dbc5fb66002 100644
--- a/include/dxc/config.h.cmake
+++ b/include/dxc/config.h.cmake
@@ -1,2 +1,4 @@
/* Disable overriding memory allocators. */
#cmakedefine DXC_DISABLE_ALLOCATOR_OVERRIDES
+/* Generate a trap if an hlsl::Exception is thrown during code generation */
+#cmakedefine DXC_CODEGEN_EXCEPTIONS_TRAP
diff --git a/lib/HLSL/HLMatrixLowerPass.cpp b/lib/HLSL/HLMatrixLowerPass.cpp
index d5959eb9335465f67d8e7ef7d7ab4eb720274226..3bb9f65834ecfd0c7a25c8a176f62c124e9967e5 100644
--- a/lib/HLSL/HLMatrixLowerPass.cpp
+++ b/lib/HLSL/HLMatrixLowerPass.cpp
@@ -60,7 +60,12 @@ class TempOverloadPool {
public:
TempOverloadPool(llvm::Module &Module, const char *BaseName)
: Module(Module), BaseName(BaseName) {}
- ~TempOverloadPool() { clear(); }
+ ~TempOverloadPool() {
+ if (!Funcs.empty()) {
+ // The flow has thrown an exception. Let that exception
+ // propagate out and be reported as a compile error.
+ }
+ }
Function *get(FunctionType *Ty);
bool contains(FunctionType *Ty) const { return Funcs.count(Ty) != 0; }
@@ -248,12 +253,15 @@ bool HLMatrixLowerPass::runOnModule(Module &M) {
m_matToVecStubs = nullptr;
m_vecToMatStubs = nullptr;
- // If you hit an assert during TempOverloadPool destruction,
+ // If you hit an assert while clearing TempOverloadPool,
// it means that either a matrix producer was lowered,
// causing a translation stub to be created,
// but the consumer of that matrix was never (properly) lowered.
// Or the opposite: a matrix consumer was lowered and not its producer.
+ matToVecStubs.clear();
+ vecToMatStubs.clear();
+
return true;
}
diff --git a/tools/clang/lib/CodeGen/BackendUtil.cpp b/tools/clang/lib/CodeGen/BackendUtil.cpp
index 294ca05946eed6d87a3ad4e2b56a641d24065760..1e9adb40f4bae4cada42b5581582d50dc3676594 100644
--- a/tools/clang/lib/CodeGen/BackendUtil.cpp
+++ b/tools/clang/lib/CodeGen/BackendUtil.cpp
@@ -8,6 +8,10 @@
//===----------------------------------------------------------------------===//
#include "clang/CodeGen/BackendUtil.h"
+#include "dxc/HLSL/DxilGenerationPass.h" // HLSL Change
+#include "dxc/HLSL/HLMatrixLowerPass.h" // HLSL Change
+#include "dxc/Support/Global.h" // HLSL Change
+#include "dxc/config.h" // HLSL Change
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetOptions.h"
@@ -41,10 +45,8 @@
#include "llvm/Transforms/ObjCARC.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/SymbolRewriter.h"
+#include <cstdio>
#include <memory>
-#include "dxc/HLSL/DxilGenerationPass.h" // HLSL Change
-#include "dxc/HLSL/HLMatrixLowerPass.h" // HLSL Change
-#include "dxc/Support/Global.h" // HLSL Change
using namespace clang;
using namespace llvm;
@@ -780,6 +782,13 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
} catch (const ::hlsl::Exception &hlslException) {
Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0\n"))
<< StringRef(hlslException.what());
+#if defined(DXC_CODEGEN_EXCEPTIONS_TRAP)
+ // llvm::errs() doesn't work in release builds on Linux.
+ // Use C-style fprintf because it works everywhere.
+ fprintf(stderr, "internal codegen error: %s\n", hlslException.what());
+ fflush(stderr);
+ LLVM_BUILTIN_TRAP;
+#endif
} // HLSL Change Ends
// If an optional clang TargetInfo description string was passed in, use it to
diff --git a/tools/clang/test/DXC/Passes/HLMatrixLower/dont_crash_on_invalid_cast.ll b/tools/clang/test/DXC/Passes/HLMatrixLower/dont_crash_on_invalid_cast.ll
new file mode 100644
index 0000000000000000000000000000000000000000..fca52d11595d3ac99dedb28219f0746a26add6c9
--- /dev/null
+++ b/tools/clang/test/DXC/Passes/HLMatrixLower/dont_crash_on_invalid_cast.ll
@@ -0,0 +1,130 @@
+; RUN: not %dxopt %s -hlsl-passes-resume -hlmatrixlower -S | FileCheck %s
+
+
+; The HL matrix lowering pass can sometimes throw an exception
+; due to an invalid LLVM-level cast<Ty> call. Make sure that
+; propagates out to a user-level error.
+
+; Note: There is still a bug in the compiler here. Not all matrix
+; lowerings are covered by the pass.
+
+; TODO: Fix the underlying bug https://github.com/microsoft/DirectXShaderCompiler/issues/6723
+; Once that is fixed, this test changes or should be deleted.
+
+
+; CHECK: Operation failed - error code
+
+;
+; Buffer Definitions:
+;
+; cbuffer $Globals
+; {
+;
+; [0 x i8] (type annotation not present)
+;
+; }
+;
+;
+; Resource Bindings:
+;
+; Name Type Format Dim ID HLSL Bind Count
+; ------------------------------ ---------- ------- ----------- ------- -------------- ------
+; $Globals cbuffer NA NA CB0 cb4294967295 1
+;
+target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
+target triple = "dxil-ms-dx"
+
+%ConstantBuffer = type opaque
+%class.matrix.float.2.4 = type { [2 x <4 x float>] }
+%struct.e = type { [1 x %struct.d], [1 x %struct.d] }
+%struct.d = type { %struct.a }
+%struct.a = type { float, %class.matrix.float.2.4 }
+
+@"$Globals" = external constant %ConstantBuffer
+@g.0.0.0 = internal global [1 x float] undef, align 4
+@g.0.0.1 = internal global [1 x %class.matrix.float.2.4] undef, align 4
+@g.1.0.0 = internal global [1 x float] undef, align 4
+@g.1.0.1 = internal global [1 x %class.matrix.float.2.4] undef, align 4
+
+; Function Attrs: nounwind
+define void @main() #0 {
+entry:
+ %h.0.1 = alloca %class.matrix.float.2.4, !dbg !26 ; line:13 col:17
+ store float 0.000000e+00, float* getelementptr inbounds ([1 x float], [1 x float]* @g.0.0.0, i32 0, i32 0), !dbg !26 ; line:13 col:17
+ %0 = call %class.matrix.float.2.4 @"dx.hl.init.rn.%class.matrix.float.2.4 (i32, <8 x float>)"(i32 0, <8 x float> zeroinitializer) #0, !dbg !26 ; line:13 col:17
+ %1 = call %class.matrix.float.2.4 @"dx.hl.cast.rowMatToColMat.%class.matrix.float.2.4 (i32, %class.matrix.float.2.4)"(i32 7, %class.matrix.float.2.4 %0) #0, !dbg !26 ; line:13 col:17
+ %2 = call %class.matrix.float.2.4 @"dx.hl.matldst.colStore.%class.matrix.float.2.4 (i32, %class.matrix.float.2.4*, %class.matrix.float.2.4)"(i32 1, %class.matrix.float.2.4* getelementptr inbounds ([1 x %class.matrix.float.2.4], [1 x %class.matrix.float.2.4]* @g.0.0.1, i32 0, i32 0), %class.matrix.float.2.4 %1) #0, !dbg !26 ; line:13 col:17
+ store float 0.000000e+00, float* getelementptr inbounds ([1 x float], [1 x float]* @g.1.0.0, i32 0, i32 0), !dbg !26 ; line:13 col:17
+ %3 = call %class.matrix.float.2.4 @"dx.hl.init.rn.%class.matrix.float.2.4 (i32, <8 x float>)"(i32 0, <8 x float> zeroinitializer) #0, !dbg !26 ; line:13 col:17
+ %4 = call %class.matrix.float.2.4 @"dx.hl.cast.rowMatToColMat.%class.matrix.float.2.4 (i32, %class.matrix.float.2.4)"(i32 7, %class.matrix.float.2.4 %3) #0, !dbg !26 ; line:13 col:17
+ %5 = call %class.matrix.float.2.4 @"dx.hl.matldst.colStore.%class.matrix.float.2.4 (i32, %class.matrix.float.2.4*, %class.matrix.float.2.4)"(i32 1, %class.matrix.float.2.4* getelementptr inbounds ([1 x %class.matrix.float.2.4], [1 x %class.matrix.float.2.4]* @g.1.0.1, i32 0, i32 0), %class.matrix.float.2.4 %4) #0, !dbg !26 ; line:13 col:17
+ %6 = load float, float* getelementptr inbounds ([1 x float], [1 x float]* @g.1.0.0, i32 0, i32 0), !dbg !32 ; line:17 col:9
+ %7 = getelementptr inbounds %class.matrix.float.2.4, %class.matrix.float.2.4* %h.0.1, i32 0, i32 0, i32 0, !dbg !32 ; line:17 col:9
+ %8 = load <4 x float>, <4 x float>* getelementptr inbounds ([1 x %class.matrix.float.2.4], [1 x %class.matrix.float.2.4]* @g.1.0.1, i32 0, i32 0, i32 0, i32 0), !dbg !32 ; line:17 col:9
+ store <4 x float> %8, <4 x float>* %7, !dbg !32 ; line:17 col:9
+ %9 = getelementptr inbounds %class.matrix.float.2.4, %class.matrix.float.2.4* %h.0.1, i32 0, i32 0, i32 1, !dbg !32 ; line:17 col:9
+ %10 = load <4 x float>, <4 x float>* getelementptr inbounds ([1 x %class.matrix.float.2.4], [1 x %class.matrix.float.2.4]* @g.1.0.1, i32 0, i32 0, i32 0, i32 1), !dbg !32 ; line:17 col:9
+ store <4 x float> %10, <4 x float>* %9, !dbg !32 ; line:17 col:9
+ ret void, !dbg !33 ; line:18 col:3
+}
+
+; Function Attrs: nounwind
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #0
+
+; Function Attrs: nounwind readnone
+declare %class.matrix.float.2.4 @"dx.hl.init.rn.%class.matrix.float.2.4 (i32, <8 x float>)"(i32, <8 x float>) #1
+
+; Function Attrs: nounwind readnone
+declare %class.matrix.float.2.4 @"dx.hl.cast.rowMatToColMat.%class.matrix.float.2.4 (i32, %class.matrix.float.2.4)"(i32, %class.matrix.float.2.4) #1
+
+; Function Attrs: nounwind
+declare %class.matrix.float.2.4 @"dx.hl.matldst.colStore.%class.matrix.float.2.4 (i32, %class.matrix.float.2.4*, %class.matrix.float.2.4)"(i32, %class.matrix.float.2.4*, %class.matrix.float.2.4) #0
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
+
+!llvm.module.flags = !{!0}
+!pauseresume = !{!1}
+!llvm.ident = !{!2}
+!dx.version = !{!3}
+!dx.valver = !{!4}
+!dx.shaderModel = !{!5}
+!dx.typeAnnotations = !{!6, !15}
+!dx.entryPoints = !{!19}
+!dx.fnprops = !{!23}
+!dx.options = !{!24, !25}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !{!"hlsl-hlemit", !"hlsl-hlensure"}
+!2 = !{!"dxc(private) 1.8.0.4640 (issue-785, 45018c752d)"}
+!3 = !{i32 1, i32 0}
+!4 = !{i32 1, i32 8}
+!5 = !{!"cs", i32 6, i32 0}
+!6 = !{i32 0, %struct.e undef, !7, %struct.d undef, !10, %struct.a undef, !11}
+!7 = !{i32 152, !8, !9}
+!8 = !{i32 6, !"c", i32 3, i32 0}
+!9 = !{i32 6, !"f", i32 3, i32 80}
+!10 = !{i32 72, !8}
+!11 = !{i32 72, !12, !13}
+!12 = !{i32 6, !"b", i32 3, i32 0, i32 7, i32 9}
+!13 = !{i32 6, !"c", i32 2, !14, i32 3, i32 16, i32 7, i32 9}
+!14 = !{i32 2, i32 4, i32 2}
+!15 = !{i32 1, void ()* @main, !16}
+!16 = !{!17}
+!17 = !{i32 1, !18, !18}
+!18 = !{}
+!19 = !{void ()* @main, !"main", null, !20, null}
+!20 = !{null, null, !21, null}
+!21 = !{!22}
+!22 = !{i32 0, %ConstantBuffer* @"$Globals", !"$Globals", i32 0, i32 -1, i32 1, i32 0, null}
+!23 = !{void ()* @main, i32 5, i32 1, i32 1, i32 1}
+!24 = !{i32 64}
+!25 = !{i32 -1}
+!26 = !DILocation(line: 13, column: 17, scope: !27, inlinedAt: !30)
+!27 = !DISubprogram(name: "??__Eg@@YAXXZ", scope: !28, file: !28, line: 13, type: !29, isLocal: true, isDefinition: true, scopeLine: 13, flags: DIFlagPrototyped, isOptimized: false)
+!28 = !DIFile(filename: "a.hlsl", directory: "")
+!29 = !DISubroutineType(types: !18)
+!30 = distinct !DILocation(line: 16, scope: !31)
+!31 = !DISubprogram(name: "main", scope: !28, file: !28, line: 16, type: !29, isLocal: false, isDefinition: true, scopeLine: 16, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @main)
+!32 = !DILocation(line: 17, column: 9, scope: !31)
+!33 = !DILocation(line: 18, column: 3, scope: !31)

View File

@@ -0,0 +1,231 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Antonio Maiorano <amaiorano@google.com>
Date: Thu, 20 Jun 2024 15:39:00 -0400
Subject: Fix instcombine overflow check inserting inst at wrong place (#6679)
When optimizing an overflow check of an add followed by a compare, the
new instruction was being inserted at the compare, and the add removed.
This produced invalid IR in cases where there were other uses of the
former add between it and the compare. This fix makes sure to insert the
new instruction at the old add location, rather than at the compare.
Note that this was also fixed in LLVM:
https://github.com/llvm/llvm-project/commit/6f5dca70ed1c030957a45ad91bd295921f17b18d
Bug: chromium:342545100
Change-Id: Iecf758e4465b32371266bbe9879790328f363322
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5644335
Reviewed-by: dan sinclair <dsinclair@google.com>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 7274304b3de7b110a4fa3a5123ea7215d99935ef..82e7e49003e65846c84e3df2801453fb463aa23e 100644
--- a/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2145,6 +2145,12 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS,
return true;
};
+ // If the overflow check was an add followed by a compare, the insertion point
+ // may be pointing to the compare. We want to insert the new instructions
+ // before the add in case there are uses of the add between the add and the
+ // compare.
+ Builder->SetInsertPoint(&OrigI);
+
switch (OCF) {
case OCF_INVALID:
llvm_unreachable("bad overflow check kind!");
diff --git a/tools/clang/test/DXC/Passes/InstructionCombining/instcombine-opt-overflow-check-inserts-at-add.ll b/tools/clang/test/DXC/Passes/InstructionCombining/instcombine-opt-overflow-check-inserts-at-add.ll
new file mode 100644
index 0000000000000000000000000000000000000000..70efa00c91c6523867980de0fb9f69c7fcfb318c
--- /dev/null
+++ b/tools/clang/test/DXC/Passes/InstructionCombining/instcombine-opt-overflow-check-inserts-at-add.ll
@@ -0,0 +1,187 @@
+; RUN: %dxopt %s -hlsl-passes-resume -instcombine,NoSink=0 -S | FileCheck %s
+
+; Generated from the following HLSL:
+; cbuffer cbuffer_g : register(b0) {
+; uint4 g[1];
+; };
+;
+; [numthreads(1, 1, 1)]
+; void main() {
+; uint a = 2147483648u;
+; uint b = (g[0].x | 2651317025u);
+; uint c = (b + 2651317025u);
+; while (true) {
+; bool d = (a > c);
+; if (d) {
+; break;
+; } else {
+; while (true) {
+; if (!d) {
+; return;
+; }
+; a = b;
+; bool e = (d ? d : d);
+; if (e) {
+; break;
+; }
+; }
+; }
+; }
+; }
+;
+; Compiling this was resulting in invalid IR being produced from instcombine.
+; Specifically, when optimizing an overflow check of an add followed by a compare,
+; the new instruction was being inserted at the compare, and the add removed. This
+; broke in cases like this one, where there were other uses of the former add between
+; it and the compare. The fix was to make sure to insert the new instruction
+; (another add in this case) at the old add rather than at the compare.
+
+; Make sure the new %add is still in the entry block before its uses.
+; CHECK-LABEL: entry
+; CHECK: %add = add i32 %or, -1643650271
+; CHECK-NEXT: %cmp.2 = icmp sgt i32 %add, -1,
+;
+; Make sure the new %add is NOT in the loopexit where %cmp was optimized.
+; CHECK-LABEL: while.body.loopexit
+; CHECK-NEXT: br i1 false, label %if.end.preheader, label %while.end.14
+
+;
+; Buffer Definitions:
+;
+; cbuffer cbuffer_g
+; {
+;
+; struct cbuffer_g
+; {
+;
+; uint4 g[1]; ; Offset: 0
+;
+; } cbuffer_g; ; Offset: 0 Size: 16
+;
+; }
+;
+;
+; Resource Bindings:
+;
+; Name Type Format Dim ID HLSL Bind Count
+; ------------------------------ ---------- ------- ----------- ------- -------------- ------
+; cbuffer_g cbuffer NA NA CB0 cb0 1
+;
+target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
+target triple = "dxil-ms-dx"
+
+%cbuffer_g = type { [1 x <4 x i32>] }
+%dx.types.Handle = type { i8* }
+%dx.types.ResourceProperties = type { i32, i32 }
+%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
+
+@cbuffer_g = external constant %cbuffer_g
+@llvm.used = appending global [1 x i8*] [i8* bitcast (%cbuffer_g* @cbuffer_g to i8*)], section "llvm.metadata"
+
+; Function Attrs: nounwind
+define void @main() #0 {
+entry:
+ %0 = load %cbuffer_g, %cbuffer_g* @cbuffer_g
+ %cbuffer_g = call %dx.types.Handle @dx.op.createHandleForLib.cbuffer_g(i32 160, %cbuffer_g %0) ; CreateHandleForLib(Resource)
+ %1 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %cbuffer_g, %dx.types.ResourceProperties { i32 13, i32 16 }) ; AnnotateHandle(res,props) resource: CBuffer
+ %2 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %1, i32 0), !dbg !19 ; line:8 col:13 ; CBufferLoadLegacy(handle,regIndex)
+ %3 = extractvalue %dx.types.CBufRet.i32 %2, 0, !dbg !19 ; line:8 col:13
+ %or = or i32 %3, -1643650271, !dbg !23 ; line:8 col:20
+ %add = add i32 %or, -1643650271, !dbg !24 ; line:9 col:15
+ %cmp.2 = icmp ugt i32 -2147483648, %add, !dbg !25 ; line:11 col:17
+ %frombool.3 = zext i1 %cmp.2 to i32, !dbg !26 ; line:11 col:10
+ %tobool1.4 = icmp eq i32 %frombool.3, 0, !dbg !27 ; line:12 col:9
+ %or.cond.6 = and i1 %tobool1.4, %cmp.2, !dbg !27 ; line:12 col:9
+ br i1 %or.cond.6, label %if.end.preheader, label %while.end.14, !dbg !27 ; line:12 col:9
+
+while.body.loopexit: ; preds = %if.end
+ %cmp = icmp ugt i32 %or, %add, !dbg !25 ; line:11 col:17
+ %frombool = zext i1 %cmp to i32, !dbg !26 ; line:11 col:10
+ %tobool1 = icmp eq i32 %frombool, 0, !dbg !27 ; line:12 col:9
+ %or.cond = and i1 %tobool1, %cmp, !dbg !27 ; line:12 col:9
+ br i1 %or.cond, label %if.end.preheader, label %while.end.14, !dbg !27 ; line:12 col:9
+
+if.end.preheader: ; preds = %entry, %while.body.loopexit
+ %d.0 = phi i32 [ %frombool, %while.body.loopexit ], [ %frombool.3, %entry ]
+ br label %if.end, !dbg !28 ; line:19 col:13
+
+while.body.3: ; preds = %if.end
+ %tobool4.old = icmp ne i32 %d.0, 0, !dbg !29 ; line:16 col:14
+ br i1 %tobool4.old, label %if.end, label %while.end.14, !dbg !30 ; line:16 col:13
+
+if.end: ; preds = %if.end.preheader, %while.body.3
+ %tobool6 = icmp ne i32 %d.0, 0, !dbg !31 ; line:20 col:19
+ %tobool7 = icmp ne i32 %d.0, 0, !dbg !32 ; line:20 col:23
+ %tobool8 = icmp ne i32 %d.0, 0, !dbg !33 ; line:20 col:27
+ %4 = select i1 %tobool6, i1 %tobool7, i1 %tobool8, !dbg !31 ; line:20 col:19
+ br i1 %4, label %while.body.loopexit, label %while.body.3, !dbg !34 ; line:21 col:13
+
+while.end.14: ; preds = %while.body.loopexit, %while.body.3, %entry
+ ret void, !dbg !35 ; line:27 col:1
+}
+
+; Function Attrs: nounwind readnone
+declare %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %cbuffer_g*, i32)"(i32, %cbuffer_g*, i32) #1
+
+; Function Attrs: nounwind readnone
+declare %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %cbuffer_g)"(i32, %dx.types.Handle, %dx.types.ResourceProperties, %cbuffer_g) #1
+
+; Function Attrs: nounwind readonly
+declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #2
+
+; Function Attrs: nounwind readonly
+declare %dx.types.Handle @dx.op.createHandleForLib.cbuffer_g(i32, %cbuffer_g) #2
+
+; Function Attrs: nounwind readnone
+declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
+attributes #2 = { nounwind readonly }
+
+!llvm.module.flags = !{!0}
+!pauseresume = !{!1}
+!llvm.ident = !{!2}
+!dx.version = !{!3}
+!dx.valver = !{!4}
+!dx.shaderModel = !{!5}
+!dx.resources = !{!6}
+!dx.typeAnnotations = !{!9, !12}
+!dx.entryPoints = !{!16}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !{!"hlsl-dxilemit", !"hlsl-dxilload"}
+!2 = !{!"dxc(private) 1.8.0.4514 (d9bd2a706-dirty)"}
+!3 = !{i32 1, i32 0}
+!4 = !{i32 1, i32 8}
+!5 = !{!"cs", i32 6, i32 0}
+!6 = !{null, null, !7, null}
+!7 = !{!8}
+!8 = !{i32 0, %cbuffer_g* @cbuffer_g, !"cbuffer_g", i32 0, i32 0, i32 1, i32 16, null}
+!9 = !{i32 0, %cbuffer_g undef, !10}
+!10 = !{i32 16, !11}
+!11 = !{i32 6, !"g", i32 3, i32 0, i32 7, i32 5}
+!12 = !{i32 1, void ()* @main, !13}
+!13 = !{!14}
+!14 = !{i32 1, !15, !15}
+!15 = !{}
+!16 = !{void ()* @main, !"main", null, !6, !17}
+!17 = !{i32 4, !18}
+!18 = !{i32 1, i32 1, i32 1}
+!19 = !DILocation(line: 8, column: 13, scope: !20)
+!20 = !DISubprogram(name: "main", scope: !21, file: !21, line: 6, type: !22, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: false, function: void ()* @main)
+!21 = !DIFile(filename: "/mnt/c/Users/amaiorano/Downloads/342545100/standalone_reduced.hlsl", directory: "")
+!22 = !DISubroutineType(types: !15)
+!23 = !DILocation(line: 8, column: 20, scope: !20)
+!24 = !DILocation(line: 9, column: 15, scope: !20)
+!25 = !DILocation(line: 11, column: 17, scope: !20)
+!26 = !DILocation(line: 11, column: 10, scope: !20)
+!27 = !DILocation(line: 12, column: 9, scope: !20)
+!28 = !DILocation(line: 19, column: 13, scope: !20)
+!29 = !DILocation(line: 16, column: 14, scope: !20)
+!30 = !DILocation(line: 16, column: 13, scope: !20)
+!31 = !DILocation(line: 20, column: 19, scope: !20)
+!32 = !DILocation(line: 20, column: 23, scope: !20)
+!33 = !DILocation(line: 20, column: 27, scope: !20)
+!34 = !DILocation(line: 21, column: 13, scope: !20)
+!35 = !DILocation(line: 27, column: 1, scope: !20)

View File

@@ -0,0 +1,294 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Natalie Chouinard <chouinard@google.com>
Date: Mon, 10 Jun 2024 18:21:40 +0000
Subject: Fix LoopDeletion incorrectly updating PHI with multiple duplicate
inputs (#6643)
LoopDeletion was incorrectly updating PHI nodes in the target block when
it had duplicate input edges. This happens, for example, when deleting a
loop that uses a switch with multiple cases that exit the same way.
After determining that this was the bug, I found this fix in LLVM:
https://reviews.llvm.org/D34516 and applied it here.
Bug: 340196361
Change-Id: I98b150bb9a164466eb84dd3d46f720d5d92ef909
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5616791
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/lib/Transforms/Scalar/LoopDeletion.cpp b/lib/Transforms/Scalar/LoopDeletion.cpp
index 6c2c1d60548f5a8a7939fee70728e8a34572b648..6cd1fba7c085b6d61dcb23b073358fc4c798e099 100644
--- a/lib/Transforms/Scalar/LoopDeletion.cpp
+++ b/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -195,15 +195,29 @@ bool LoopDeletion::runOnLoop(Loop *L, LPPassManager &LPM) {
// Rewrite phis in the exit block to get their inputs from
// the preheader instead of the exiting block.
- BasicBlock *exitingBlock = exitingBlocks[0];
BasicBlock::iterator BI = exitBlock->begin();
while (PHINode *P = dyn_cast<PHINode>(BI)) {
- int j = P->getBasicBlockIndex(exitingBlock);
- assert(j >= 0 && "Can't find exiting block in exit block's phi node!");
- P->setIncomingBlock(j, preheader);
- for (unsigned i = 1; i < exitingBlocks.size(); ++i)
- P->removeIncomingValue(exitingBlocks[i]);
+ // HLSL Change begin - apply https://reviews.llvm.org/D34516
+ // Set the zero'th element of Phi to be from the preheader and remove all
+ // other incoming values. Given the loop has dedicated exits, all other
+ // incoming values must be from the exiting blocks.
+ int PredIndex = 0;
+ P->setIncomingBlock(PredIndex, preheader);
+ // Removes all incoming values from all other exiting blocks (including
+ // duplicate values from an exiting block).
+ // Nuke all entries except the zero'th entry which is the preheader entry.
+ // NOTE! We need to remove Incoming Values in the reverse order as done
+ // below, to keep the indices valid for deletion (removeIncomingValues
+ // updates getNumIncomingValues and shifts all values down into the operand
+ // being deleted).
+ for (unsigned i = 0, e = P->getNumIncomingValues() - 1; i != e; ++i)
+ P->removeIncomingValue(e - i, false);
+
+ assert((P->getNumIncomingValues() == 1 &&
+ P->getIncomingBlock(PredIndex) == preheader) &&
+ "Should have exactly one value and that's from the preheader!");
++BI;
+ // HLSL Change end
}
// Update the dominator tree and remove the instructions and blocks that will
diff --git a/tools/clang/test/DXC/Passes/DxilLoopDeletion/dxil-loop-deletion-phi-with-duplicate-preds.ll b/tools/clang/test/DXC/Passes/DxilLoopDeletion/dxil-loop-deletion-phi-with-duplicate-preds.ll
new file mode 100644
index 0000000000000000000000000000000000000000..62736bf2934a5db67ee75386431498f49e101f49
--- /dev/null
+++ b/tools/clang/test/DXC/Passes/DxilLoopDeletion/dxil-loop-deletion-phi-with-duplicate-preds.ll
@@ -0,0 +1,229 @@
+; RUN: %dxopt %s -hlsl-passes-resume -dxil-loop-deletion,NoSink=0 -S | FileCheck %s
+
+; This test was generated from the following HLSL:
+;
+; cbuffer cbuffer_g : register(b0) {
+; uint4 gu4[1];
+; };
+;
+; float4 f() {
+; float4 r = float4(0.0f, 0.0f, 0.0f, 0.0f);
+; int i = 0;
+; int j = 0;
+; while (true) {
+; float a = asfloat(gu4[0].y);
+; int ai = int(a);
+; bool b = (j < ai);
+; if (j >= ai) {
+; break;
+; }
+; bool c = (i > 0);
+; if (c) {
+; break;
+; } else {
+; bool3 b3 = bool3(b.xxx);
+; if (b3[i]) {
+; switch(i) {
+; case 0: return r;
+; case -1: return r;
+; }
+; if (c) {
+; break;
+; }
+; } else {
+; r = float4(0.0f, 0.0f, 0.0f, a);
+; }
+; }
+; i = j;
+; j = (j + 1);
+; }
+; r = (0.0f).xxxx;
+; return r;
+; }
+;
+; struct return_val {
+; float4 value : SV_Target0;
+; };
+;
+; return_val main() {
+; float4 inner_result = f();
+; return_val wrapper_result = (return_val)0;
+; wrapper_result.value = inner_result;
+; return wrapper_result;
+; }
+;
+; When compiling the above with dxc, ASAN reported a use-after-free in simplifycfg,
+; which originated from a delete during the dxil-loop-deletion pass. This was due
+; to a bug in LoopDeletion::runOnLoop that did not properly handle updated PHIs
+; with duplicate input preds. After this test runs, the loop should be deleted,
+; and the program optimized to simply write out 0s to the cbuffer.
+
+; CHECK: define void @main
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float 0.000000e+00)
+; CHECK-NEXT: call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float 0.000000e+00)
+; CHECK-NEXT: call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float 0.000000e+00)
+; CHECK-NEXT: call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float 0.000000e+00)
+; CHECK-NEXT: ret void
+
+;
+; Output signature:
+;
+; Name Index InterpMode DynIdx
+; -------------------- ----- ---------------------- ------
+; SV_Target 0
+;
+; Buffer Definitions:
+;
+; cbuffer cbuffer_g
+; {
+;
+; struct cbuffer_g
+; {
+;
+; uint4 gu4[1]; ; Offset: 0
+;
+; } cbuffer_g; ; Offset: 0 Size: 16
+;
+; }
+;
+;
+; Resource Bindings:
+;
+; Name Type Format Dim ID HLSL Bind Count
+; ------------------------------ ---------- ------- ----------- ------- -------------- ------
+; cbuffer_g cbuffer NA NA CB0 cb0 1
+;
+target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
+target triple = "dxil-ms-dx"
+
+%cbuffer_g = type { [1 x <4 x i32>] }
+%dx.types.Handle = type { i8* }
+%dx.types.ResourceProperties = type { i32, i32 }
+%dx.types.CBufRet.i32 = type { i32, i32, i32, i32 }
+%struct.return_val = type { <4 x float> }
+
+@cbuffer_g = external constant %cbuffer_g
+@.hca = internal unnamed_addr constant [3 x i32] [i32 1, i32 1, i32 1]
+@llvm.used = appending global [1 x i8*] [i8* bitcast (%cbuffer_g* @cbuffer_g to i8*)], section "llvm.metadata"
+
+; Function Attrs: nounwind readnone
+declare %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %cbuffer_g*, i32)"(i32, %cbuffer_g*, i32) #0
+
+; Function Attrs: nounwind readnone
+declare %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %cbuffer_g)"(i32, %dx.types.Handle, %dx.types.ResourceProperties, %cbuffer_g) #0
+
+; Function Attrs: nounwind
+define void @main(<4 x float>* noalias nocapture readnone) #1 {
+entry:
+ %1 = load %cbuffer_g, %cbuffer_g* @cbuffer_g, align 4, !dbg !25 ; line:45 col:25
+ %cbuffer_g = call %dx.types.Handle @dx.op.createHandleForLib.cbuffer_g(i32 160, %cbuffer_g %1), !dbg !25 ; line:45 col:25 ; CreateHandleForLib(Resource)
+ %2 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %cbuffer_g, %dx.types.ResourceProperties { i32 13, i32 16 }), !dbg !25 ; line:45 col:25 ; AnnotateHandle(res,props) resource: CBuffer
+ %3 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %2, i32 0), !dbg !29 ; line:10 col:23 ; CBufferLoadLegacy(handle,regIndex)
+ %4 = extractvalue %dx.types.CBufRet.i32 %3, 1, !dbg !29 ; line:10 col:23
+ %5 = bitcast i32 %4 to float, !dbg !32 ; line:10 col:15
+ %conv.i.6 = fptosi float %5 to i32, !dbg !33 ; line:11 col:18
+ %cmp1.i.8 = icmp sgt i32 %conv.i.6, 0, !dbg !34 ; line:13 col:11
+ br i1 %cmp1.i.8, label %if.end.i, label %"\01?f@@YA?AV?$vector@M$03@@XZ.exit", !dbg !35 ; line:13 col:9
+
+if.end.i: ; preds = %entry, %if.end.19.i
+ %6 = phi float [ %9, %if.end.19.i ], [ %5, %entry ]
+ %j.i.011 = phi i32 [ %add.i, %if.end.19.i ], [ 0, %entry ]
+ %r.i.0.i310 = phi float [ %r.i.0.i310, %if.end.19.i ], [ 0.000000e+00, %entry ]
+ %i.i.09 = phi i32 [ %j.i.011, %if.end.19.i ], [ 0, %entry ]
+ %cmp4.i = icmp sgt i32 %i.i.09, 0, !dbg !36 ; line:16 col:17
+ br i1 %cmp4.i, label %"\01?f@@YA?AV?$vector@M$03@@XZ.exit", label %if.then.12.i, !dbg !37 ; line:17 col:9
+
+if.then.12.i: ; preds = %if.end.i
+ switch i32 %i.i.09, label %if.end.19.i [
+ i32 0, label %"\01?f@@YA?AV?$vector@M$03@@XZ.exit"
+ i32 -1, label %"\01?f@@YA?AV?$vector@M$03@@XZ.exit"
+ ], !dbg !38 ; line:22 col:9
+
+if.end.19.i: ; preds = %if.then.12.i
+ %add.i = add nuw nsw i32 %j.i.011, 1, !dbg !39 ; line:34 col:12
+ %7 = call %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32 59, %dx.types.Handle %2, i32 0), !dbg !29 ; line:10 col:23 ; CBufferLoadLegacy(handle,regIndex)
+ %8 = extractvalue %dx.types.CBufRet.i32 %7, 1, !dbg !29 ; line:10 col:23
+ %9 = bitcast i32 %8 to float, !dbg !32 ; line:10 col:15
+ %conv.i = fptosi float %9 to i32, !dbg !33 ; line:11 col:18
+ %cmp.i = icmp slt i32 %add.i, %conv.i, !dbg !40 ; line:12 col:17
+ br i1 %cmp.i, label %if.end.i, label %"\01?f@@YA?AV?$vector@M$03@@XZ.exit", !dbg !35 ; line:13 col:9
+
+"\01?f@@YA?AV?$vector@M$03@@XZ.exit": ; preds = %if.then.12.i, %if.then.12.i, %if.end.i, %if.end.19.i, %entry
+ %retval.i.0.i3 = phi float [ 0.000000e+00, %entry ], [ %r.i.0.i310, %if.then.12.i ], [ %r.i.0.i310, %if.then.12.i ], [ 0.000000e+00, %if.end.i ], [ 0.000000e+00, %if.end.19.i ]
+ call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float 0.000000e+00), !dbg !41 ; line:48 col:10 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
+ call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float 0.000000e+00), !dbg !41 ; line:48 col:10 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
+ call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float 0.000000e+00), !dbg !41 ; line:48 col:10 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
+ call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %retval.i.0.i3), !dbg !41 ; line:48 col:10 ; StoreOutput(outputSigId,rowIndex,colIndex,value)
+ ret void, !dbg !42 ; line:48 col:3
+}
+
+; Function Attrs: nounwind
+declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #1
+
+; Function Attrs: nounwind readonly
+declare %dx.types.CBufRet.i32 @dx.op.cbufferLoadLegacy.i32(i32, %dx.types.Handle, i32) #2
+
+; Function Attrs: nounwind readonly
+declare %dx.types.Handle @dx.op.createHandleForLib.cbuffer_g(i32, %cbuffer_g) #2
+
+; Function Attrs: nounwind readnone
+declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #0
+
+attributes #0 = { nounwind readnone }
+attributes #1 = { nounwind }
+attributes #2 = { nounwind readonly }
+
+!llvm.module.flags = !{!0}
+!pauseresume = !{!1}
+!llvm.ident = !{!2}
+!dx.version = !{!3}
+!dx.valver = !{!4}
+!dx.shaderModel = !{!5}
+!dx.resources = !{!6}
+!dx.typeAnnotations = !{!9, !14}
+!dx.entryPoints = !{!21}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !{!"hlsl-dxilemit", !"hlsl-dxilload"}
+!2 = !{!"dxc(private) 1.8.0.4514 (d9bd2a706-dirty)"}
+!3 = !{i32 1, i32 5}
+!4 = !{i32 1, i32 8}
+!5 = !{!"ps", i32 6, i32 5}
+!6 = !{null, null, !7, null}
+!7 = !{!8}
+!8 = !{i32 0, %cbuffer_g* @cbuffer_g, !"cbuffer_g", i32 0, i32 0, i32 1, i32 16, null}
+!9 = !{i32 0, %struct.return_val undef, !10, %cbuffer_g undef, !12}
+!10 = !{i32 16, !11}
+!11 = !{i32 6, !"value", i32 3, i32 0, i32 4, !"SV_Target0", i32 7, i32 9}
+!12 = !{i32 16, !13}
+!13 = !{i32 6, !"gu4", i32 3, i32 0, i32 7, i32 5}
+!14 = !{i32 1, void (<4 x float>*)* @main, !15}
+!15 = !{!16, !18}
+!16 = !{i32 0, !17, !17}
+!17 = !{}
+!18 = !{i32 1, !19, !20}
+!19 = !{i32 4, !"SV_Target0", i32 7, i32 9}
+!20 = !{i32 0}
+!21 = !{void (<4 x float>*)* @main, !"main", !22, !6, null}
+!22 = !{null, !23, null}
+!23 = !{!24}
+!24 = !{i32 0, !"SV_Target", i8 9, i8 16, !20, i8 0, i32 1, i8 4, i32 0, i8 0, null}
+!25 = !DILocation(line: 45, column: 25, scope: !26)
+!26 = !DISubprogram(name: "main", scope: !27, file: !27, line: 44, type: !28, isLocal: false, isDefinition: true, scopeLine: 44, flags: DIFlagPrototyped, isOptimized: false, function: void (<4 x float>*)* @main)
+!27 = !DIFile(filename: "/mnt/c/Users/amaiorano/Downloads/340196361/standalone_reduced.hlsl", directory: "")
+!28 = !DISubroutineType(types: !17)
+!29 = !DILocation(line: 10, column: 23, scope: !30, inlinedAt: !31)
+!30 = !DISubprogram(name: "f", scope: !27, file: !27, line: 5, type: !28, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false)
+!31 = distinct !DILocation(line: 45, column: 25, scope: !26)
+!32 = !DILocation(line: 10, column: 15, scope: !30, inlinedAt: !31)
+!33 = !DILocation(line: 11, column: 18, scope: !30, inlinedAt: !31)
+!34 = !DILocation(line: 13, column: 11, scope: !30, inlinedAt: !31)
+!35 = !DILocation(line: 13, column: 9, scope: !30, inlinedAt: !31)
+!36 = !DILocation(line: 16, column: 17, scope: !30, inlinedAt: !31)
+!37 = !DILocation(line: 17, column: 9, scope: !30, inlinedAt: !31)
+!38 = !DILocation(line: 22, column: 9, scope: !30, inlinedAt: !31)
+!39 = !DILocation(line: 34, column: 12, scope: !30, inlinedAt: !31)
+!40 = !DILocation(line: 12, column: 17, scope: !30, inlinedAt: !31)
+!41 = !DILocation(line: 48, column: 10, scope: !26)
+!42 = !DILocation(line: 48, column: 3, scope: !26)

1
patches/angle/.patches Normal file
View File

@@ -0,0 +1 @@
cherry-pick-5d4df51d1d7d.patch

View File

@@ -0,0 +1,28 @@
From 5d4df51d1d7d6a290d54111527a4798f10c7ca3c Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Thu, 13 Jun 2024 16:54:03 -0400
Subject: [PATCH] M126: Vulkan: Disable VK_EXT_shader_stencil_export on SwiftShader
Bug: chromium:40942995
Change-Id: I5035d9b11997a1c7c839d7d62544fecca9fd1f73
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5634418
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
---
diff --git a/src/libANGLE/renderer/vulkan/vk_renderer.cpp b/src/libANGLE/renderer/vulkan/vk_renderer.cpp
index 581c84b..f818130 100644
--- a/src/libANGLE/renderer/vulkan/vk_renderer.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_renderer.cpp
@@ -4287,9 +4287,11 @@
}
#endif // defined(ANGLE_PLATFORM_ANDROID) || defined(ANGLE_PLATFORM_LINUX)
+ // Disabled on SwiftShader due to http://crbug.com/40942995
ANGLE_FEATURE_CONDITION(
&mFeatures, supportsShaderStencilExport,
- ExtensionFound(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, deviceExtensionNames));
+ ExtensionFound(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, deviceExtensionNames) &&
+ !isSwiftShader);
ANGLE_FEATURE_CONDITION(
&mFeatures, supportsRenderPassLoadStoreOpNone,

View File

@@ -135,3 +135,13 @@ feat_add_support_for_missing_dialog_features_to_shell_dialogs.patch
revert_fix_ime_prevent_tsf_hang_chromium_window_when_dpi_changed.patch
fix_font_face_resolution_when_renderer_is_blocked.patch
x11_use_localized_display_label_only_for_browser_process.patch
feat_enable_passing_exit_code_on_service_process_crash.patch
feat_enable_customizing_symbol_color_in_framecaptionbutton.patch
cherry-pick-44b7fbf35b10.patch
cherry-pick-d54105311590.patch
cherry-pick-43b8b682d05c.patch
cherry-pick-c5dd8839bfaf.patch
cherry-pick-38e4483e47f9.patch
cherry-pick-1b9040817119.patch
cherry-pick-99cafbf4b4b9.patch
cherry-pick-d9f7652c867c.patch

View File

@@ -0,0 +1,84 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bryant Chandler <bryantchandler@chromium.org>
Date: Mon, 24 Jun 2024 17:28:53 +0000
Subject: Fix pointer tear down order problem
Holding a RenderFrameHost* in the `OnceBinding` isn't safe,
because the `RenderFrameHost` can be destroyed before the
binding. This CL changes the task strategy so that the
RenderFrameHost* doesn't need to be bound in a callback.
Tested using the repro steps in the bug and this change stops
it from reproducing.
Fixed: 347373236
Change-Id: Id639f317b0f37a508833aba9fe52ffc5c0ed590c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5640501
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
Commit-Queue: Bryant Chandler <bryantchandler@chromium.org>
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1318653}
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index 65bee7132f6583cb64d774756423942382c8eed6..2c27db7ee49193cbf91158d576e29bb255378a3e 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -2887,25 +2887,19 @@ void MediaStreamManager::GetRawDeviceIdsOpenedForFrame(
RenderFrameHost* render_frame_host,
blink::mojom::MediaStreamType type,
GetRawDeviceIdsOpenedForFrameCallback callback) const {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- CHECK(render_frame_host);
- auto collect_all_render_frame_host_ids = base::BindOnce(
- [](RenderFrameHost* render_frame_host) {
- base::flat_set<GlobalRenderFrameHostId> all_render_frame_host_ids;
- render_frame_host->ForEachRenderFrameHost(
- [&all_render_frame_host_ids](RenderFrameHost* render_frame_host) {
- all_render_frame_host_ids.insert(
- render_frame_host->GetGlobalId());
- });
- return all_render_frame_host_ids;
- },
- render_frame_host);
-
- GetUIThreadTaskRunner()->PostTaskAndReplyWithResult(
- FROM_HERE, std::move(collect_all_render_frame_host_ids),
- base::BindPostTaskToCurrentDefault(
- base::BindOnce(&MediaStreamManager::GetRawDeviceIdsOpenedForFrameIds,
- base::Unretained(this), type, std::move(callback))));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ base::flat_set<GlobalRenderFrameHostId> all_render_frame_host_ids;
+ render_frame_host->ForEachRenderFrameHost(
+ [&all_render_frame_host_ids](RenderFrameHost* render_frame_host) {
+ all_render_frame_host_ids.insert(render_frame_host->GetGlobalId());
+ });
+
+ GetIOThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&MediaStreamManager::GetRawDeviceIdsOpenedForFrameIds,
+ base::Unretained(this), type, std::move(callback),
+ all_render_frame_host_ids));
}
void MediaStreamManager::GetRawDeviceIdsOpenedForFrameIds(
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index b0b1d0aea5bf251411d0cab06562fd77d8d7c549..819c73370d6e6fc5e6ab24e78646a206b6a5873d 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -10808,12 +10808,9 @@ void WebContentsImpl::GetMediaCaptureRawDeviceIdsOpened(
return;
}
- GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&MediaStreamManager::GetRawDeviceIdsOpenedForFrame,
- base::Unretained(media_stream_manager),
- GetPrimaryMainFrame(), type,
- base::BindPostTaskToCurrentDefault(std::move(callback))));
+ media_stream_manager->GetRawDeviceIdsOpenedForFrame(
+ GetPrimaryMainFrame(), type,
+ base::BindPostTaskToCurrentDefault(std::move(callback)));
}
} // namespace content

View File

@@ -0,0 +1,88 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Johannes Kron <kron@chromium.org>
Date: Wed, 19 Jun 2024 20:59:48 +0000
Subject: Use BindPostTask() + weak pointer in callback handler
The callback handler incorrectly accessed member objects directly which may
cause UAF. Avoid this by using BindPostTask() together with a weak pointer.
Fixed: 346898524
Change-Id: I9d03d6decfd0212af88d3d0d8d70f83f1081d2e3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5639016
Reviewed-by: Avi Drissman <avi@chromium.org>
Reviewed-by: Mark Foltz <mfoltz@chromium.org>
Commit-Queue: Johannes Kron <kron@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1317142}
diff --git a/content/browser/media/capture/screen_capture_kit_device_mac.mm b/content/browser/media/capture/screen_capture_kit_device_mac.mm
index 4fb3e8eb5f34a7ee9e8b0f22a7c842129cdc31eb..e2710fba1a8d7a4cee6023558898c74706a9c189 100644
--- a/content/browser/media/capture/screen_capture_kit_device_mac.mm
+++ b/content/browser/media/capture/screen_capture_kit_device_mac.mm
@@ -326,13 +326,18 @@ void OnStreamSample(gfx::ScopedInUseIOSurface io_surface,
destRectInFrame:dest_rect_in_frame
frameRate:requested_capture_format_->
frame_rate];
+
+ __block base::OnceCallback<void()> on_update_configuration_error =
+ base::BindPostTask(
+ device_task_runner_,
+ base::BindOnce(
+ &ScreenCaptureKitDeviceMac::OnUpdateConfigurationError,
+ weak_factory_.GetWeakPtr()));
[stream_
updateConfiguration:config
completionHandler:^(NSError* _Nullable error) {
if (error) {
- client()->OnError(
- media::VideoCaptureError::kScreenCaptureKitStreamError,
- FROM_HERE, "Error on updateConfiguration");
+ std::move(on_update_configuration_error).Run();
}
}];
}
@@ -361,6 +366,21 @@ void OnStreamError() {
FROM_HERE, "Stream delegate called didStopWithError");
}
}
+ void OnUpdateContentFilterCompleted(NSError* _Nullable error) {
+ DCHECK(device_task_runner_->RunsTasksInCurrentSequence());
+ is_resetting_ = false;
+
+ if (error) {
+ client()->OnError(media::VideoCaptureError::kScreenCaptureKitStreamError,
+ FROM_HERE,
+ "Error on updateContentFilter (fullscreen window).");
+ }
+ }
+ void OnUpdateConfigurationError() {
+ DCHECK(device_task_runner_->RunsTasksInCurrentSequence());
+ client()->OnError(media::VideoCaptureError::kScreenCaptureKitStreamError,
+ FROM_HERE, "Error on updateConfiguration");
+ }
// IOSurfaceCaptureDeviceBase:
void OnStart() override {
@@ -411,15 +431,16 @@ void ResetStreamTo(SCWindow* window) override {
SCContentFilter* filter =
[[SCContentFilter alloc] initWithDesktopIndependentWindow:window];
+ __block base::OnceCallback<void(NSError*)>
+ on_update_content_filter_completed = base::BindPostTask(
+ device_task_runner_,
+ base::BindOnce(
+ &ScreenCaptureKitDeviceMac::OnUpdateContentFilterCompleted,
+ weak_factory_.GetWeakPtr()));
+
[stream_ updateContentFilter:filter
completionHandler:^(NSError* _Nullable error) {
- is_resetting_ = false;
- if (error) {
- client()->OnError(
- media::VideoCaptureError::kScreenCaptureKitStreamError,
- FROM_HERE,
- "Error on updateContentFilter (fullscreen window).");
- }
+ std::move(on_update_content_filter_completed).Run(error);
}];
}

View File

@@ -0,0 +1,264 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Philip Pfaffe <pfaffe@chromium.org>
Date: Tue, 18 Jun 2024 10:04:45 +0000
Subject: Prevent script injection on reload when racing with a navigation
DevTools passes the loaderId now when calling Page.reload, in order to
prevent accidentally reloading the wrong page when a navigation occurred
concurrently. It can still happen that the navigation kicks in in between the reload iniated in the browser and the script injection that happens in the renderer, which would run the injected script on the wrong target. We need to check the loaderId also on the renderer side.
Fixed: 341136300
Change-Id: I891fb37fa10e6789c8697a0f29bf7118788a9319
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5625857
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Commit-Queue: Philip Pfaffe <pfaffe@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1316330}
diff --git a/third_party/blink/renderer/core/inspector/build.gni b/third_party/blink/renderer/core/inspector/build.gni
index 2e9feebe066f938506d63d157be65828aa2a27c9..39de006f5f97f9e2a84ee4d38f7bb98e99c41924 100644
--- a/third_party/blink/renderer/core/inspector/build.gni
+++ b/third_party/blink/renderer/core/inspector/build.gni
@@ -138,6 +138,7 @@ blink_core_tests_inspector = [
"inspector_emulation_agent_test.cc",
"inspector_highlight_test.cc",
"inspector_history_test.cc",
+ "inspector_page_agent_unittest.cc",
"inspector_preload_agent_unittest.cc",
"inspector_media_context_impl_unittest.cc",
"inspector_session_state_test.cc",
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
index 1825080b32ab6d7adb86236a389c08caf0b90c5c..f17565a6178c3f47037378faf965cd0f52cb0d26 100644
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -479,6 +479,42 @@ String InspectorPageAgent::CachedResourceTypeJson(
return ResourceTypeJson(ToResourceType(cached_resource.GetType()));
}
+InspectorPageAgent::PageReloadScriptInjection::PageReloadScriptInjection(
+ InspectorAgentState& agent_state)
+ : pending_script_to_evaluate_on_load_once_(&agent_state,
+ /*default_value=*/{}),
+ target_url_for_pending_script_(&agent_state,
+ /*default_value=*/{}) {}
+
+void InspectorPageAgent::PageReloadScriptInjection::clear() {
+ script_to_evaluate_on_load_once_ = {};
+ pending_script_to_evaluate_on_load_once_.Set({});
+ target_url_for_pending_script_.Set({});
+}
+
+void InspectorPageAgent::PageReloadScriptInjection::SetPending(
+ String script,
+ const KURL& target_url) {
+ pending_script_to_evaluate_on_load_once_.Set(script);
+ target_url_for_pending_script_.Set(target_url.GetString().GetString());
+}
+
+void InspectorPageAgent::PageReloadScriptInjection::PromoteToLoadOnce() {
+ script_to_evaluate_on_load_once_ =
+ pending_script_to_evaluate_on_load_once_.Get();
+ target_url_for_active_script_ = target_url_for_pending_script_.Get();
+ pending_script_to_evaluate_on_load_once_.Set({});
+ target_url_for_pending_script_.Set({});
+}
+
+String InspectorPageAgent::PageReloadScriptInjection::GetScriptForInjection(
+ const KURL& target_url) {
+ if (target_url_for_active_script_ == target_url.GetString()) {
+ return script_to_evaluate_on_load_once_;
+ }
+ return {};
+}
+
InspectorPageAgent::InspectorPageAgent(
InspectedFrames* inspected_frames,
Client* client,
@@ -495,8 +531,6 @@ InspectorPageAgent::InspectorPageAgent(
screencast_enabled_(&agent_state_, /*default_value=*/false),
lifecycle_events_enabled_(&agent_state_, /*default_value=*/false),
bypass_csp_enabled_(&agent_state_, /*default_value=*/false),
- pending_script_to_evaluate_on_load_once_(&agent_state_,
- /*default_value=*/String()),
scripts_to_evaluate_on_load_(&agent_state_,
/*default_value=*/String()),
worlds_to_evaluate_on_load_(&agent_state_,
@@ -506,7 +540,8 @@ InspectorPageAgent::InspectorPageAgent(
/*default_value=*/false),
standard_font_size_(&agent_state_, /*default_value=*/0),
fixed_font_size_(&agent_state_, /*default_value=*/0),
- script_font_families_cbor_(&agent_state_, std::vector<uint8_t>()) {}
+ script_font_families_cbor_(&agent_state_, std::vector<uint8_t>()),
+ script_injection_on_load_(agent_state_) {}
void InspectorPageAgent::Restore() {
if (enabled_.Get())
@@ -545,8 +580,7 @@ protocol::Response InspectorPageAgent::enable() {
protocol::Response InspectorPageAgent::disable() {
agent_state_.ClearAllFields();
pending_isolated_worlds_.clear();
- script_to_evaluate_on_load_once_ = String();
- pending_script_to_evaluate_on_load_once_.Set(String());
+ script_injection_on_load_.clear();
instrumenting_agents_->RemoveInspectorPageAgent(this);
inspector_resource_content_loader_->Cancel(
resource_content_loader_client_id_);
@@ -672,8 +706,9 @@ protocol::Response InspectorPageAgent::setAdBlockingEnabled(bool enable) {
protocol::Response InspectorPageAgent::reload(
Maybe<bool> optional_bypass_cache,
Maybe<String> optional_script_to_evaluate_on_load) {
- pending_script_to_evaluate_on_load_once_.Set(
- optional_script_to_evaluate_on_load.value_or(""));
+ script_injection_on_load_.SetPending(
+ optional_script_to_evaluate_on_load.value_or(""),
+ inspected_frames_->Root()->Loader().GetDocumentLoader()->Url());
v8_session_->setSkipAllPauses(true);
v8_session_->resume(true /* terminate on resume */);
return protocol::Response::Success();
@@ -989,7 +1024,9 @@ void InspectorPageAgent::DidCreateMainWorldContext(LocalFrame* frame) {
EvaluateScriptOnNewDocument(*frame, key);
}
- if (script_to_evaluate_on_load_once_.empty()) {
+ String script = script_injection_on_load_.GetScriptForInjection(
+ frame->Loader().GetDocumentLoader()->Url());
+ if (script.empty()) {
return;
}
ScriptState* script_state = ToScriptStateForMainWorld(frame);
@@ -997,9 +1034,8 @@ void InspectorPageAgent::DidCreateMainWorldContext(LocalFrame* frame) {
return;
}
- v8_session_->evaluate(
- script_state->GetContext(),
- ToV8InspectorStringView(script_to_evaluate_on_load_once_));
+ v8_session_->evaluate(script_state->GetContext(),
+ ToV8InspectorStringView(script));
}
void InspectorPageAgent::EvaluateScriptOnNewDocument(
@@ -1049,9 +1085,7 @@ void InspectorPageAgent::LoadEventFired(LocalFrame* frame) {
void InspectorPageAgent::WillCommitLoad(LocalFrame*, DocumentLoader* loader) {
if (loader->GetFrame() == inspected_frames_->Root()) {
- script_to_evaluate_on_load_once_ =
- pending_script_to_evaluate_on_load_once_.Get();
- pending_script_to_evaluate_on_load_once_.Set(String());
+ script_injection_on_load_.PromoteToLoadOnce();
}
GetFrontend()->frameNavigated(BuildObjectForFrame(loader->GetFrame()),
protocol::Page::NavigationTypeEnum::Navigation);
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.h b/third_party/blink/renderer/core/inspector/inspector_page_agent.h
index 6e6263beee810946d03934e7f707bb49a3177a2f..e7003baa895494bf61ad06f875d825ac9f53aec2 100644
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.h
@@ -94,6 +94,22 @@ class CORE_EXPORT InspectorPageAgent final
kOtherResource
};
+ class CORE_EXPORT PageReloadScriptInjection {
+ private:
+ String script_to_evaluate_on_load_once_;
+ String target_url_for_active_script_;
+ InspectorAgentState::String pending_script_to_evaluate_on_load_once_;
+ InspectorAgentState::String target_url_for_pending_script_;
+
+ public:
+ explicit PageReloadScriptInjection(InspectorAgentState&);
+
+ void clear();
+ void SetPending(String script, const KURL& target_url);
+ void PromoteToLoadOnce();
+ String GetScriptForInjection(const KURL& target_url);
+ };
+
static bool CachedResourceContent(const Resource*,
String* result,
bool* base64_encoded);
@@ -307,7 +323,6 @@ class CORE_EXPORT InspectorPageAgent final
ad_script_identifiers_;
v8_inspector::V8InspectorSession* v8_session_;
Client* client_;
- String script_to_evaluate_on_load_once_;
Member<InspectorResourceContentLoader> inspector_resource_content_loader_;
int resource_content_loader_client_id_;
InspectorAgentState::Boolean intercept_file_chooser_;
@@ -315,7 +330,6 @@ class CORE_EXPORT InspectorPageAgent final
InspectorAgentState::Boolean screencast_enabled_;
InspectorAgentState::Boolean lifecycle_events_enabled_;
InspectorAgentState::Boolean bypass_csp_enabled_;
- InspectorAgentState::String pending_script_to_evaluate_on_load_once_;
InspectorAgentState::StringMap scripts_to_evaluate_on_load_;
InspectorAgentState::StringMap worlds_to_evaluate_on_load_;
InspectorAgentState::BooleanMap
@@ -323,6 +337,7 @@ class CORE_EXPORT InspectorPageAgent final
InspectorAgentState::Integer standard_font_size_;
InspectorAgentState::Integer fixed_font_size_;
InspectorAgentState::Bytes script_font_families_cbor_;
+ PageReloadScriptInjection script_injection_on_load_;
};
} // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent_unittest.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b81f6b4735392f3f542ccbb2a114c2def185be1c
--- /dev/null
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent_unittest.cc
@@ -0,0 +1,57 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/inspector/inspector_page_agent.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/inspector/inspector_session_state.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+
+class PageReloadScriptInjectionTest : public testing::Test {
+ protected:
+ blink::mojom::blink::DevToolsSessionStatePtr session_state_cookie_;
+ blink::InspectorAgentState agent_state_;
+ blink::InspectorPageAgent::PageReloadScriptInjection injection_;
+ blink::InspectorSessionState state_;
+
+ public:
+ PageReloadScriptInjectionTest()
+ : agent_state_("page"),
+ injection_(agent_state_),
+ state_(session_state_cookie_.Clone()) {}
+
+ void SetUp() override { agent_state_.InitFrom(&state_); }
+};
+
+TEST_F(PageReloadScriptInjectionTest, PromotesScript) {
+ blink::KURL url("http://example.com");
+ injection_.SetPending("script", url);
+ ASSERT_TRUE(injection_.GetScriptForInjection(url).empty());
+ injection_.PromoteToLoadOnce();
+ ASSERT_EQ(injection_.GetScriptForInjection(url), "script");
+ injection_.PromoteToLoadOnce();
+ ASSERT_TRUE(injection_.GetScriptForInjection(url).empty());
+}
+
+TEST_F(PageReloadScriptInjectionTest, ClearsScript) {
+ blink::KURL url("http://example.com");
+ injection_.SetPending("script", url);
+ injection_.clear();
+ injection_.PromoteToLoadOnce();
+ ASSERT_TRUE(injection_.GetScriptForInjection(url).empty());
+
+ injection_.SetPending("script", url);
+ injection_.PromoteToLoadOnce();
+ ASSERT_EQ(injection_.GetScriptForInjection(url), "script");
+ injection_.clear();
+ ASSERT_TRUE(injection_.GetScriptForInjection(url).empty());
+}
+
+TEST_F(PageReloadScriptInjectionTest, ChecksLoaderId) {
+ blink::KURL url("http://example.com");
+ blink::KURL url2("about:blank");
+ injection_.SetPending("script", url);
+ injection_.PromoteToLoadOnce();
+ ASSERT_TRUE(injection_.GetScriptForInjection(url2).empty());
+}

View File

@@ -0,0 +1,288 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hiroshige Hayashizaki <hiroshige@chromium.org>
Date: Tue, 16 Jul 2024 03:44:29 +0000
Subject: Handle ThrottlingURLLoader deletion during throttle calls
Theoretically `ThrottlingURLLoader` can be deleted during
throttle calls and some call sites have already protection
for such cases. This CL adds the protection for more call sites.
This CL also adds more unit tests for cancelling/deleting
`ThrottlingURLLoader` during throttle calls.
(cherry picked from commit c40f8866cfd6438725cc58e5db2d792e6d9f869b)
Bug: 349342289
Change-Id: I80d64be9ba1a3ac920315f5b4012b29c9737e414
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5665925
Commit-Queue: Hiroshige Hayashizaki <hiroshige@chromium.org>
Reviewed-by: Tsuyoshi Horo <horo@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1323986}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5710951
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
Cr-Commit-Position: refs/branch-heads/6533@{#1515}
Cr-Branched-From: 7e0b87ec6b8cb5cb2969e1479fc25776e582721d-refs/heads/main@{#1313161}
diff --git a/third_party/blink/common/loader/throttling_url_loader.cc b/third_party/blink/common/loader/throttling_url_loader.cc
index d2de163172880bd23f7478c6743c2608a5f04d94..28f55e1b3867cbd1ff3817c21c1f648fef4fcbc7 100644
--- a/third_party/blink/common/loader/throttling_url_loader.cc
+++ b/third_party/blink/common/loader/throttling_url_loader.cc
@@ -660,8 +660,12 @@ void ThrottlingURLLoader::OnReceiveResponse(
for (auto& entry : throttles_) {
auto* throttle = entry.throttle.get();
base::Time start = base::Time::Now();
+ auto weak_ptr = weak_factory_.GetWeakPtr();
throttle->BeforeWillProcessResponse(response_url_, *response_head,
&has_pending_restart);
+ if (!weak_ptr) {
+ return;
+ }
RecordExecutionTimeHistogram("BeforeWillProcessResponse", start);
if (!HandleThrottleResult(throttle)) {
return;
@@ -681,8 +685,12 @@ void ThrottlingURLLoader::OnReceiveResponse(
auto* throttle = entry.throttle.get();
bool throttle_deferred = false;
base::Time start = base::Time::Now();
+ auto weak_ptr = weak_factory_.GetWeakPtr();
throttle->WillProcessResponse(response_url_, response_head.get(),
&throttle_deferred);
+ if (!weak_ptr) {
+ return;
+ }
RecordExecutionTimeHistogram(GetStageNameForHistogram(DEFERRED_RESPONSE),
start);
if (!HandleThrottleResult(throttle, throttle_deferred, &deferred))
@@ -852,7 +860,11 @@ void ThrottlingURLLoader::OnComplete(
for (auto& entry : throttles_) {
auto* throttle = entry.throttle.get();
base::Time start = base::Time::Now();
+ auto weak_ptr = weak_factory_.GetWeakPtr();
throttle->WillOnCompleteWithError(status);
+ if (!weak_ptr) {
+ return;
+ }
RecordExecutionTimeHistogram("WillOnCompleteWithError", start);
if (!HandleThrottleResult(throttle)) {
return;
diff --git a/third_party/blink/common/loader/throttling_url_loader_unittest.cc b/third_party/blink/common/loader/throttling_url_loader_unittest.cc
index 2c73705d12445c13067e937b4bfae1c99290da09..a7e037b2dde9390d9cc15d863ed926809f9afccf 100644
--- a/third_party/blink/common/loader/throttling_url_loader_unittest.cc
+++ b/third_party/blink/common/loader/throttling_url_loader_unittest.cc
@@ -338,9 +338,9 @@ class TestURLLoaderThrottle : public blink::URLLoaderThrottle {
network::mojom::URLResponseHead* response_head,
bool* defer) override {
will_process_response_called_++;
+ response_url_ = response_url;
if (will_process_response_callback_)
will_process_response_callback_.Run(delegate_.get(), defer);
- response_url_ = response_url;
}
void BeforeWillProcessResponse(
@@ -422,6 +422,11 @@ class ThrottlingURLLoaderTest : public testing::Test {
factory_.factory_remote().FlushForTesting();
}
+ void ResetLoader() {
+ ResetThrottleRawPointer();
+ loader_.reset();
+ }
+
void ResetThrottleRawPointer() { throttle_ = nullptr; }
// Be the first member so it is destroyed last.
@@ -467,6 +472,25 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeStart) {
EXPECT_EQ(1u, client_.on_complete_called());
}
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeStart) {
+ base::RunLoop run_loop;
+ throttle_->set_will_start_request_callback(base::BindLambdaForTesting(
+ [this, &run_loop](blink::URLLoaderThrottle::Delegate* delegate,
+ bool* defer) {
+ ResetLoader();
+ run_loop.Quit();
+ }));
+
+ CreateLoaderAndStart();
+ run_loop.Run();
+
+ EXPECT_EQ(1u, factory_.create_loader_and_start_called());
+
+ EXPECT_EQ(0u, client_.on_received_response_called());
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
+ EXPECT_EQ(0u, client_.on_complete_called());
+}
+
TEST_F(ThrottlingURLLoaderTest, DeferBeforeStart) {
throttle_->set_will_start_request_callback(base::BindLambdaForTesting(
[](blink::URLLoaderThrottle::Delegate* delegate, bool* defer) {
@@ -667,6 +691,88 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeRedirect) {
EXPECT_EQ(1u, client_.on_complete_called());
}
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeRedirect) {
+ base::RunLoop run_loop;
+ throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
+ [this, &run_loop](
+ blink::URLLoaderThrottle::Delegate* delegate, bool* /* defer */,
+ std::vector<std::string>* /* removed_headers */,
+ net::HttpRequestHeaders* /* modified_headers */,
+ net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
+ ResetLoader();
+ run_loop.Quit();
+ }));
+
+ CreateLoaderAndStart();
+
+ factory_.NotifyClientOnReceiveRedirect();
+
+ run_loop.Run();
+
+ EXPECT_EQ(0u, client_.on_received_response_called());
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
+ EXPECT_EQ(0u, client_.on_complete_called());
+}
+
+TEST_F(ThrottlingURLLoaderTest, CancelBeforeWillRedirect) {
+ throttle_->set_before_will_redirect_request_callback(
+ base::BindLambdaForTesting(
+ [](blink::URLLoaderThrottle::Delegate* delegate,
+ RestartWithURLReset* restart_with_url_reset,
+ std::vector<std::string>* /* removed_headers */,
+ net::HttpRequestHeaders* /* modified_headers */,
+ net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
+ delegate->CancelWithError(net::ERR_ACCESS_DENIED);
+ }));
+
+ base::RunLoop run_loop;
+ client_.set_on_complete_callback(
+ base::BindLambdaForTesting([&run_loop](int error) {
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
+ run_loop.Quit();
+ }));
+
+ CreateLoaderAndStart();
+
+ factory_.NotifyClientOnReceiveRedirect();
+
+ run_loop.Run();
+
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
+ EXPECT_EQ(1u, throttle_->will_redirect_request_called());
+ EXPECT_EQ(0u, throttle_->before_will_process_response_called());
+ EXPECT_EQ(0u, throttle_->will_process_response_called());
+
+ EXPECT_EQ(0u, client_.on_received_response_called());
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
+ EXPECT_EQ(1u, client_.on_complete_called());
+}
+
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeWillRedirect) {
+ base::RunLoop run_loop;
+ throttle_->set_before_will_redirect_request_callback(
+ base::BindLambdaForTesting(
+ [this, &run_loop](
+ blink::URLLoaderThrottle::Delegate* delegate,
+ RestartWithURLReset* restart_with_url_reset,
+ std::vector<std::string>* /* removed_headers */,
+ net::HttpRequestHeaders* /* modified_headers */,
+ net::HttpRequestHeaders* /* modified_cors_exempt_headers */) {
+ ResetLoader();
+ run_loop.Quit();
+ }));
+
+ CreateLoaderAndStart();
+
+ factory_.NotifyClientOnReceiveRedirect();
+
+ run_loop.Run();
+
+ EXPECT_EQ(0u, client_.on_received_response_called());
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
+ EXPECT_EQ(0u, client_.on_complete_called());
+}
+
TEST_F(ThrottlingURLLoaderTest, DeferBeforeRedirect) {
base::RunLoop run_loop1;
throttle_->set_will_redirect_request_callback(base::BindLambdaForTesting(
@@ -880,6 +986,77 @@ TEST_F(ThrottlingURLLoaderTest, CancelBeforeResponse) {
EXPECT_EQ(1u, client_.on_complete_called());
}
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeResponse) {
+ base::RunLoop run_loop;
+ throttle_->set_will_process_response_callback(base::BindLambdaForTesting(
+ [this, &run_loop](blink::URLLoaderThrottle::Delegate* delegate,
+ bool* defer) {
+ ResetLoader();
+ run_loop.Quit();
+ }));
+
+ CreateLoaderAndStart();
+
+ factory_.NotifyClientOnReceiveResponse();
+
+ run_loop.Run();
+
+ EXPECT_EQ(0u, client_.on_received_response_called());
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
+ EXPECT_EQ(0u, client_.on_complete_called());
+}
+
+TEST_F(ThrottlingURLLoaderTest, CancelBeforeWillProcessResponse) {
+ throttle_->set_before_will_process_response_callback(
+ base::BindLambdaForTesting(
+ [](blink::URLLoaderThrottle::Delegate* delegate,
+ RestartWithURLReset* restart_with_url_reset) {
+ delegate->CancelWithError(net::ERR_ACCESS_DENIED);
+ }));
+
+ base::RunLoop run_loop;
+ client_.set_on_complete_callback(
+ base::BindLambdaForTesting([&run_loop](int error) {
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, error);
+ run_loop.Quit();
+ }));
+
+ CreateLoaderAndStart();
+
+ factory_.NotifyClientOnReceiveResponse();
+
+ run_loop.Run();
+
+ EXPECT_EQ(1u, throttle_->will_start_request_called());
+ EXPECT_EQ(0u, throttle_->will_redirect_request_called());
+ EXPECT_EQ(1u, throttle_->before_will_process_response_called());
+ EXPECT_EQ(0u, throttle_->will_process_response_called());
+ EXPECT_EQ(0u, client_.on_received_response_called());
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
+ EXPECT_EQ(1u, client_.on_complete_called());
+}
+
+TEST_F(ThrottlingURLLoaderTest, DeleteBeforeWillProcessResponse) {
+ base::RunLoop run_loop;
+ throttle_->set_before_will_process_response_callback(
+ base::BindLambdaForTesting(
+ [this, &run_loop](blink::URLLoaderThrottle::Delegate* delegate,
+ RestartWithURLReset* restart_with_url_reset) {
+ ResetLoader();
+ run_loop.Quit();
+ }));
+
+ CreateLoaderAndStart();
+
+ factory_.NotifyClientOnReceiveResponse();
+
+ run_loop.Run();
+
+ EXPECT_EQ(0u, client_.on_received_response_called());
+ EXPECT_EQ(0u, client_.on_received_redirect_called());
+ EXPECT_EQ(0u, client_.on_complete_called());
+}
+
TEST_F(ThrottlingURLLoaderTest, DeferBeforeResponse) {
base::RunLoop run_loop1;
throttle_->set_will_process_response_callback(base::BindRepeating(

View File

@@ -0,0 +1,166 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yann Dago <ydago@chromium.org>
Date: Mon, 8 Jul 2024 16:20:32 +0000
Subject: Ensure chrome://policy/test messages ignored when not supported
It was possible to go to chrome://policy and in the dev tools and send
the right message to set test policies even if the policy test page was disabled and/or unavailable because both pages share the same handler.
Bug: 338248595
Change-Id: If689325999cb108b2b71b2821d905e42efd3390d
Low-Coverage-Reason: TRIVIAL_CHANGE
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5679162
Auto-Submit: Yann Dago <ydago@chromium.org>
Reviewed-by: Rohit Rao <rohitrao@chromium.org>
Reviewed-by: Sergey Poromov <poromov@chromium.org>
Commit-Queue: Rohit Rao <rohitrao@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1324277}
diff --git a/chrome/browser/ui/webui/policy/policy_test_ui_browsertest.cc b/chrome/browser/ui/webui/policy/policy_test_ui_browsertest.cc
index e27325a18087c8a01d21111f2fa0dd6e6da60023..a03c639b8654a5cbedccc3c38de4007dba084bf8 100644
--- a/chrome/browser/ui/webui/policy/policy_test_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/policy/policy_test_ui_browsertest.cc
@@ -8,6 +8,7 @@
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
+#include "chrome/browser/enterprise/browser_management/browser_management_service.h"
#include "chrome/browser/enterprise/browser_management/management_service_factory.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/policy/chrome_browser_policy_connector.h"
@@ -270,6 +271,57 @@ class PolicyTestHandlerTest : public PlatformBrowserTest {
#endif
};
+IN_PROC_BROWSER_TEST_F(PolicyTestHandlerTest,
+ HandleSetLocalTestPoliciesNotSupported) {
+ // Ensure chrome://policy/test not supported.
+ policy::ScopedManagementServiceOverrideForTesting profile_management(
+ policy::ManagementServiceFactory::GetForProfile(GetProfile()),
+ policy::EnterpriseManagementAuthority::CLOUD);
+ std::unique_ptr<PolicyUIHandler> handler = SetUpHandler();
+ const std::string jsonString =
+ R"([
+ {"level": 0,"scope": 0,"source": 0, "namespace": "chrome",
+ "name": "AutofillAddressEnabled","value": false},
+ {"level": 1,"scope": 1,"source": 2, "namespace": "chrome",
+ "name": "CloudReportingEnabled","value": true}
+ ])";
+ const std::string revertAppliedPoliciesButtonDisabledJs =
+ R"(
+ document
+ .querySelector('#revert-applied-policies')
+ .disabled;
+ )";
+
+ base::Value::List list_args;
+
+ list_args.Append("setLocalTestPolicies");
+ list_args.Append(jsonString);
+ list_args.Append("{}");
+
+ // Open chrome://policy
+ ASSERT_TRUE(
+ content::NavigateToURL(web_contents(), GURL(chrome::kChromeUIPolicyURL)));
+ web_ui()->HandleReceivedMessage("setLocalTestPolicies", list_args);
+
+ base::RunLoop().RunUntilIdle();
+
+ const policy::PolicyNamespace chrome_namespace(policy::POLICY_DOMAIN_CHROME,
+ std::string());
+ policy::PolicyService* policy_service =
+ GetProfile()->GetProfilePolicyConnector()->policy_service();
+
+ // Check policies not applied
+ const policy::PolicyMap* policy_map =
+ &policy_service->GetPolicies(chrome_namespace);
+ ASSERT_TRUE(policy_map);
+
+ {
+ const policy::PolicyMap::Entry* entry =
+ policy_map->Get(policy::key::kAutofillAddressEnabled);
+ ASSERT_FALSE(entry);
+ }
+}
+
IN_PROC_BROWSER_TEST_F(PolicyTestHandlerTest,
HandleSetAndRevertLocalTestPolicies) {
if (!policy::utils::IsPolicyTestingEnabled(/*pref_service=*/nullptr,
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.cc b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
index 0d13979009fc4df379432d5eea1a394607203615..1dc6ecc6bed91115be10021c0661f8d81456161b 100644
--- a/chrome/browser/ui/webui/policy/policy_ui_handler.cc
+++ b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
@@ -49,6 +49,7 @@
#include "chrome/browser/ui/chrome_select_file_policy.h"
#include "chrome/browser/ui/webui/policy/policy_ui.h"
#include "chrome/browser/ui/webui/webui_util.h"
+#include "chrome/common/channel_info.h"
#include "chrome/grit/branded_strings.h"
#include "components/crx_file/id_util.h"
#include "components/enterprise/browser/controller/browser_dm_token_storage.h"
@@ -69,6 +70,7 @@
#include "components/policy/core/common/policy_pref_names.h"
#include "components/policy/core/common/policy_scheduler.h"
#include "components/policy/core/common/policy_types.h"
+#include "components/policy/core/common/policy_utils.h"
#include "components/policy/core/common/remote_commands/remote_commands_service.h"
#include "components/policy/core/common/schema.h"
#include "components/policy/core/common/schema_map.h"
@@ -316,6 +318,12 @@ void PolicyUIHandler::HandleCopyPoliciesJson(const base::Value::List& args) {
void PolicyUIHandler::HandleSetLocalTestPolicies(
const base::Value::List& args) {
std::string policies = args[1].GetString();
+ AllowJavascript();
+
+ if (!PolicyUI::ShouldLoadTestPage(Profile::FromWebUI(web_ui()))) {
+ ResolveJavascriptCallback(args[0], true);
+ return;
+ }
policy::LocalTestPolicyProvider* local_test_provider =
static_cast<policy::LocalTestPolicyProvider*>(
@@ -338,12 +346,14 @@ void PolicyUIHandler::HandleSetLocalTestPolicies(
->UseLocalTestPolicyProvider();
local_test_provider->LoadJsonPolicies(policies);
- AllowJavascript();
ResolveJavascriptCallback(args[0], true);
}
void PolicyUIHandler::HandleRevertLocalTestPolicies(
const base::Value::List& args) {
+ if (!PolicyUI::ShouldLoadTestPage(Profile::FromWebUI(web_ui()))) {
+ return;
+ }
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
Profile::FromWebUI(web_ui())->GetPrefs()->ClearPref(
prefs::kUserCloudSigninPolicyResponseFromPolicyTestPage);
diff --git a/ios/chrome/browser/webui/ui_bundled/policy/policy_ui_handler.mm b/ios/chrome/browser/webui/ui_bundled/policy/policy_ui_handler.mm
index 577caf2012e0cdcdcf5baa4c5a288119da40cabd..94466842c2faeb13fd0ae33ba619362f8a43cd06 100644
--- a/ios/chrome/browser/webui/ui_bundled/policy/policy_ui_handler.mm
+++ b/ios/chrome/browser/webui/ui_bundled/policy/policy_ui_handler.mm
@@ -220,6 +220,12 @@
const base::Value::List& args) {
std::string json_policies_string = args[1].GetString();
+ if (!PolicyUI::ShouldLoadTestPage(
+ ChromeBrowserState::FromWebUIIOS(web_ui()))) {
+ web_ui()->ResolveJavascriptCallback(args[0], true);
+ return;
+ }
+
policy::LocalTestPolicyProvider* local_test_provider =
static_cast<policy::LocalTestPolicyProvider*>(
GetApplicationContext()
@@ -238,6 +244,11 @@
void PolicyUIHandler::HandleRevertLocalTestPolicies(
const base::Value::List& args) {
+ if (!PolicyUI::ShouldLoadTestPage(
+ ChromeBrowserState::FromWebUIIOS(web_ui()))) {
+ return;
+ }
+
ChromeBrowserState::FromWebUIIOS(web_ui())
->GetPolicyConnector()
->RevertUseLocalTestPolicyProvider();

View File

@@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rakina Zata Amni <rakina@chromium.org>
Date: Wed, 19 Jun 2024 02:49:58 +0000
Subject: Destruct controller before referenced WebUI in CreateWebUIIfNeeded
Reset `controller` first before resetting `web_ui_`, since the
controller still has a pointer to `web_ui_`, to avoid referencing to
the already deleted `web_ui_` object from `controller`'s destructor.
Bug: 345640549
Change-Id: Ie9c193436b593845d8269605f68bf94bc75beed7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5624749
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
Reviewed-by: Nasko Oskov <nasko@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1316830}
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index 8a9beaf3bfb9fe5eca8ca6675c7c45b4b880db03..85041c38c8d2e84d780948a4dab94013ce39dfbe 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -10268,6 +10268,11 @@ void NavigationRequest::CreateWebUIIfNeeded(RenderFrameHostImpl* frame_host) {
bindings() != web_ui_->GetBindings()) {
RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
base::WeakPtr<NavigationRequest> self = GetWeakPtr();
+ // Reset `controller` first before resetting `web_ui_`, since the controller
+ // still has a pointer to `web_ui_`, to avoid referencing to the already
+ // deleted `web_ui_` object from `controller`'s destructor. See also
+ // https://crbug.com/345640549.
+ controller.reset();
web_ui_.reset();
// Resetting the WebUI may indirectly call content's embedders and delete
// `this`. There are no known occurrences of it, so we assume this never

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "mark a. foltz" <mfoltz@chromium.org>
Date: Mon, 17 Jun 2024 23:07:32 +0000
Subject: Retain refptr to shared helper to prevent UAF.
Capture a reference to the shared helper in the onerror handler to
prevent a UAF that can occur when the browser drops the mojo
connection.
Bug: 346692546
Change-Id: Ifb264488a6fa8417c134a34d902605d2c141720b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5634908
Reviewed-by: Avi Drissman <avi@chromium.org>
Commit-Queue: Mark Foltz <mfoltz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1316145}
diff --git a/media/audio/mac/audio_loopback_input_mac_impl.mm b/media/audio/mac/audio_loopback_input_mac_impl.mm
index 7b301492f17a3f1da96b8ff990f6deeb4a19b6e3..f90c00e668f58c2389e622466422ae7aa237c94d 100644
--- a/media/audio/mac/audio_loopback_input_mac_impl.mm
+++ b/media/audio/mac/audio_loopback_input_mac_impl.mm
@@ -394,12 +394,15 @@ - (void)stream:(SCStream*)stream
base::BindRepeating(&SCKAudioInputStream::OnStreamError,
base::Unretained(this)));
+ // Make a local copy of the shared_refptr in case the error handler is called
+ // after `this` is destroyed.
+ auto local_shared_helper = shared_helper_;
[stream_ startCaptureWithCompletionHandler:^(NSError* error) {
if (!error) {
return;
}
- shared_helper_->OnStreamError(error);
+ local_shared_helper->OnStreamError(error);
}];
}

View File

@@ -0,0 +1,159 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Adam Rice <ricea@chromium.org>
Date: Thu, 25 Jul 2024 05:28:45 +0000
Subject: Don't allocate WebTransportCloseInfo on stack
blink::WebTransport::OnClosed() was allocating a WebTransportCloseInfo
object on the stack. Since it is a garbage-collected object, this is
wrong. Allocate it with MakeGarbageCollected<>() instead.
(cherry picked from commit 84c1481d8a8d5e7f51316b648d1bf71f2ae52122)
Fixed: 352872238
Change-Id: I83484021d5f3f6d49d3c222c8f2dc34219f2d240
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5725413
Commit-Queue: Nidhi Jaju <nidhijaju@chromium.org>
Reviewed-by: Nidhi Jaju <nidhijaju@chromium.org>
Auto-Submit: Adam Rice <ricea@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1331525}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5740536
Commit-Queue: Adam Rice <ricea@chromium.org>
Cr-Commit-Position: refs/branch-heads/6478@{#1848}
Cr-Branched-From: e6143acc03189c5e52959545b110d6d17ecd5286-refs/heads/main@{#1300313}
diff --git a/third_party/blink/renderer/modules/webtransport/web_transport.cc b/third_party/blink/renderer/modules/webtransport/web_transport.cc
index bcfa17448f3051dc2b292aa3e19dbfb915cf692a..4922359605b53c6b9ac5339f6ce6b3613bfe275b 100644
--- a/third_party/blink/renderer/modules/webtransport/web_transport.cc
+++ b/third_party/blink/renderer/modules/webtransport/web_transport.cc
@@ -1092,17 +1092,17 @@ void WebTransport::OnClosed(
latest_stats_ = ConvertStatsFromMojom(std::move(final_stats));
- WebTransportCloseInfo idl_close_info;
+ auto* idl_close_info = MakeGarbageCollected<WebTransportCloseInfo>();
if (close_info) {
- idl_close_info.setCloseCode(close_info->code);
- idl_close_info.setReason(close_info->reason);
+ idl_close_info->setCloseCode(close_info->code);
+ idl_close_info->setReason(close_info->reason);
}
v8::Local<v8::Value> error = WebTransportError::Create(
isolate, /*stream_error_code=*/std::nullopt, "The session is closed.",
WebTransportError::Source::kSession);
- Cleanup(&idl_close_info, error, /*abruptly=*/false);
+ Cleanup(idl_close_info, error, /*abruptly=*/false);
}
void WebTransport::OnOutgoingStreamClosed(uint32_t stream_id) {
diff --git a/third_party/blink/renderer/modules/webtransport/web_transport_test.cc b/third_party/blink/renderer/modules/webtransport/web_transport_test.cc
index 01f5a0fca58d88e342298e03231dd2263ca5a678..fc05ad637888df648f8692683f8a626c8d6a38dd 100644
--- a/third_party/blink/renderer/modules/webtransport/web_transport_test.cc
+++ b/third_party/blink/renderer/modules/webtransport/web_transport_test.cc
@@ -1959,6 +1959,21 @@ TEST_F(WebTransportTest, OnClosed) {
EXPECT_EQ(close_info->reason(), "reason");
}
+// Regression test for https://crbug.com/347710668.
+TEST_F(WebTransportTest, ClosedAccessorCalledAfterOnClosed) {
+ V8TestingScope scope;
+
+ auto* web_transport =
+ CreateAndConnectSuccessfully(scope, "https://example.com");
+
+ web_transport->OnClosed(
+ network::mojom::blink::WebTransportCloseInfo::New(99, "reason"),
+ network::mojom::blink::WebTransportStats::New());
+
+ // If this doesn't crash then the test passed.
+ EXPECT_FALSE(web_transport->closed(scope.GetScriptState()).IsEmpty());
+}
+
TEST_F(WebTransportTest, OnClosedWithNull) {
V8TestingScope scope;
v8::Isolate* isolate = scope.GetIsolate();
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any-expected.txt
index d4e43edbd19a9eb16f3384c1c95e5c3d1a2f2619..09e2bbddaa40e1cfc192d3adbeb9538e7aeaebfe 100644
--- a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any-expected.txt
@@ -1,4 +1,5 @@
This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: promise_rejects_dom: function "function() { throw e }" threw object "NetworkError: Failed to execute 'createBidirectionalStream' on 'WebTransport': No connection." that is not a DOMException InvalidStateError: property "code" is equal to 19, expected 11
[FAIL] opening unidirectional stream before ready
promise_test: Unhandled rejection with value: object "NetworkError: Failed to execute 'createUnidirectionalStream' on 'WebTransport': No connection."
[FAIL] opening bidirectional stream before ready
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.js b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.js
index 0d8579584fbb21e74595588f663ef21c3b028c63..d69967ba70bb716f8664f973fe83d4158ba6da89 100644
--- a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.js
@@ -163,3 +163,24 @@ promise_test(async t => {
const wt = new WebTransport(webtransport_url('server-close.py'));
promise_rejects_dom(t, "InvalidStateError", wt.createBidirectionalStream());
}, 'server initiated closure while opening bidirectional stream before ready');
+
+// Regression test for https://crbug.com/347710668.
+promise_test(async t => {
+ const wt = new WebTransport(webtransport_url('server-read-then-close.py'));
+ add_completion_callback(() => wt.close());
+ await wt.ready;
+
+ const bidi_reader = wt.incomingBidirectionalStreams.getReader();
+ const { value: bidi } = await bidi_reader.read();
+
+ bidi.writable.getWriter().write(new TextEncoder().encode('some data'));
+ const reader = bidi.readable.getReader();
+ await reader.closed.catch(t.step_func(
+ e => assert_true(e instanceof WebTransportError)));
+
+ // The WebTransport session will already be closed.
+ const {reason, closeCode} = await wt.closed;
+
+ assert_equals(reason, '', 'reason should be default');
+ assert_equals(closeCode, 0, 'closeCode should be default');
+}, 'reading closed property after close should work');
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.serviceworker-expected.txt
index d4e43edbd19a9eb16f3384c1c95e5c3d1a2f2619..09e2bbddaa40e1cfc192d3adbeb9538e7aeaebfe 100644
--- a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.serviceworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.serviceworker-expected.txt
@@ -1,4 +1,5 @@
This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: promise_rejects_dom: function "function() { throw e }" threw object "NetworkError: Failed to execute 'createBidirectionalStream' on 'WebTransport': No connection." that is not a DOMException InvalidStateError: property "code" is equal to 19, expected 11
[FAIL] opening unidirectional stream before ready
promise_test: Unhandled rejection with value: object "NetworkError: Failed to execute 'createUnidirectionalStream' on 'WebTransport': No connection."
[FAIL] opening bidirectional stream before ready
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.sharedworker-expected.txt
index d4e43edbd19a9eb16f3384c1c95e5c3d1a2f2619..09e2bbddaa40e1cfc192d3adbeb9538e7aeaebfe 100644
--- a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.sharedworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.sharedworker-expected.txt
@@ -1,4 +1,5 @@
This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: promise_rejects_dom: function "function() { throw e }" threw object "NetworkError: Failed to execute 'createBidirectionalStream' on 'WebTransport': No connection." that is not a DOMException InvalidStateError: property "code" is equal to 19, expected 11
[FAIL] opening unidirectional stream before ready
promise_test: Unhandled rejection with value: object "NetworkError: Failed to execute 'createUnidirectionalStream' on 'WebTransport': No connection."
[FAIL] opening bidirectional stream before ready
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.worker-expected.txt
index d4e43edbd19a9eb16f3384c1c95e5c3d1a2f2619..09e2bbddaa40e1cfc192d3adbeb9538e7aeaebfe 100644
--- a/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webtransport/close.https.any.worker-expected.txt
@@ -1,4 +1,5 @@
This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: promise_rejects_dom: function "function() { throw e }" threw object "NetworkError: Failed to execute 'createBidirectionalStream' on 'WebTransport': No connection." that is not a DOMException InvalidStateError: property "code" is equal to 19, expected 11
[FAIL] opening unidirectional stream before ready
promise_test: Unhandled rejection with value: object "NetworkError: Failed to execute 'createUnidirectionalStream' on 'WebTransport': No connection."
[FAIL] opening bidirectional stream before ready
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/handlers/server-read-then-close.py b/third_party/blink/web_tests/external/wpt/webtransport/handlers/server-read-then-close.py
new file mode 100644
index 0000000000000000000000000000000000000000..7f992e0dcca3ae62277cac0fa39355fce3e57be0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webtransport/handlers/server-read-then-close.py
@@ -0,0 +1,9 @@
+def session_established(session):
+ stream_id = session.create_bidirectional_stream()
+
+
+def stream_data_received(session,
+ stream_id: int,
+ data: bytes,
+ stream_ended: bool):
+ session.close(None)

View File

@@ -8,6 +8,9 @@ This CL adds support for the following features to //shell_dialogs:
* showHiddenFiles - Show hidden files in dialog.
* showOverwriteConfirmation - Whether the user will be presented a confirmation dialog if the user types a file name that already exists.
It also:
* Changes XDG Portal implementation behavior to set default path regardless of dialog type.
This may be partially upstreamed to Chromium in the future.
diff --git a/ui/gtk/select_file_dialog_linux_gtk.cc b/ui/gtk/select_file_dialog_linux_gtk.cc
@@ -269,7 +272,7 @@ index 796e98cd42a5c6087da6cdf1d7bff4248113aeab..bcf43ab96bcb426fde6362dd0da44217
&SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse, this,
parent, params));
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.cc b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
index decba61300c21f7f5d070b24c23ff2e08b06d161..ae6e76186b6db9d0d32d51baaaeafa6106225c0f 100644
index decba61300c21f7f5d070b24c23ff2e08b06d161..26ba2c573ca83433de82496e6f20f71c194babc0 100644
--- a/ui/shell_dialogs/select_file_dialog_linux_portal.cc
+++ b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
@@ -218,6 +218,10 @@ void SelectFileDialogLinuxPortal::SelectFileImpl(
@@ -360,7 +363,7 @@ index decba61300c21f7f5d070b24c23ff2e08b06d161..ae6e76186b6db9d0d32d51baaaeafa61
IDS_SELECT_UPLOAD_FOLDER_DIALOG_UPLOAD_BUTTON));
}
@@ -562,6 +571,7 @@ void SelectFileDialogLinuxPortal::DialogInfo::AppendOptions(
@@ -562,12 +571,12 @@ void SelectFileDialogLinuxPortal::DialogInfo::AppendOptions(
type == SelectFileDialog::Type::SELECT_UPLOAD_FOLDER ||
type == SelectFileDialog::Type::SELECT_EXISTING_FOLDER) {
AppendBoolOption(&options_writer, kFileChooserOptionDirectory, true);
@@ -368,6 +371,13 @@ index decba61300c21f7f5d070b24c23ff2e08b06d161..ae6e76186b6db9d0d32d51baaaeafa61
} else if (type == SelectFileDialog::Type::SELECT_OPEN_MULTI_FILE) {
AppendBoolOption(&options_writer, kFileChooserOptionMultiple, true);
}
- if (type == SelectFileDialog::Type::SELECT_SAVEAS_FILE &&
- !default_path.empty()) {
+ if (!default_path.empty()) {
if (default_path_exists) {
// If this is an existing directory, navigate to that directory, with no
// filename.
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.h b/ui/shell_dialogs/select_file_dialog_linux_portal.h
index c487f7da19e2d05696a8eb72f2fa3e12972149f3..02a40c571570974dcc61e1b1f7ed95fbfc2bedf2 100644
--- a/ui/shell_dialogs/select_file_dialog_linux_portal.h

View File

@@ -0,0 +1,80 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Fri, 5 Apr 2024 11:07:22 +0200
Subject: feat: enable customizing symbol color in FrameCaptionButton
This enables customizing the symbol color on a given FrameCaptionButton
for the Window Controls Overlay API on Linux. By default, the symbol color
is dynamically calculated based on the background color of the button to
ensure it has minimum contrast required to be accessible.
This should be upstreamed to Chromium if possible.
diff --git a/ui/views/window/frame_caption_button.cc b/ui/views/window/frame_caption_button.cc
index 73e6020e3b9b6e0d12a8dea991f189b3ddeab14c..b38e5bd1408c26cbbfc995fc2ac5dc5983cc0db7 100644
--- a/ui/views/window/frame_caption_button.cc
+++ b/ui/views/window/frame_caption_button.cc
@@ -107,7 +107,7 @@ FrameCaptionButton::FrameCaptionButton(PressedCallback callback,
FrameCaptionButton::~FrameCaptionButton() = default;
// static
-SkColor FrameCaptionButton::GetButtonColor(SkColor background_color) {
+SkColor FrameCaptionButton::GetAccessibleButtonColor(SkColor background_color) {
// Use IsDark() to change target colors instead of PickContrastingColor(), so
// that DefaultFrameHeader::GetTitleColor() (which uses different target
// colors) can change between light/dark targets at the same time. It looks
@@ -124,6 +124,22 @@ SkColor FrameCaptionButton::GetButtonColor(SkColor background_color) {
.color;
}
+SkColor FrameCaptionButton::GetButtonColor(SkColor background_color) {
+ // If the button color has been overridden, return that.
+ if (button_color_ != SkColor())
+ return button_color_;
+
+ return GetAccessibleButtonColor(background_color);
+}
+
+void FrameCaptionButton::SetButtonColor(SkColor button_color) {
+ if (button_color_ == button_color)
+ return;
+
+ button_color_ = button_color;
+ MaybeRefreshIconAndInkdropBaseColor();
+}
+
// static
float FrameCaptionButton::GetInactiveButtonColorAlphaRatio() {
return 0.38f;
diff --git a/ui/views/window/frame_caption_button.h b/ui/views/window/frame_caption_button.h
index 0d20ec5891d08187b4dae7a6b46a9a6de2f7c39c..eb396811a39c4e6021916dbba1f89baa83d77d31 100644
--- a/ui/views/window/frame_caption_button.h
+++ b/ui/views/window/frame_caption_button.h
@@ -43,8 +43,18 @@ class VIEWS_EXPORT FrameCaptionButton : public Button {
FrameCaptionButton& operator=(const FrameCaptionButton&) = delete;
~FrameCaptionButton() override;
+ // Gets the color to use for a frame caption button with accessible contrast
+ // to the given background color.
+ static SkColor GetAccessibleButtonColor(SkColor background_color);
+
// Gets the color to use for a frame caption button.
- static SkColor GetButtonColor(SkColor background_color);
+ SkColor GetButtonColor(SkColor background_color);
+
+ // Sets the color to use for a frame caption button.
+ // The color is by default calculated to be an accessible contrast
+ // to the background color, so you should keep that in mind when
+ // overriding that behavior.
+ void SetButtonColor(SkColor button_color);
// Gets the alpha ratio for the colors of inactive frame caption buttons.
static float GetInactiveButtonColorAlphaRatio();
@@ -133,6 +143,7 @@ class VIEWS_EXPORT FrameCaptionButton : public Button {
// TODO(b/292154873): Store the foreground color instead of the background
// color for the SkColor type.
absl::variant<ui::ColorId, SkColor> color_ = gfx::kPlaceholderColor;
+ SkColor button_color_ = SkColor();
// Whether the button should be painted as active.
bool paint_as_active_ = false;

View File

@@ -0,0 +1,136 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Tue, 28 May 2024 10:44:06 +0200
Subject: feat: enable passing exit code on service process crash
This patch enables plumbing the exit code of the service process to the
browser process when the service process crashes. The process can perform cleanup
after the message pipe disconnection, which previously led to racy and incorrect
exit codes in some crashing scenarios. To mitigate this, we can rely on
ServiceProcessHost::Observer functions, but we need to pass the exit code to
the observer.
diff --git a/content/browser/service_process_host_impl.cc b/content/browser/service_process_host_impl.cc
index 73d8c2fcbed9db89161ad3fabd5cbfb6b3761a4d..9d5673a19f4d9cc1754759ac792e0bdd0d12a2d7 100644
--- a/content/browser/service_process_host_impl.cc
+++ b/content/browser/service_process_host_impl.cc
@@ -72,12 +72,15 @@ class ServiceProcessTracker {
processes_.erase(iter);
}
- void NotifyCrashed(ServiceProcessId id) {
+ void NotifyCrashed(ServiceProcessId id, int exit_code) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto iter = processes_.find(id);
DCHECK(iter != processes_.end());
- for (auto& observer : observers_)
- observer.OnServiceProcessCrashed(iter->second.Duplicate());
+ for (auto& observer : observers_) {
+ auto params = iter->second.Duplicate();
+ params.set_exit_code(exit_code);
+ observer.OnServiceProcessCrashed(params);
+ }
processes_.erase(iter);
}
@@ -86,6 +89,11 @@ class ServiceProcessTracker {
observers_.AddObserver(observer);
}
+ bool HasObserver(ServiceProcessHost::Observer* observer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return observers_.HasObserver(observer);
+ }
+
void RemoveObserver(ServiceProcessHost::Observer* observer) {
// NOTE: Some tests may remove observers after BrowserThreads are shut down.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
@@ -153,7 +161,7 @@ class UtilityProcessClient : public UtilityProcessHost::Client {
process_info_->service_process_id());
}
- void OnProcessCrashed() override {
+ void OnProcessCrashed(int exit_code) override {
// TODO(https://crbug.com/1016027): It is unclear how we can observe
// |OnProcessCrashed()| without observing |OnProcessLaunched()| first, but
// it can happen on Android. Ignore the notification in this case.
@@ -161,7 +169,7 @@ class UtilityProcessClient : public UtilityProcessHost::Client {
return;
GetServiceProcessTracker().NotifyCrashed(
- process_info_->service_process_id());
+ process_info_->service_process_id(), exit_code);
}
private:
@@ -233,6 +241,11 @@ void ServiceProcessHost::AddObserver(Observer* observer) {
GetServiceProcessTracker().AddObserver(observer);
}
+// static
+bool ServiceProcessHost::HasObserver(Observer* observer) {
+ return GetServiceProcessTracker().HasObserver(observer);
+}
+
// static
void ServiceProcessHost::RemoveObserver(Observer* observer) {
GetServiceProcessTracker().RemoveObserver(observer);
diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc
index 9b99a3caf366368917c39ae5c12a11f5294c3948..c54bd936ed463dea36f3b2a301549111bfded55d 100644
--- a/content/browser/utility_process_host.cc
+++ b/content/browser/utility_process_host.cc
@@ -551,7 +551,7 @@ void UtilityProcessHost::OnProcessCrashed(int exit_code) {
// Take ownership of |client_| so the destructor doesn't notify it of
// termination.
auto client = std::move(client_);
- client->OnProcessCrashed();
+ client->OnProcessCrashed(exit_code);
}
std::optional<std::string> UtilityProcessHost::GetServiceName() {
diff --git a/content/browser/utility_process_host.h b/content/browser/utility_process_host.h
index ecb0b0e02870386f3ad4365461325ba0627ba1ce..780e43ddaedbf91aea9918bb860c487b4aed54b8 100644
--- a/content/browser/utility_process_host.h
+++ b/content/browser/utility_process_host.h
@@ -84,7 +84,7 @@ class CONTENT_EXPORT UtilityProcessHost
virtual void OnProcessLaunched(const base::Process& process) {}
virtual void OnProcessTerminatedNormally() {}
- virtual void OnProcessCrashed() {}
+ virtual void OnProcessCrashed(int exit_code) {}
};
// This class is self-owned. It must be instantiated using new, and shouldn't
diff --git a/content/public/browser/service_process_host.h b/content/public/browser/service_process_host.h
index 4895ba5c305c898bb21472a2408ecd62afb46fd6..c67737f4647b2b07f13aee77d95401edf34c72d0 100644
--- a/content/public/browser/service_process_host.h
+++ b/content/public/browser/service_process_host.h
@@ -234,6 +234,10 @@ class CONTENT_EXPORT ServiceProcessHost {
// removed before destruction. Must be called from the UI thread only.
static void AddObserver(Observer* observer);
+ // Returns true if the given observer is currently registered.
+ // Must be called from the UI thread only.
+ static bool HasObserver(Observer* observer);
+
// Removes a registered observer. This must be called some time before
// |*observer| is destroyed and must be called from the UI thread only.
static void RemoveObserver(Observer* observer);
diff --git a/content/public/browser/service_process_info.h b/content/public/browser/service_process_info.h
index 1a8656aef341cd3b23af588fb00569b79d6cd100..f904af7ee6bbacf4474e0939855ecf9f2c9a5eaa 100644
--- a/content/public/browser/service_process_info.h
+++ b/content/public/browser/service_process_info.h
@@ -64,7 +64,13 @@ class CONTENT_EXPORT ServiceProcessInfo {
const std::optional<GURL>& site() const { return site_; }
const base::Process& GetProcess() const { return process_; }
+ void set_exit_code(int exit_code) { exit_code_ = exit_code; }
+ int exit_code() const { return exit_code_; }
+
private:
+ // The exit code of the process, if it has exited.
+ int exit_code_;
+
// The name of the service interface for which the process was launched.
std::string service_interface_name_;

View File

@@ -11,5 +11,8 @@
{ "patch_dir": "src/electron/patches/Mantle", "repo": "src/third_party/squirrel.mac/vendor/Mantle" },
{ "patch_dir": "src/electron/patches/ReactiveObjC", "repo": "src/third_party/squirrel.mac/vendor/ReactiveObjC" },
{ "patch_dir": "src/electron/patches/webrtc", "repo": "src/third_party/webrtc" },
{ "patch_dir": "src/electron/patches/reclient-configs", "repo": "src/third_party/engflow-reclient-configs" }
{ "patch_dir": "src/electron/patches/reclient-configs", "repo": "src/third_party/engflow-reclient-configs" },
{ "patch_dir": "src/electron/patches/libaom", "repo": "src/third_party/libaom/source/libaom" },
{ "patch_dir": "src/electron/patches/DirectXShaderCompiler", "repo": "src/third_party/dawn/third_party/dxc" },
{ "patch_dir": "src/electron/patches/dawn", "repo": "src/third_party/dawn" }
]

2
patches/dawn/.patches Normal file
View File

@@ -0,0 +1,2 @@
dawn_dxc_disable_dxc_pass_structurize-loop-exits-for-unroll.patch
deps_update_dxc_to_patched_branch.patch

View File

@@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Antonio Maiorano <amaiorano@google.com>
Date: Mon, 17 Jun 2024 18:33:47 +0000
Subject: dawn/dxc: disable DXC pass 'structurize-loop-exits-for-unroll'
Multiple security bugs have been reported related to this optimization pass, and after careful consideration, we have decided to disable it.
Bug: chromium:333508731
Bug: chromium:339171223
Bug: chromium:339169163
Bug: chromium:346595893
Change-Id: I5c9d7180ed09e7417c120595937bcb1013b6ce66
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/184422
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Natalie Chouinard <chouinard@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/194160
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/dawn/native/d3d/ShaderUtils.cpp b/src/dawn/native/d3d/ShaderUtils.cpp
index e1937ca2d5f9b84f3590c5cc3285850a06db5a5d..2d2d5dc49b971dc52ed39c29bb443e127e6d5166 100644
--- a/src/dawn/native/d3d/ShaderUtils.cpp
+++ b/src/dawn/native/d3d/ShaderUtils.cpp
@@ -58,6 +58,10 @@ std::vector<const wchar_t*> GetDXCArguments(std::wstring_view entryPointNameW,
arguments.push_back(L"-E");
arguments.push_back(entryPointNameW.data());
+ // TODO(chromium:346595893): Disable buggy DXC pass
+ arguments.push_back(L"-opt-disable");
+ arguments.push_back(L"structurize-loop-exits-for-unroll");
+
uint32_t compileFlags = r.compileFlags;
if (compileFlags & D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY) {
arguments.push_back(L"/Gec");

View File

@@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: David Neto <dneto@google.com>
Date: Wed, 17 Jul 2024 14:09:26 +0000
Subject: DEPS: Update DXC to patched branch
Also, add DXC_CODEGEN_EXCEPTIONS_TRAP=1 to DXC gn config.
Bug: chromium:346618785, chromium:350696474
Change-Id: I4c1ac753d824c4790e78d8f36231c8f2fe0e2722
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/198756
Reviewed-by: Natalie Chouinard <chouinard@google.com>
diff --git a/third_party/gn/dxc/BUILD.gn b/third_party/gn/dxc/BUILD.gn
index aadb64eeb4fba2f2da442a8a7f4b285a469c5cdd..0060484cefcf1835138b111258c33e09fab1279c 100644
--- a/third_party/gn/dxc/BUILD.gn
+++ b/third_party/gn/dxc/BUILD.gn
@@ -453,7 +453,10 @@ cmake_configure_file("clang-config-h") {
cmake_configure_file("dxc-config-h") {
input = "$dawn_dxc_dir/include/dxc/config.h.cmake"
output = "$target_gen_dir/include/dxc/config.h"
- values = [ "DXC_DISABLE_ALLOCATOR_OVERRIDES=1" ]
+ values = [
+ "DXC_DISABLE_ALLOCATOR_OVERRIDES=1",
+ "DXC_CODEGEN_EXCEPTIONS_TRAP=1",
+ ]
}
#######################################################################

2
patches/libaom/.patches Normal file
View File

@@ -0,0 +1,2 @@
update_codec_config_after_svc_scale_controls.patch
encode_api_test_add_repro_for_chromium_339877165.patch

View File

@@ -0,0 +1,162 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: James Zern <jzern@google.com>
Date: Thu, 16 May 2024 13:44:52 -0700
Subject: encode_api_test: add repro for chromium 339877165
BUG=chromium:339877165
Change-Id: I69dcc2cda098ec96a34e1e5f7ef557ee8caf5521
(cherry picked from commit 01467cdbd524900eed283660836179fd1b2cd536)
diff --git a/test/encode_api_test.cc b/test/encode_api_test.cc
index a7d5b3aa3c7dbcfce8e726fca1f1670ed878e53c..27bcbc14c14c4218d45e59e509fbe5fdbdc005bb 100644
--- a/test/encode_api_test.cc
+++ b/test/encode_api_test.cc
@@ -635,6 +635,147 @@ TEST(EncodeAPI, PtsOrDurationTooBig) {
aom_codec_destroy(&enc);
}
+// Reproduces https://crbug.com/339877165.
+TEST(EncodeAPI, Buganizer339877165) {
+ // Initialize libaom encoder.
+ aom_codec_iface_t *const iface = aom_codec_av1_cx();
+ aom_codec_ctx_t enc;
+ aom_codec_enc_cfg_t cfg;
+
+ ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_REALTIME),
+ AOM_CODEC_OK);
+
+ cfg.g_w = 2560;
+ cfg.g_h = 1600;
+ cfg.rc_target_bitrate = 231;
+ cfg.rc_end_usage = AOM_CBR;
+ cfg.g_threads = 8;
+
+ ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
+
+ // From libaom_av1_encoder.cc in WebRTC.
+ ASSERT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, 11), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_CDEF, 1), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_TPL_MODEL, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_DELTAQ_MODE, 0), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_ORDER_HINT, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_AQ_MODE, 3), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AOME_SET_MAX_INTRA_BITRATE_PCT, 300),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_COEFF_COST_UPD_FREQ, 3),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_MODE_COST_UPD_FREQ, 3),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_MV_COST_UPD_FREQ, 3),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_PALETTE, 1), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_ROWS, 1), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_COLUMNS, 2), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_OBMC, 0), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_NOISE_SENSITIVITY, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_WARPED_MOTION, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_GLOBAL_MOTION, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_REF_FRAME_MVS, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SUPERBLOCK_SIZE,
+ AOM_SUPERBLOCK_SIZE_DYNAMIC),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_CFL_INTRA, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_SMOOTH_INTRA, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_ANGLE_DELTA, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_FILTER_INTRA, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_INTRA_DEFAULT_TX_ONLY, 1),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_DISABLE_TRELLIS_QUANT, 1),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_DIST_WTD_COMP, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_DIFF_WTD_COMP, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_DUAL_FILTER, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTERINTRA_COMP, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTERINTRA_WEDGE, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTRA_EDGE_FILTER, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_INTRABC, 0), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_MASKED_COMP, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_PAETH_INTRA, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_QM, 0), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_RECT_PARTITIONS, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_RESTORATION, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_SMOOTH_INTERINTRA, 0),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_ENABLE_TX64, 0), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_MAX_REFERENCE_FRAMES, 3),
+ AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_enc_config_set(&enc, &cfg), AOM_CODEC_OK);
+
+ aom_svc_params_t svc_params = {};
+ svc_params.number_spatial_layers = 2;
+ svc_params.number_temporal_layers = 1;
+ svc_params.max_quantizers[0] = svc_params.max_quantizers[1] = 56;
+ svc_params.min_quantizers[0] = svc_params.min_quantizers[1] = 10;
+ svc_params.scaling_factor_num[0] = svc_params.scaling_factor_num[1] = 1;
+ svc_params.scaling_factor_den[0] = 2;
+ svc_params.scaling_factor_den[1] = 1;
+ svc_params.layer_target_bitrate[0] = cfg.rc_target_bitrate;
+ svc_params.framerate_factor[0] = 1;
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_PARAMS, &svc_params),
+ AOM_CODEC_OK);
+
+ aom_svc_layer_id_t layer_id = {};
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_LAYER_ID, &layer_id),
+ AOM_CODEC_OK);
+
+ aom_svc_ref_frame_config_t ref_frame_config = {};
+ ref_frame_config.refresh[0] = 1;
+ ASSERT_EQ(
+ aom_codec_control(&enc, AV1E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config),
+ AOM_CODEC_OK);
+
+ // Create input image.
+ aom_image_t *const image =
+ CreateGrayImage(AOM_IMG_FMT_I420, cfg.g_w, cfg.g_h);
+ ASSERT_NE(image, nullptr);
+
+ // Encode layer 0.
+ ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK);
+
+ layer_id.spatial_layer_id = 1;
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_LAYER_ID, &layer_id),
+ AOM_CODEC_OK);
+
+ ref_frame_config.refresh[0] = 0;
+ ASSERT_EQ(
+ aom_codec_control(&enc, AV1E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config),
+ AOM_CODEC_OK);
+
+ // Encode layer 1.
+ ASSERT_EQ(aom_codec_encode(&enc, image, 0, 1, 0), AOM_CODEC_OK);
+
+ // Free resources.
+ aom_img_free(image);
+ aom_codec_destroy(&enc);
+}
+
class EncodeAPIParameterized
: public testing::TestWithParam<std::tuple<
/*usage=*/unsigned int, /*speed=*/int, /*aq_mode=*/unsigned int>> {};

View File

@@ -0,0 +1,196 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: James Zern <jzern@google.com>
Date: Tue, 14 May 2024 17:54:10 -0700
Subject: update codec config after svc/scale controls
This ensures the encoder state/allocations stay in sync with scaling and
svc layer changes. In the SVC case, depending on the resolution,
differences in the chosen superblock size among layers may have caused a
crash. This was reproducible in WebRTC in screen content mode.
The fix is based on a change by Yuan Tong (tongyuan200097) [1]. It
refreshes the encoder config after AOME_SET_SCALEMODE,
AOME_SET_NUMBER_SPATIAL_LAYERS and AV1E_SET_SVC_PARAMS if no frames have
been encoded. AV1E_SET_SVC_PARAMS was missed in the original change.
[1]: https://aomedia-review.googlesource.com/c/aom/+/171941/2
Bug: chromium:339877165
Change-Id: Ib3d2a123b159898d7c7e19c81e89ff148920e1f1
(cherry picked from commit e42f4b1980bbbc772aa886d8b43a885461d7b89e)
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 2b6b1504e6245b44f7693612eda31bfe3a14c402..652c6eadef2911a1a54a14cd78fd064b801868f5 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -1609,37 +1609,42 @@ static aom_codec_err_t ctrl_get_baseline_gf_interval(aom_codec_alg_priv_t *ctx,
return AOM_CODEC_OK;
}
+static aom_codec_err_t update_encoder_cfg(aom_codec_alg_priv_t *ctx) {
+ set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
+ av1_check_fpmt_config(ctx->ppi, &ctx->oxcf);
+ bool is_sb_size_changed = false;
+ av1_change_config_seq(ctx->ppi, &ctx->oxcf, &is_sb_size_changed);
+ for (int i = 0; i < ctx->ppi->num_fp_contexts; i++) {
+ AV1_COMP *const cpi = ctx->ppi->parallel_cpi[i];
+ struct aom_internal_error_info *const error = cpi->common.error;
+ if (setjmp(error->jmp)) {
+ error->setjmp = 0;
+ return error->error_code;
+ }
+ error->setjmp = 1;
+ av1_change_config(cpi, &ctx->oxcf, is_sb_size_changed);
+ error->setjmp = 0;
+ }
+ if (ctx->ppi->cpi_lap != NULL) {
+ AV1_COMP *const cpi_lap = ctx->ppi->cpi_lap;
+ struct aom_internal_error_info *const error = cpi_lap->common.error;
+ if (setjmp(error->jmp)) {
+ error->setjmp = 0;
+ return error->error_code;
+ }
+ error->setjmp = 1;
+ av1_change_config(cpi_lap, &ctx->oxcf, is_sb_size_changed);
+ error->setjmp = 0;
+ }
+ return AOM_CODEC_OK;
+}
+
static aom_codec_err_t update_extra_cfg(aom_codec_alg_priv_t *ctx,
const struct av1_extracfg *extra_cfg) {
const aom_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg);
if (res == AOM_CODEC_OK) {
ctx->extra_cfg = *extra_cfg;
- set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
- av1_check_fpmt_config(ctx->ppi, &ctx->oxcf);
- bool is_sb_size_changed = false;
- av1_change_config_seq(ctx->ppi, &ctx->oxcf, &is_sb_size_changed);
- for (int i = 0; i < ctx->ppi->num_fp_contexts; i++) {
- AV1_COMP *const cpi = ctx->ppi->parallel_cpi[i];
- struct aom_internal_error_info *const error = cpi->common.error;
- if (setjmp(error->jmp)) {
- error->setjmp = 0;
- return error->error_code;
- }
- error->setjmp = 1;
- av1_change_config(cpi, &ctx->oxcf, is_sb_size_changed);
- error->setjmp = 0;
- }
- if (ctx->ppi->cpi_lap != NULL) {
- AV1_COMP *const cpi_lap = ctx->ppi->cpi_lap;
- struct aom_internal_error_info *const error = cpi_lap->common.error;
- if (setjmp(error->jmp)) {
- error->setjmp = 0;
- return error->error_code;
- }
- error->setjmp = 1;
- av1_change_config(cpi_lap, &ctx->oxcf, is_sb_size_changed);
- error->setjmp = 0;
- }
+ return update_encoder_cfg(ctx);
}
return res;
}
@@ -3610,11 +3615,23 @@ static aom_codec_err_t ctrl_set_scale_mode(aom_codec_alg_priv_t *ctx,
aom_scaling_mode_t *const mode = va_arg(args, aom_scaling_mode_t *);
if (mode) {
- const int res = av1_set_internal_size(
- &ctx->ppi->cpi->oxcf, &ctx->ppi->cpi->resize_pending_params,
- mode->h_scaling_mode, mode->v_scaling_mode);
- av1_check_fpmt_config(ctx->ppi, &ctx->ppi->cpi->oxcf);
- return (res == 0) ? AOM_CODEC_OK : AOM_CODEC_INVALID_PARAM;
+ AV1EncoderConfig *const oxcf =
+ ctx->ppi->seq_params_locked ? &ctx->ppi->cpi->oxcf : &ctx->oxcf;
+ const int res =
+ av1_set_internal_size(oxcf, &ctx->ppi->cpi->resize_pending_params,
+ mode->h_scaling_mode, mode->v_scaling_mode);
+ if (res == 0) {
+ // update_encoder_cfg() is somewhat costly and this control may be called
+ // multiple times, so update_encoder_cfg() is only called to ensure frame
+ // and superblock sizes are updated before they're fixed by the first
+ // encode call.
+ if (ctx->ppi->seq_params_locked) {
+ av1_check_fpmt_config(ctx->ppi, &ctx->ppi->cpi->oxcf);
+ return AOM_CODEC_OK;
+ }
+ return update_encoder_cfg(ctx);
+ }
+ return AOM_CODEC_INVALID_PARAM;
} else {
return AOM_CODEC_INVALID_PARAM;
}
@@ -3635,6 +3652,13 @@ static aom_codec_err_t ctrl_set_number_spatial_layers(aom_codec_alg_priv_t *ctx,
if (number_spatial_layers > MAX_NUM_SPATIAL_LAYERS)
return AOM_CODEC_INVALID_PARAM;
ctx->ppi->number_spatial_layers = number_spatial_layers;
+ // update_encoder_cfg() is somewhat costly and this control may be called
+ // multiple times, so update_encoder_cfg() is only called to ensure frame and
+ // superblock sizes are updated before they're fixed by the first encode
+ // call.
+ if (!ctx->ppi->seq_params_locked) {
+ return update_encoder_cfg(ctx);
+ }
return AOM_CODEC_OK;
}
@@ -3652,8 +3676,6 @@ static aom_codec_err_t ctrl_set_svc_params(aom_codec_alg_priv_t *ctx,
va_list args) {
AV1_PRIMARY *const ppi = ctx->ppi;
AV1_COMP *const cpi = ppi->cpi;
- AV1_COMMON *const cm = &cpi->common;
- AV1EncoderConfig *oxcf = &cpi->oxcf;
aom_svc_params_t *const params = va_arg(args, aom_svc_params_t *);
int64_t target_bandwidth = 0;
ppi->number_spatial_layers = params->number_spatial_layers;
@@ -3693,19 +3715,38 @@ static aom_codec_err_t ctrl_set_svc_params(aom_codec_alg_priv_t *ctx,
target_bandwidth += lc->layer_target_bitrate;
}
}
- if (cm->current_frame.frame_number == 0) {
- if (!cpi->ppi->seq_params_locked) {
- SequenceHeader *const seq_params = &ppi->seq_params;
- seq_params->operating_points_cnt_minus_1 =
- ppi->number_spatial_layers * ppi->number_temporal_layers - 1;
- av1_init_seq_coding_tools(ppi, &cpi->oxcf, 1);
- }
+
+ if (ppi->seq_params_locked) {
+ AV1EncoderConfig *const oxcf = &cpi->oxcf;
+ // Keep ctx->oxcf in sync in case further codec controls are made prior
+ // to encoding.
+ ctx->oxcf.rc_cfg.target_bandwidth = oxcf->rc_cfg.target_bandwidth =
+ target_bandwidth;
+ set_primary_rc_buffer_sizes(oxcf, ppi);
+ av1_update_layer_context_change_config(cpi, target_bandwidth);
+ check_reset_rc_flag(cpi);
+ } else {
+ // Note av1_init_layer_context() relies on cpi->oxcf. The order of that
+ // call and the ones in the other half of this block (which
+ // update_encoder_cfg() transitively makes) is important. So we keep
+ // ctx->oxcf and cpi->oxcf in sync here as update_encoder_cfg() will
+ // overwrite cpi->oxcf with ctx->oxcf.
+ ctx->oxcf.rc_cfg.target_bandwidth = cpi->oxcf.rc_cfg.target_bandwidth =
+ target_bandwidth;
+ SequenceHeader *const seq_params = &ppi->seq_params;
+ seq_params->operating_points_cnt_minus_1 =
+ ppi->number_spatial_layers * ppi->number_temporal_layers - 1;
+
av1_init_layer_context(cpi);
+ // update_encoder_cfg() is somewhat costly and this control may be called
+ // multiple times, so update_encoder_cfg() is only called to ensure frame
+ // and superblock sizes are updated before they're fixed by the first
+ // encode call.
+ return update_encoder_cfg(ctx);
}
- oxcf->rc_cfg.target_bandwidth = target_bandwidth;
- set_primary_rc_buffer_sizes(oxcf, cpi->ppi);
- av1_update_layer_context_change_config(cpi, target_bandwidth);
- check_reset_rc_flag(cpi);
+ } else if (!ppi->seq_params_locked) {
+ // Ensure frame and superblock sizes are updated.
+ return update_encoder_cfg(ctx);
}
av1_check_fpmt_config(ctx->ppi, &ctx->ppi->cpi->oxcf);
return AOM_CODEC_OK;

View File

@@ -13,7 +13,6 @@ fix_account_for_debugger_agent_race_condition.patch
fix_readbarrier_undefined_symbol_error_on_woa_arm64.patch
fix_suppress_clang_-wdeprecated-declarations_in_libuv.patch
fix_serdes_test.patch
feat_add_knostartdebugsignalhandler_to_environment_to_prevent.patch
feat_add_uv_loop_interrupt_on_io_change_option_to_uv_loop_configure.patch
support_v8_sandboxed_pointers.patch
build_ensure_native_module_compilation_fails_if_not_using_a_new.patch
@@ -33,7 +32,6 @@ fix_assert_module_in_the_renderer_process.patch
fix_add_trusted_space_and_trusted_lo_space_to_the_v8_heap.patch
win_process_avoid_assert_after_spawning_store_app_4152.patch
chore_remove_use_of_deprecated_kmaxlength.patch
feat_optionally_prevent_calling_v8_enablewebassemblytraphandler.patch
build_only_create_cppgc_heap_on_non-32_bit_platforms.patch
src_update_default_v8_platform_to_override_functions_with_location.patch
fix_capture_embedder_exceptions_before_entering_v8.patch
@@ -43,3 +41,6 @@ test_match_wpt_streams_transferable_transform-stream-members_any_js.patch
build_ensure_v8_pointer_compression_sandbox_is_enabled_on_64bit.patch
fix_revert_src_lb_reducing_c_calls_of_esm_legacy_main_resolve.patch
deprecate_vector_v8_local_in_v8.patch
src_account_for_openssl_unexpected_version.patch
windows_32bit_config_change_callback_needs_to_be_stdcall.patch
fix_building_with_unicode.patch

View File

@@ -537,10 +537,10 @@ index 0e69d7383762f6b81c5b57698aa9d121d5a9c401..35bbeb37acc7ccb14b4b8a644ec3d4c7
cflags_c = [
"-mavx512vl",
diff --git a/deps/cares/BUILD.gn b/deps/cares/BUILD.gn
index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..3f253daee0f9b1faa50857f61d76de001bd8947e 100644
index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..087e27424f3997575e4e089a57955d04b8802321 100644
--- a/deps/cares/BUILD.gn
+++ b/deps/cares/BUILD.gn
@@ -1,14 +1,163 @@
@@ -1,14 +1,170 @@
-##############################################################################
-# #
-# DO NOT EDIT THIS FILE! #
@@ -582,6 +582,8 @@ index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..3f253daee0f9b1faa50857f61d76de00
+ "src/lib/ares__htable_strvp.h",
+ "src/lib/ares__htable_szvp.c",
+ "src/lib/ares__htable_szvp.h",
+ "src/lib/ares__htable_vpvp.c",
+ "src/lib/ares__htable_vpvp.h",
+ "src/lib/ares__iface_ips.c",
+ "src/lib/ares__iface_ips.h",
+ "src/lib/ares__llist.c",
@@ -607,6 +609,7 @@ index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..3f253daee0f9b1faa50857f61d76de00
+ "src/lib/ares_dns_record.c",
+ "src/lib/ares_dns_private.h",
+ "src/lib/ares_dns_write.c",
+ "src/lib/ares_event_configchg.c",
+ "src/lib/ares_event.h",
+ "src/lib/ares_event_win32.h",
+ "src/lib/ares_event_epoll.c",
@@ -711,7 +714,11 @@ index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..3f253daee0f9b1faa50857f61d76de00
-cares_gn_build("cares") {
+ if (is_mac) {
+ include_dirs += [ "config/darwin" ]
+ sources += [ "config/darwin/ares_config.h" ]
+ sources += [
+ "config/darwin/ares_config.h",
+ "src/lib/ares_sysconfig_mac.c",
+ "src/lib/thirdparty/apple/dnsinfo.h",
+ ]
+ }
}
diff --git a/deps/googletest/BUILD.gn b/deps/googletest/BUILD.gn
@@ -1256,10 +1263,10 @@ index 0000000000000000000000000000000000000000..af9cbada10203b387fb9732b346583b1
+}
diff --git a/filenames.json b/filenames.json
new file mode 100644
index 0000000000000000000000000000000000000000..d18a59b6629849588e31f977e8d537ff5b11f7e4
index 0000000000000000000000000000000000000000..7fed188f922a6754907411046ba4a977049394ea
--- /dev/null
+++ b/filenames.json
@@ -0,0 +1,738 @@
@@ -0,0 +1,740 @@
+// This file is automatically generated by generate_gn_filenames_json.py
+// DO NOT EDIT
+{
@@ -1846,6 +1853,7 @@ index 0000000000000000000000000000000000000000..d18a59b6629849588e31f977e8d537ff
+ "src/permission/fs_permission.cc",
+ "src/permission/inspector_permission.cc",
+ "src/permission/permission.cc",
+ "src/permission/wasi_permission.cc",
+ "src/permission/worker_permission.cc",
+ "src/pipe_wrap.cc",
+ "src/process_wrap.cc",
@@ -1967,6 +1975,7 @@ index 0000000000000000000000000000000000000000..d18a59b6629849588e31f977e8d537ff
+ "src/permission/fs_permission.h",
+ "src/permission/inspector_permission.h",
+ "src/permission/permission.h",
+ "src/permission/wasi_permission.h",
+ "src/permission/worker_permission.h",
+ "src/pipe_wrap.h",
+ "src/req_wrap.h",

View File

@@ -40,10 +40,10 @@ index 9a27610992612b59eadcc8e481683cf1e6a5dbb6..1fad20645d059ad5f3efaa9279f582f9
# list in v8/BUILD.gn.
['v8_enable_v8_checks == 1', {
diff --git a/configure.py b/configure.py
index 11c0df455451d4ab4bea066a8361246cbf10bf1d..c30052f02f97df78e0d9294784cb3efb3fd2d1a7 100755
index f189ba2bf09fc248b3c1ce3c3535b939a4160ad2..2c24db93618f88f5f07e95a3edf63fb7942ac009 100755
--- a/configure.py
+++ b/configure.py
@@ -1501,6 +1501,7 @@ def configure_library(lib, output, pkgname=None):
@@ -1559,6 +1559,7 @@ def configure_library(lib, output, pkgname=None):
def configure_v8(o):

View File

@@ -22,10 +22,10 @@ index 1fad20645d059ad5f3efaa9279f582f99cb1006b..4fbb33550e8a044b92997a42eb6603f1
['target_arch in "ppc64 s390x"', {
'v8_enable_backtrace': 1,
diff --git a/configure.py b/configure.py
index c30052f02f97df78e0d9294784cb3efb3fd2d1a7..5fb89e56fde52d01b3806ec4e8549cbeb5ffca66 100755
index 2c24db93618f88f5f07e95a3edf63fb7942ac009..4e6dc7378e4435b90246eb072379cea1bfdad09c 100755
--- a/configure.py
+++ b/configure.py
@@ -1515,6 +1515,7 @@ def configure_v8(o):
@@ -1573,6 +1573,7 @@ def configure_v8(o):
o['variables']['v8_use_siphash'] = 0 if options.without_siphash else 1
o['variables']['v8_enable_maglev'] = 1 if options.v8_enable_maglev else 0
o['variables']['v8_enable_pointer_compression'] = 1 if options.enable_pointer_compression else 0

View File

@@ -33,10 +33,10 @@ index 7d201bb6b822f0401c3be2bc52d65bc71463748b..38f4b5afb9e667f0958008847224fa7a
node_platform = "win32"
} else if (target_os == "mac") {
diff --git a/src/env.cc b/src/env.cc
index 5c75e5b99d9415163640ab90f5891c0fee067a88..5f8bb37d117d82123b81f5f4b32735150184fa74 100644
index ea0ae4e08ec7dd98721bc89d2fe80fa47eaddfec..cad55dc4458cc64d701b53975f817b1552660d73 100644
--- a/src/env.cc
+++ b/src/env.cc
@@ -557,7 +557,8 @@ IsolateData::IsolateData(Isolate* isolate,
@@ -569,7 +569,8 @@ IsolateData::IsolateData(Isolate* isolate,
// for embedder ID, V8 could accidentally enable cppgc on them. So
// safe guard against this.
DCHECK_NE(descriptor.wrappable_type_index, BaseObject::kSlot);
@@ -46,7 +46,7 @@ index 5c75e5b99d9415163640ab90f5891c0fee067a88..5f8bb37d117d82123b81f5f4b3273515
cpp_heap_ = CppHeap::Create(
platform,
CppHeapCreateParams{
@@ -565,6 +566,7 @@ IsolateData::IsolateData(Isolate* isolate,
@@ -577,6 +578,7 @@ IsolateData::IsolateData(Isolate* isolate,
WrapperDescriptor(
BaseObject::kEmbedderType, BaseObject::kSlot, cppgc_id)});
isolate->AttachCppHeap(cpp_heap_.get());

View File

@@ -26,7 +26,7 @@ index 155485dbab0d46bb225fa40e99f555d805659c4f..8183cffe9d7060571c08f696abb7c090
try {
resolvedArgv = Module._resolveFilename(process.argv[1], null, false);
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
index 16e291484bfe85d5614557f070ab0d2ae59655d4..b4272f01e84d7fec263dcad444d92459743780a8 100644
index 8fad2fe617e4f8d2364b8c9d3cfb27c265f08b5b..710af646aaf97f88ac2ee003d8f83388ccf9a84f 100644
--- a/lib/internal/process/pre_execution.js
+++ b/lib/internal/process/pre_execution.js
@@ -244,12 +244,14 @@ function patchProcessObject(expandArgv1) {

View File

@@ -45,10 +45,10 @@ index f995c170540ffaa80b1b5f8b95dbd8f52bbd5431..6455dbdd015477e16c414b6d21131393
fixtures.path(name),
transform ?? defaultTransform,
diff --git a/test/parallel/test-node-output-errors.mjs b/test/parallel/test-node-output-errors.mjs
index c0acee2bfc8c124e9d9b254041589a49c8301b8f..0e266899ffc0918b2f94e8f636043a6ec5f0870f 100644
index 84f20a77dda367fe1ada8d616c7b6813d39efd43..27d16d74884a006ba01b777f5a20339b4906197b 100644
--- a/test/parallel/test-node-output-errors.mjs
+++ b/test/parallel/test-node-output-errors.mjs
@@ -61,21 +61,22 @@ describe('errors output', { concurrency: true }, () => {
@@ -59,21 +59,22 @@ describe('errors output', { concurrency: true }, () => {
{ name: 'errors/events_unhandled_error_subclass.js', transform: errTransform },
{ name: 'errors/if-error-has-good-stack.js', transform: errTransform },
{ name: 'errors/throw_custom_error.js', transform: errTransform },
@@ -69,11 +69,11 @@ index c0acee2bfc8c124e9d9b254041589a49c8301b8f..0e266899ffc0918b2f94e8f636043a6e
- { skip: skipForceColors, name: 'errors/force_colors.js',
- transform: forceColorsTransform, env: { FORCE_COLOR: 1 } },
+ // { skip: skipForceColors, name: 'errors/force_colors.js',
+ // transform: forceColorsTransform, env: { FORCE_COLOR: 1 } },
+ // transform: forceColorsTransform, env: { FORCE_COLOR: 1 } },
];
for (const { name, transform = defaultTransform, env, skip = false } of tests) {
it(name, { skip }, async () => {
+ if (env) env.ELECTRON_RUN_AS_NODE = 1;
await snapshot.spawnAndAssert(fixtures.path(name), transform, { env });
await snapshot.spawnAndAssert(fixtures.path(name), transform, { env: { ...env, ...process.env } });
});
}

View File

@@ -8,7 +8,7 @@ to child processes spawned with `ELECTRON_RUN_AS_NODE` which is used
by the crashpad client to connect with the handler process.
diff --git a/lib/child_process.js b/lib/child_process.js
index c09fca512584ce2c674ae1d05136ff4cd8ea8471..3947e231f4e641b97d12c9639a736fab8836787b 100644
index c09fca512584ce2c674ae1d05136ff4cd8ea8471..d4edaa71a7bf6660bad209fbfbc43014bb4bf741 100644
--- a/lib/child_process.js
+++ b/lib/child_process.js
@@ -61,6 +61,7 @@ let debug = require('internal/util/debuglog').debuglog(
@@ -27,25 +27,34 @@ index c09fca512584ce2c674ae1d05136ff4cd8ea8471..3947e231f4e641b97d12c9639a736fab
args = [...execArgv, modulePath, ...args];
if (typeof options.stdio === 'string') {
@@ -617,6 +617,21 @@ function normalizeSpawnArguments(file, args, options) {
@@ -617,6 +617,22 @@ function normalizeSpawnArguments(file, args, options) {
'options.windowsVerbatimArguments');
}
+ if (process.platform === 'linux') {
+ if (ObjectPrototypeHasOwnProperty(options.env || process.env, 'ELECTRON_RUN_AS_NODE') &&
+ (file === process.execPath)) {
+ // On Linux, pass the file descriptor which crashpad handler process
+ // uses to monitor the child process and PID of the handler process.
+ // https://source.chromium.org/chromium/chromium/src/+/110.0.5415.0:components/crash/core/app/crashpad_linux.cc;l=199-206
+ const fd = getCrashdumpSignalFD();
+ const pid = getCrashpadHandlerPID();
+ if (fd !== -1 && pid !== -1) {
+ options.env.CRASHDUMP_SIGNAL_FD = fd;
+ options.env.CRASHPAD_HANDLER_PID = pid;
+ }
+ const env = options.env || process.env;
+
+ if ((process.platform === 'linux') &&
+ ObjectPrototypeHasOwnProperty(env, 'ELECTRON_RUN_AS_NODE') &&
+ (file === process.execPath)) {
+ // On Linux, pass the file descriptor which crashpad handler process
+ // uses to monitor the child process and PID of the handler process.
+ // https://source.chromium.org/chromium/chromium/src/+/110.0.5415.0:components/crash/core/app/crashpad_linux.cc;l=199-206
+ const fd = getCrashdumpSignalFD();
+ const pid = getCrashpadHandlerPID();
+ if (fd !== -1 && pid !== -1) {
+ env.CRASHDUMP_SIGNAL_FD = fd;
+ env.CRASHPAD_HANDLER_PID = pid;
+ }
+ }
+
if (options.shell) {
validateArgumentNullCheck(options.shell, 'options.shell');
const command = ArrayPrototypeJoin([file, ...args], ' ');
@@ -650,7 +666,6 @@ function normalizeSpawnArguments(file, args, options) {
ArrayPrototypeUnshift(args, file);
}
- const env = options.env || process.env;
const envPairs = [];
// process.env.NODE_V8_COVERAGE always propagates, making it possible to

View File

@@ -1,69 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <samuel.r.attard@gmail.com>
Date: Mon, 7 Mar 2022 16:36:28 -0800
Subject: feat: add kNoStartDebugSignalHandler to Environment to prevent
SIGUSR1 handling
This patch should be upstreamed, it allows embedders to prevent the call to StartDebugSignalHandler which handles SIGUSR1 and starts the inspector agent. Apps that have --inspect disabled also don't want SIGUSR1 to have this affect.
diff --git a/src/env-inl.h b/src/env-inl.h
index 099e7352e68af6179f143741c626d8f539b568bb..63ce35ba68b48a55d8150395304bf86c2bf23aae 100644
--- a/src/env-inl.h
+++ b/src/env-inl.h
@@ -677,6 +677,10 @@ inline bool Environment::no_global_search_paths() const {
!options_->global_search_paths;
}
+inline bool Environment::should_start_debug_signal_handler() const {
+ return (flags_ & EnvironmentFlags::kNoStartDebugSignalHandler) == 0;
+}
+
inline bool Environment::no_browser_globals() const {
// configure --no-browser-globals
#ifdef NODE_NO_BROWSER_GLOBALS
diff --git a/src/env.h b/src/env.h
index c0c99456471788d40218152291a32db5fbdf1101..910c69b6d1d17ef25201dbb39d3d074f4f3f011f 100644
--- a/src/env.h
+++ b/src/env.h
@@ -801,6 +801,7 @@ class Environment : public MemoryRetainer {
inline bool tracks_unmanaged_fds() const;
inline bool hide_console_windows() const;
inline bool no_global_search_paths() const;
+ inline bool should_start_debug_signal_handler() const;
inline bool no_browser_globals() const;
inline uint64_t thread_id() const;
inline worker::Worker* worker_context() const;
diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc
index 63c8ae14abb3dee3c4a628d1042c2e9e25688806..4e1eb17dd174e18a814fce6b170d75d161937ace 100644
--- a/src/inspector_agent.cc
+++ b/src/inspector_agent.cc
@@ -717,8 +717,10 @@ bool Agent::Start(const std::string& path,
StartIoThreadAsyncCallback));
uv_unref(reinterpret_cast<uv_handle_t*>(&start_io_thread_async));
start_io_thread_async.data = this;
- // Ignore failure, SIGUSR1 won't work, but that should not block node start.
- StartDebugSignalHandler();
+ if (parent_env_->should_start_debug_signal_handler()) {
+ // Ignore failure, SIGUSR1 won't work, but that should not block node start.
+ StartDebugSignalHandler();
+ }
parent_env_->AddCleanupHook([](void* data) {
Environment* env = static_cast<Environment*>(data);
diff --git a/src/node.h b/src/node.h
index 24dd1d9fe8de5993863f9fcd0ce7f65ec5460cce..c267ed1eeaa2d8b6ecd5a1563a4e9440bf0cca00 100644
--- a/src/node.h
+++ b/src/node.h
@@ -658,7 +658,11 @@ enum Flags : uint64_t {
// This control is needed by embedders who may not want to initialize the V8
// inspector in situations where one has already been created,
// e.g. Blink's in Chromium.
- kNoCreateInspector = 1 << 9
+ kNoCreateInspector = 1 << 9,
+ // Controls where or not the InspectorAgent for this Environment should
+ // call StartDebugSignalHandler. This control is needed by embedders who may
+ // not want to allow other processes to start the V8 inspector.
+ kNoStartDebugSignalHandler = 1 << 10
};
} // namespace EnvironmentFlags

View File

@@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Thu, 16 Nov 2023 16:48:10 +0100
Subject: feat: optionally prevent calling V8::EnableWebAssemblyTrapHandler
V8::EnableWebAssemblyTrapHandler can be called only once or it will
hard crash. We need to prevent Node.js calling it in the event it has
already been called.
This should be upstreamed.
diff --git a/src/node.cc b/src/node.cc
index 3e4f1b5d730865fae61f8bfbc58c14c6a59fb33a..7478ef81eb9b275eb5f45b528582e5bbd30e60ec 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -650,6 +650,7 @@ static void PlatformInit(ProcessInitializationFlags::Flags flags) {
#endif
}
#endif // defined(_WIN32)
+ if (!(flags & ProcessInitializationFlags::kNoEnableWasmTrapHandler))
V8::EnableWebAssemblyTrapHandler(false);
#endif // NODE_USE_V8_WASM_TRAP_HANDLER
}
diff --git a/src/node.h b/src/node.h
index e55256996f2c85b0ae3854cbd1b83ca88a3e22cb..76e2459eceed127e69c686f26fd5bd369b81f1af 100644
--- a/src/node.h
+++ b/src/node.h
@@ -275,6 +275,10 @@ enum Flags : uint32_t {
kNoInitializeCppgc = 1 << 13,
// Initialize the process for predictable snapshot generation.
kGeneratePredictableSnapshot = 1 << 14,
+ // Do not initialize the Web Assembly trap handler. This is used by
+ // embedders to account for the case where it may already have been
+ // initialized - calling it more than once will hard crash.
+ kNoEnableWasmTrapHandler = 1 << 15,
// Emulate the behavior of InitializeNodeWithArgs() when passing
// a flags argument to the InitializeOncePerProcess() replacement

View File

@@ -28,7 +28,7 @@ In file included from ../../third_party/electron_node/src/env-inl.h:32:
1 error generated.
diff --git a/src/util.h b/src/util.h
index cd4fe2e422a7843f5a3f0f4b336a8625a0b24bcf..8edd50e598d8612144b8da9236e63f9079b99156 100644
index 3ae876e5484f0ebacfae6749cc336f42cd69bf14..8e9e8289de249119d6b8078abe32db6b885dfaab 100644
--- a/src/util.h
+++ b/src/util.h
@@ -146,9 +146,9 @@ void DumpJavaScriptBacktrace(FILE* fp);

View File

@@ -58,10 +58,10 @@ index f9d29f0065b1de63a62cfdce74a9705c22dd87d7..3f44160f1bd40fc2d4658f10edf0d0b3
}
diff --git a/src/node_options.cc b/src/node_options.cc
index dae3237abc95362db81a1f529becfac43454d709..ee8e6f342bf4956c5f186337b6c051e1d62a6dcd 100644
index 28fbd93c5d4a6f379844e10e556920b7614910d8..53cf93719bea001db09697b56f197815549dc953 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -1301,6 +1301,11 @@ void GetEmbedderOptions(const FunctionCallbackInfo<Value>& args) {
@@ -1321,6 +1321,11 @@ void GetEmbedderOptions(const FunctionCallbackInfo<Value>& args) {
Local<Context> context = env->context();
Local<Object> ret = Object::New(isolate);

View File

@@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Keeley Hammond <khammond@slack-corp.com>
Date: Thu, 25 Jul 2024 15:29:12 -0700
Subject: fix: building with UNICODE
Use the unicode version of 'RegOpenKeyEx' to avoid compilation error on string type.
Backport of https://github.com/c-ares/c-ares/pull/802.
diff --git a/deps/cares/src/lib/ares_event_configchg.c b/deps/cares/src/lib/ares_event_configchg.c
index c9b39f7b3358f37e61fb95e440695a9b590c2090..b33141ce3a30dd92509de8a4aff1a7fc76a5b915 100644
--- a/deps/cares/src/lib/ares_event_configchg.c
+++ b/deps/cares/src/lib/ares_event_configchg.c
@@ -319,15 +319,15 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg,
/* Monitor HKLM\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\Interfaces
* and HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces
* for changes via RegNotifyChangeKeyValue() */
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces",
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces",
0, KEY_NOTIFY, &c->regip4) != ERROR_SUCCESS) {
status = ARES_ESERVFAIL;
goto done;
}
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- "SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters\\Interfaces",
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters\\Interfaces",
0, KEY_NOTIFY, &c->regip6) != ERROR_SUCCESS) {
status = ARES_ESERVFAIL;
goto done;

View File

@@ -24,7 +24,7 @@ index 69e2a389f9e1480a1a4ba37f5df5356b42f7d52d..0c29b00298b44b97f88a63aa5b89f1c2
wrap->object()->Has(env->context(), env->handle_onclose_symbol())
.FromMaybe(false)) {
diff --git a/src/node_contextify.cc b/src/node_contextify.cc
index ca8575e9a21b9a0b8089484a04abe702b2fe6d4e..df1d9cb4fd0442ec6ce6164a136b7a5fbcbe5b67 100644
index d873792ab95e41d54579f552c6c1fa43447ca4cd..708fa03d088e67a50dc4e69bb3f2cc14529dc3f1 100644
--- a/src/node_contextify.cc
+++ b/src/node_contextify.cc
@@ -460,6 +460,7 @@ bool ContextifyContext::IsStillInitializing(const ContextifyContext* ctx) {

View File

@@ -31,7 +31,7 @@ index 4e3c32fdcd23fbe3e74bd5e624b739d224689f33..19d65aae7fa8ec9f9b907733ead17a20
// Test Parallel Execution w/ KeyObject is threadsafe in openssl3
{
diff --git a/test/parallel/test-crypto-authenticated.js b/test/parallel/test-crypto-authenticated.js
index 6178445adbc634160c3c3ca699a36868f894e544..ff4dc2f7d527b5eb1fa442ba6b0f9ba04af39357 100644
index 59dd3b69c4bdf6dbd7b5e4f03df74caac551d459..1e0f9ce4c979683530afdf83ac3dc095acad2eb8 100644
--- a/test/parallel/test-crypto-authenticated.js
+++ b/test/parallel/test-crypto-authenticated.js
@@ -48,7 +48,9 @@ const errMessages = {
@@ -381,7 +381,7 @@ index fcf1922bcdba733af6c22f142db4f7b099947757..9f72ae4e41a113e752f40795103c2af5
assert.throws(() => crypto.createDiffieHellman('abcdef', g), ex);
assert.throws(() => crypto.createDiffieHellman('abcdef', 'hex', g), ex);
diff --git a/test/parallel/test-crypto-dh.js b/test/parallel/test-crypto-dh.js
index 3b738b7f47ec59ba718a92e3a0024fed45a9c87c..fabf5775a263804f5974b10cf73c6886d59bf1fa 100644
index fb580e1b315445182538c56fc114742ce896bf4c..36014fe7cb411016d72a7f4ab118923d12e97898 100644
--- a/test/parallel/test-crypto-dh.js
+++ b/test/parallel/test-crypto-dh.js
@@ -55,18 +55,17 @@ const crypto = require('crypto');
@@ -549,7 +549,7 @@ index 1785f5eef3d202976666081d09850ed744d83446..e88227a215ba4f7fa196f7642ae694a5
});
diff --git a/test/parallel/test-crypto-rsa-dsa.js b/test/parallel/test-crypto-rsa-dsa.js
index ecda345989789d0745b631385e7411305c1c6375..542a0a16f3f2eba4efd31e807a3bc34b6752d798 100644
index 5f4fafdfffbf726b7cb39c472baa3df25c9794cf..73bb53b0405b20f51b13326cc70e52755c674366 100644
--- a/test/parallel/test-crypto-rsa-dsa.js
+++ b/test/parallel/test-crypto-rsa-dsa.js
@@ -28,12 +28,11 @@ const dsaPkcs8KeyPem = fixtures.readKey('dsa_private_pkcs8.pem');
@@ -577,10 +577,10 @@ index ecda345989789d0745b631385e7411305c1c6375..542a0a16f3f2eba4efd31e807a3bc34b
- if (padding === constants.RSA_PKCS1_PADDING) {
+ // BoringSSL does not support RSA_PKCS1_PADDING.
+ if (false) {
// TODO(richardlau): see if it's possible to determine implicit rejection
// support when dynamically linked against OpenSSL.
if (!process.config.variables.node_shared_openssl) {
@@ -419,7 +419,7 @@ assert.throws(() => {
assert.throws(() => {
crypto.privateDecrypt({
@@ -466,7 +466,7 @@ assert.throws(() => {
assert.strictEqual(verify2.verify(publicKey, signature, 'hex'), true);
}
@@ -589,11 +589,24 @@ index ecda345989789d0745b631385e7411305c1c6375..542a0a16f3f2eba4efd31e807a3bc34b
//
// Test DSA signing and verification
//
@@ -494,3 +494,4 @@ const input = 'I AM THE WALRUS';
@@ -541,3 +541,4 @@ const input = 'I AM THE WALRUS';
assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true);
}
+*/
diff --git a/test/parallel/test-crypto-scrypt.js b/test/parallel/test-crypto-scrypt.js
index 61bd65fc92678c24baa3c0eb9ffb1ead64ace70b..cb690351696a811210b9d990ee4cde3cfb2a3446 100644
--- a/test/parallel/test-crypto-scrypt.js
+++ b/test/parallel/test-crypto-scrypt.js
@@ -178,7 +178,7 @@ for (const options of bad) {
for (const options of toobig) {
const expected = {
- message: /Invalid scrypt params:.*memory limit exceeded/,
+ message: /Invalid scrypt params/,
code: 'ERR_CRYPTO_INVALID_SCRYPT_PARAMS',
};
assert.throws(() => crypto.scrypt('pass', 'salt', 1, options, () => {}),
diff --git a/test/parallel/test-crypto-sign-verify.js b/test/parallel/test-crypto-sign-verify.js
index 56e5c16c2867f019caccf42f228193cae6167150..dc585c44db9894ae57a5e11d453af03e1ea4f211 100644
--- a/test/parallel/test-crypto-sign-verify.js

View File

@@ -48,7 +48,7 @@ index 5239bc8ed883a54df206d73c5dc0b70942c4f3df..6a15fcae677b3bda58fc85f705862bbc
ArrayPrototypePush(schemes, 'https', 'http');
}
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
index b56ad6cc833f00f58bf3925e9fd82a8f5b7b9bd7..8c9e8bfb4e828d044b236a11c0890cb4f0161050 100644
index e73a8ad60a13925d6773c32cead8d04ec9d96ee7..52cdb7d5e14a18ed7b1b65e429729cf47dce3f98 100644
--- a/lib/internal/modules/esm/resolve.js
+++ b/lib/internal/modules/esm/resolve.js
@@ -741,6 +741,8 @@ function packageImportsResolve(name, base, conditions) {

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