Remove our implementation of the scripting api and use upstream's
version. It was recently moved to `extensions/` by
https://chromium-review.googlesource.com/c/chromium/src/+/7784831,
so we link it directly.
Update `ElectronExtensionsBrowserClient` to overrides `IsValidTabId()`
and `GetScriptExecutorForTab()` to provide tab validation and
script-executor hooks.
Remove now-redundant local copy of `scripting.idl`.
Upstream now provides everything we used this for.
Updated breaking-changes.md to document a CSS matching difference.
Co-authored-by: GitHub Copilot <github-copilot[bot]@users.noreply.github.com>
The `<geolocation>` HTML element looks up IDS_PERMISSION_REQUEST_GEOLOCATION
via ResourceBundle::GetLocalizedString(). These string IDs are defined in
third_party/blink/public/strings/permission_element_strings.grd.
Electron didn't include that in its pak file, causing CHECK(!data->empty()).
Ths PR adds the per-locale permission_element_strings paks and the
aggregated permission_element_generated_strings pak to electron_paks.gni.
This matches how it's done in `chrome/chrome_repack_locales.gni` and
in `chrome/chrome_paks.gni`.
Xref: https://chromium-review.googlesource.com/c/chromium/src/+/5907626
* fix: use the non-pass-through path for Fetch-intercepted requests
* Revert "fix: use the non-pass-through path for Fetch-intercepted requests"
This reverts commit 395fb8bb8c.
* fix: use no-op header client for Fetch-intercepted requests
* fix: bring back `DCHECK` that was prematurely removed
* style: reformat code
Replace ClientFrameViewLinux with electron::NativeFrameViewLinux, a thin
wrapper over views::NativeFrameViewLinux. The wrapper provides Electron
integration, such as draggable region support in NonClientHitTest,
and adapting to Electron's sizing conventions.
ElectronDesktopWindowTreeHostLinux and NativeWindowViews now use
FrameViewLinux to query frame geometry and update window states in
addition to LinuxFrameLayout.
Assisted-By: Claude Opus 4.6, Claude Code
The postinstall script resolves two things from the target platform:
1. Which artifact to download, via `downloadArtifact({ platform, ... })`.
Since #49981, `platform` is derived from
`ELECTRON_INSTALL_PLATFORM || npm_config_platform || process.platform`.
2. Which executable path to use for the `isInstalled()` cache check and
for the `path.txt` marker written after extraction, via
`getPlatformPath()`.
`getPlatformPath()` was not updated with the rest of that change and
still falls back to `npm_config_platform || os.platform()` only.
As a result, passing `ELECTRON_INSTALL_PLATFORM` (as documented in
`docs/tutorial/installation.md`) causes the two to disagree: the
download fetches the requested platform's zip, but `path.txt` and the
path sanity check are written against the host platform's executable
name. That in turn makes `isInstalled()` always return `false` on
subsequent runs (forcing redundant re-downloads) and makes the
executable path recorded in `path.txt` wrong for the artifact that
was actually extracted (e.g. `electron` written alongside a
`darwin`/`win32` build).
Check `ELECTRON_INSTALL_PLATFORM` first, matching the resolution used
for `downloadArtifact`.
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
* chore: bump chromium in DEPS to 149.0.7813.0
* chore: e patches all (trivial only)
---------
Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* fix: validate header name and value in webRequest.onBeforeSendHeaders
Chromium's net::HttpRequestHeaders::SetHeader() uses CHECK() to enforce
valid header names and values, which causes a fatal crash if the caller
passes invalid strings. When users modify requestHeaders in the
onBeforeSendHeaders callback with invalid header names (e.g. containing
spaces) or invalid header values (e.g. containing CRLF), the
gin::Converter<net::HttpRequestHeaders>::FromV8() calls SetHeader()
directly, triggering the CHECK and crashing the process.
This change adds pre-validation using net::HttpUtil::IsValidHeaderName()
and net::HttpUtil::IsValidHeaderValue() before calling SetHeader(),
silently skipping invalid headers instead of crashing.
* Update shell/common/gin_converters/net_converter.cc
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* Update spec/api-web-request-spec.ts
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* fix: lint
---------
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* chore: bump chromium in DEPS to 149.0.7812.0
* chore: update patches (trivial only)
Co-Authored-By: GitHub Copilot <copilot@github.com>
* fix(patch): declare abort in Node builtin_info
Node's builtin_info.cc uses abort() but doesn't include <cstdlib>.
It used to pick up the declaration by a transitive include, but
that broke in this libc++ roll.
This patch can be removed after it's been upstreamed to Node.js.
* SharedWorker: Enforce same-origin check for IWA and Extensions
Xref: https://chromium-review.googlesource.com/c/chromium/src/+/7784632
* chore: node script/gen-libc++-filenames.js
---------
Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: GitHub Copilot <copilot@github.com>
* chore: bump chromium in DEPS to 149.0.7809.0
* chore: bump chromium in DEPS to 149.0.7810.2
* chore: bump chromium in DEPS to 149.0.7811.0
* chore: revert [OSCrypt] Remove sync backend
Electron still depends on the synchronous os_crypt API.
Revert upstream CL 7765593 until migration to async is complete.
Followup: https://github.com/electron/electron/issues/51301
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7765593
Co-Authored-By: GitHub Copilot (Claude Opus 4.6)
* fix(patch): UAF fix in OnMouseRange
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7780978
Co-Authored-By: GitHub Copilot (Claude Opus 4.6)
* fix(patch): kGlicTrustFirstOnboarding references removed
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7773143
Co-Authored-By: GitHub Copilot (Claude Opus 4.6)
* chore: update patches (trivial only)
* fix(patch): SubtlePassKey and profile methods updates
Re-add OSCryptImpl as a friend of crypto::SubtlePassKey (removed by
https://chromium-review.googlesource.com/c/chromium/src/+/7759877)
since Electron still uses the sync backend.
Followup: https://github.com/electron/electron/issues/51301
Co-Authored-By: GitHub Copilot (Claude Opus 4.6)
* fix(patch): exclude upstream scripting API
CL 7784831 moved the Scripting API from //chrome to //extensions,
which caused duplicate symbols with Electron's own implementation.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7784831
Co-Authored-By: GitHub Copilot (Claude Opus 4.6)
* 7748618: [extensions] Move MimeHandlerStreamManager
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7748618
Co-Authored-By: GitHub Copilot (Claude Opus 4.6)
* 7713176: Move GetURLLoaderFactory from Profile to BrowserContext
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7713176
Co-Authored-By: GitHub Copilot (Claude Opus 4.6)
* 7755340: Refactor CaptureHandle storage to PageImpl
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7755340
Co-Authored-By: GitHub Copilot (Claude Opus 4.6)
* 7765593: [OSCrypt] Remove sync backend
No replacement code is needed: Electron already uses the async path.
CookieEncryptionProviderImpl (backed by OSCryptAsync) supplies
encryption to the network service via the cookie_encryption_provider
NetworkContext param, making SetEncryptionKey redundant.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7765593
Co-Authored-By: GitHub Copilot (Claude Opus 4.6)
* chore: stop disabling enterprise_cloud_content_analysis
CL 7757742 moved cloud_content_scanning from unconditional deps into
a conditional block gated on enterprise_cloud_content_analysis,
safe_browsing_mode, or is_android. Since Electron sets
safe_browsing_mode = 1, the dep is still included regardless, but
explicitly overriding enterprise_cloud_content_analysis to false now
causes other targets (e.g. chrome/browser/download) to omit enterprise
connectors code that the rest of the build expects to find.
It is simpler to let it default to true than to patch around it.
Electron does not use this feature — our PerformContentAnalysisIfNeeded
is a no-op passthrough that skips straight to NotifyListenerAndEnd.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7757742
Co-Authored-By: GitHub Copilot (Claude Opus 4.6)
* chore: update patches (trivial only)
* chore: update filenames.libcxx.gni
* chore: add GPU libraries to chromedriver zip manifests
Chromedriver now has transitive runtime dependencies on libEGL,
libGLESv2, and vk_swiftshader on macOS and Windows. These are
transitive deps pulled through chromedriver_server's dependency
on //mojo/core/embedder and //net.
* fix: add MicrotasksScope for worker exit emit in ContextWillDestroy
a39108c5a4 (#47244) replaced gin_helper::EmitEvent with a direct
`v8::Function::Call()` in `WebWorkerObserver::ContextWillDestroy`
to avoid re-entering the microtask checkpoint during worker teardown.
V8 `DCHECK()`s that a policy is set. Under the old code path, this
happened with a node::CallbackScope. Under the new code path, it's
possible for a policy to not be set, causing that `DCHECK()` to fail.
This PR copies a39108c5a4's changes in `ShareEnvironmentWithContext()`:
it explicitly adds a `kDoNotRunMicrotasks` scope.
* chore: override CreateChromeMetadataPacketRecorder in tracing delegate
https://chromium-review.googlesource.com/c/chromium/src/+/7770189
product-version, os-name, and channel metadata from the legacy
ChromeEventBundle path to a new ChromeMetadataPacket recorder callback.
Override the new TracingDelegate virtual so Electron still emits these fields.
---------
Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Added Browser::Get()->is_ready() guards to all contentTracing API functions (startRecording, stopRecording, getCategories, getTraceBufferUsage) so they reject their returned Promises with a clear error message instead of crashing when called before app.whenReady().
Added a crash-case fixture test that validates all four APIs reject properly before readiness and work normally after.
* perf: use GIO for Browser::IsDefaultProtocolClient() on Linux
perf: use GIO for Browser::SetAsDefaultProtocolClient() on Linux
Similar to 7d6227a, this speeds up app.isDefaultProtocolClient()
by using the GIO library instead of spawning a shell command to
get the info.
* feat: log errors if g_app_info_set_as_default_for_type() fails
fix: remove early capturer_.reset() that causes null deref on next refresh
Another followup to dad4ab658a: remove the `capturer_.reset()` that
`desktop_media_list.patch` was adding `Worker::RefreshNextThumbnail()`.
Since we switched from the one-shot Update() model to the continuous
StartUpdating() model, resetting `capturer_` isn't necessary and is
now dangerous: ScheduleNextRefresh() posts a delayed Worker::Refresh()
that dereferences capturer_, causing a nullptr crash.
Under CI load, the NativeDesktopMediaList can survive long enough
for the next 1-second refresh cycle to fire before FinalizeList()
destroys it. The crash can manifest as either a SIGSEGV or a
DCHECK(can_refresh()) failure, which is extra fun because dad4ab658a
was fixing a similar DCHECK crash in the first place.
Sample crash:
```
[6690:0426/173732.876803:FATAL:chrome/browser/media/webrtc/native_desktop_media_list.cc:934] DCHECK failed: can_refresh().0x00000001337aa7f3 NativeDesktopMediaList::RefreshForVizFrameSinkWindows(...) + 131
```
a39108c5a4 (#47244) replaced gin_helper::EmitEvent with a direct
`v8::Function::Call()` in `WebWorkerObserver::ContextWillDestroy`
to avoid re-entering the microtask checkpoint during worker teardown.
V8 `DCHECK()`s that a policy is set. Under the old code path, this
happened with a node::CallbackScope. Under the new code path, it's
possible for a policy to not be set, causing that `DCHECK()` to fail.
This PR copies a39108c5a4's changes in `ShareEnvironmentWithContext()`:
it explicitly adds a `kDoNotRunMicrotasks` scope.
* Revert "build: use 32-core Windows ARC runners for build jobs (#51256)"
This reverts commit 099c5c0038.
* chore: put back siso patch
* Revert "fix: route ThinLTO cache through junction outside bindflt mount (#51328)"
This reverts commit 9e7a343f39.
* Revert "fix: pre-create thinlto-cache dir on Windows to avoid bindflt race (#51292)"
This reverts commit 98e91ca555.
Pre-creating out\Default\thinlto-cache dodged the CreateDirectoryW
race on bindflt-mounted ARC runners but left CreateFileW for the
cache files inside still racy. Latest symptom (publish-x86-win on
the v43.0.0-nightly.20260425 re-run):
lld-link: error: Failed to open cache file
thinlto-cache\llvmcache-...: invalid argument
That is the same ERROR_INVALID_PARAMETER bindflt returns under the
concurrent ThinLTO write load, just on a different file op.
Replace the pre-created directory with a junction at
out\Default\thinlto-cache pointing to $env:TEMP\electron-thinlto-cache
on the underlying volume. The reparse point is resolved in the I/O
manager before bindflt sees per-file operations, so cache reads and
writes bypass the filter driver entirely.
Idempotent for re-runs: detects an existing junction (without
following it via Remove-Item) and a leftover real directory from
older builds.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: dispatch toast action and reply events from WinRT activation path
ToastEventHandler::Invoke previously returned S_OK without dispatching
whenever the activation arguments looked structured (type=action,
type=reply, or contained &tag=), on the assumption that the COM
INotificationActivationCallback::Activate path would deliver the event
instead. That assumption only holds when Windows actually invokes the
COM activator — which it does for MSIX-packaged apps launched cold, and
for unpackaged apps with a properly-registered CLSID when the app is
not already running. For non-MSIX apps with activationType="foreground"
while the app is running (the common case), Windows raises only the
in-process WinRT Activated event, so action and reply were silently
dropped.
Dispatch structured activations through the same HandleToastActivation
the COM path uses. User input (reply text, selection values) is pulled
from IToastActivatedEventArgs2::UserInput, which carries the data the
COM callback would otherwise have received via
NOTIFICATION_USER_INPUT_DATA.
Also drop the &tag= term from the structured-args check. Plain clicks
in Electron-generated XML don't carry tag=, and a custom toast_xml that
puts tag= on a click argument should now dispatch as a click rather
than being silently dropped.
* fix: release HSTRING out-params from toast activation
test: fix race in reentrant loadURL() ready-to-commit test
Fix 'fails if loadurl is called after the navigation is ready to commit'
by using a done() callback to ensure the test waits for did-fail-load
before exiting.
Previously, the test would return and call afterEach(closeAllWindows),
potentially destroying the window while navigation was in flight.
Fix a crash in AutofillPopupView::Show() when the popup
tried to show itself after the parent's native view had
already gone away during teardown.
2026-04-23T20:44:32.7015810Z Received signal 11 SEGV_ACCERR 000000000160
2026-04-23T20:44:32.9322010Z 4 Electron Framework ... views::Widget::IsVisible() const + 28
2026-04-23T20:44:32.9528810Z 6 Electron Framework ... electron::AutofillPopupView::Show() + 200
2026-04-23T20:44:32.9632090Z 7 Electron Framework ... electron::AutofillPopup::CreateView(...) + 1380
2026-04-23T20:44:32.9749770Z 8 Electron Framework ... electron::AutofillDriver::ShowAutofillPopup(...) + 736
2026-04-23T20:44:33.0015220Z ✗ Electron tests failed with kill signal SIGSEGV.
* fix: add inputs to node_headers target for proper invalidation
The `generate_node_headers` action had no `inputs` declared, so Ninja
would not rebuild when node or V8 header files changed. This caused
stale headers to remain in gen/node_headers after a Node.js bump,
leading to build failures with errors in files like target_agent.h.
Add inputs including the install.py script (which determines which
headers to copy), key Node.js headers, inspector headers, and V8
version headers. Changes to any of these will now trigger regeneration.
https://claude.ai/code/session_018qZ1FBZCEkmDC1sRvPQnqp
* refactor: drive node_headers inputs from filenames.auto.gni
Wire the `generate_node_headers` action's inputs through the existing
auto_filenames mechanism so there is a single source of truth for which
files should invalidate the generated node_headers directory.
`script/gen-filenames.ts` now enumerates node and v8 header files via
filesystem scan and records them under `auto_filenames.node_header_sources`
in filenames.auto.gni, alongside install.py (which drives which headers
get copied). BUILD.gn consumes the list directly as the action's `inputs`
parameter.
The list will repopulate fully the next time `ts-node script/gen-filenames.ts`
runs (via lint-staged on any JS/TS commit), the same way webpack bundle
deps are refreshed today.
https://claude.ai/code/session_018qZ1FBZCEkmDC1sRvPQnqp
* chore: update filenames
* fmt
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix: pre-create thinlto-cache dir on Windows to avoid bindflt race
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
* fix: discover ThinLTO cache path from GN instead of hardcoding
Addresses review feedback from @deepak1556: the hardcoded
`out\Default\thinlto-cache` path goes out of sync if upstream
changes `cache_dir` in Chromium's build/config/compiler/BUILD.gn.
Read the `/lldltocache:` flag from `gn desc` on a linked target
(`//electron:electron_app`) and pre-create whatever path GN
actually configured. Skips the pre-create entirely when ThinLTO
is disabled (non-official builds), which is the correct no-op.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: run gn gen before discovering ThinLTO cache path
Previous attempt failed on Windows CI for two reasons:
1. `e init` does not run `gn gen` — out/Default is still unpopulated
when the build step starts, so `gn desc` had nothing to introspect.
2. `e` writes informational lines to stderr (e.g. "INFO Auto-updates
disabled"), which GitHub Actions' default $ErrorActionPreference =
'Stop' turned into a terminating NativeCommandError before e build
could run.
Run `gn gen` explicitly here so `gn desc` can report the effective
`/lldltocache:` path, and shell each `e` invocation through cmd.exe
so its informational stderr stays out of PowerShell's error stream.
`e build` re-uses the same generated build dir so gn gen is paid
once.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: revert to hardcoded thinlto-cache path, document the coupling
Dynamic discovery via `gn desc` required `gn gen` to run beforehand,
and `gn gen` can't run before `e build` on Windows CI — gn.exe isn't
installed in `src/third_party/gn/` or `src/buildtools/win/gn/` until
a Chromium gclient hook that the current CI workflow doesn't trigger.
`e build` works because the restored src cache lets it skip the gen
step; any attempt to force `gn gen` earlier fails with exit 2.
Go back to pre-creating the path the upstream default currently
resolves to, and leave a comment explaining the coupling so a future
upstream relocation fails loudly (via the original LLVM error) rather
than silently.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude <svc-devxp-claude@slack-corp.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Chromium 149.0.7798.0 roll bumped the pinned siso revision, and
upstream added a `path/filepath` import to file_parser.go. That broke
the import-block context for the 0002 ERROR_INVALID_PARAMETER retry
patch, so `git am --3way` could no longer build a fake ancestor and the
build-siso-windows job started failing at the apply step.
Re-export both patches against the new siso SHA. No functional change to
the patched code; only line offsets, index hashes and the import context
move.
* build: restrict npm tarball contents to an explicit allowlist
The npm publish flow runs `npm pack` in a staging temp dir, but
`npm/package.json` had no `files` field — so any file that happened
to land in that dir was packed into the published tarball.
Recent releases (41.2.1+, 40.9.1+, 39.8.8+) shipped a self-referential
`.npm-cache/_logs/*-debug-0.log` (npm's own debug log, written into
the pack dir before pack finishes reading files) and a stray copy of
`SHASUMS256.txt` that duplicates the info already in `checksums.json`.
Add an explicit `files` allowlist so only the intended contents are
packaged, regardless of staging-dir contamination. `package.json`,
`README.md`, and `LICENSE` are auto-included by npm.
Fixes#51290.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* build: include LICENSE and README.md in files allowlist
These are auto-included by npm regardless, but listing them makes the
intended contents of the tarball self-documenting alongside the other
entries.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
perf: use GIO instead of xdg-mime for app.getApplicationNameForProtocol()
The Linux impl of app.getApplicationNameForProtocol() now uses
`g_app_info_get_default_for_uri_scheme()` + `g_app_info_get_display_name()`
instead of spawning a call to the `xdg-mime` shell command.
Clean up the related tests: remove the xdg-mime mock.
* build: use 32-core Windows ARC runners for build jobs
* ci: add siso patch to retry ERROR_INVALID_PARAMETER on ninja file open
The existing patch removes the redundant per-chunk re-open in
fileParser.readFile, but the single remaining os.Open per subninja can
still hit the bindflt race under the ~90k-file concurrent open burst on
the 32-core Windows runners. Layer a second patch on top that wraps that
open in a Windows-only 5-attempt retry (5-80ms backoff) so a single
transient failure no longer aborts the whole manifest load.
The wrapper returned by `deprecate.removeFunction` dropped the wrapped
function's return value because it did not `return` from `fn.apply`.
Every other function wrapper in this module (`renameFunction`,
`moveAPI`) forwards the return value, and the generic type signature
`<T extends Function>(fn: T, ...): T` promises that `T`'s return type
is preserved. Callers that relied on the return value of a function
wrapped by `removeFunction` would silently receive `undefined` from
the wrapper.
Mirror the forwarding done by `renameFunction` / `moveAPI` and extend
the existing spec to assert that the wrapper preserves both the return
value and the `this` context of the deprecated function.
Assisted-By: Claude Opus 4.6
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>