mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ec710e99c | ||
|
|
e9060c2793 | ||
|
|
03bfd50875 | ||
|
|
484b75568f | ||
|
|
2e95cf50bb | ||
|
|
c29526b721 | ||
|
|
f4b7aa5401 | ||
|
|
76172fd27e | ||
|
|
c145388dd2 | ||
|
|
faa3dc7654 | ||
|
|
3f0dd063cb | ||
|
|
c2184ad4ff | ||
|
|
31cd9d1f61 | ||
|
|
ca6bd89a69 | ||
|
|
82b648e491 | ||
|
|
085363db07 | ||
|
|
565988c96f | ||
|
|
2977fc4025 | ||
|
|
1ded991603 | ||
|
|
dc19cd2c9d | ||
|
|
945f1c7262 | ||
|
|
70255b1db1 | ||
|
|
c96d7db592 | ||
|
|
6780e671f9 | ||
|
|
e5799c1dc2 | ||
|
|
6544cec686 | ||
|
|
8618d5d220 | ||
|
|
15d87d48b2 | ||
|
|
59436b032b | ||
|
|
e93a028c91 | ||
|
|
80de0b6acd | ||
|
|
28485340b0 | ||
|
|
de85def21b | ||
|
|
c9ff1d38e4 | ||
|
|
3649df1043 | ||
|
|
89817d6a02 | ||
|
|
8177a16f9a | ||
|
|
abd7850ee4 | ||
|
|
b0c3534ecb | ||
|
|
16adf2a263 | ||
|
|
b96b40223a | ||
|
|
a4f6d8a1f7 | ||
|
|
2ed1041e66 | ||
|
|
d6221eaf2d | ||
|
|
ace362c4c4 | ||
|
|
f163b0ad64 | ||
|
|
6fa5495a70 | ||
|
|
2df0c05a3a | ||
|
|
d5d40d50ab | ||
|
|
b9acd8afbd | ||
|
|
865a72fe34 | ||
|
|
59f50c75fc | ||
|
|
52251f2154 | ||
|
|
750df6ad9a | ||
|
|
e21a6bf385 | ||
|
|
8f005ee01c | ||
|
|
38b64d334f | ||
|
|
9283a9d19b | ||
|
|
116dcfb827 | ||
|
|
87bf58d04a | ||
|
|
08f30e2623 | ||
|
|
35670486f7 | ||
|
|
33057eb8d4 | ||
|
|
b12e04eda0 | ||
|
|
0c9581609c | ||
|
|
b0121d9eb1 | ||
|
|
b70b76e97f | ||
|
|
42728caaa3 | ||
|
|
d60d4c6b2d | ||
|
|
cdf99a215a | ||
|
|
af42e8e9c7 | ||
|
|
52113e0d1c | ||
|
|
8f72f9bcb5 | ||
|
|
6e44c8f7d0 | ||
|
|
0f8ebfba1e | ||
|
|
4583072a98 | ||
|
|
8f902599e4 | ||
|
|
dcc19bb8d6 | ||
|
|
71d6776e00 | ||
|
|
37d4f807a6 | ||
|
|
efad0a8018 | ||
|
|
dae05a44a0 | ||
|
|
e887328b23 | ||
|
|
337684f3cb | ||
|
|
0862529a86 |
@@ -75,17 +75,15 @@ executors:
|
||||
resource_class: << parameters.size >>
|
||||
|
||||
# Electron Runners
|
||||
apple-silicon:
|
||||
resource_class: electronjs/macos-arm64
|
||||
machine: true
|
||||
|
||||
linux-arm:
|
||||
resource_class: electronjs/linux-arm
|
||||
machine: true
|
||||
resource_class: electronjs/aks-linux-arm-test
|
||||
docker:
|
||||
- image: ghcr.io/electron/test:arm32v7-8e0f85b708fa58e28e4824954d6fd55adfda5e9e
|
||||
|
||||
linux-arm64:
|
||||
resource_class: electronjs/linux-arm64
|
||||
machine: true
|
||||
resource_class: electronjs/aks-linux-arm-test
|
||||
docker:
|
||||
- image: ghcr.io/electron/test:arm64v8-76d5d29e247972da3855a01c2d8cf72c5998233a
|
||||
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "SLACK_WEBHOOK" Slack hook URL to send notifications.
|
||||
@@ -250,6 +248,10 @@ step-depot-tools-get: &step-depot-tools-get
|
||||
name: Get depot tools
|
||||
command: |
|
||||
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
cd depot_tools
|
||||
git fetch --depth 1 origin f76550541c751f956ef9287f2695a6c8a74bf709
|
||||
git checkout f76550541c751f956ef9287f2695a6c8a74bf709
|
||||
cd ..
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
|
||||
sed -i '' '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
@@ -1657,17 +1659,15 @@ commands:
|
||||
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 && (circleci tests glob "spec/*-spec.ts" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings 2>&1)) | $ASAN_SYMBOLIZE
|
||||
(cd electron && (circleci tests glob "spec/*-spec.ts" | xargs -I@ -P4 bash -c "echo $(pwd)/@" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings 2>&1)) | $ASAN_SYMBOLIZE
|
||||
else
|
||||
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
export ELECTRON_SKIP_NATIVE_MODULE_TESTS=true
|
||||
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging)
|
||||
else
|
||||
if [ "$TARGET_ARCH" == "ia32" ]; then
|
||||
npm_config_arch=x64 node electron/node_modules/dugite/script/download-git.js
|
||||
fi
|
||||
(cd electron && (circleci tests glob "spec/*-spec.ts" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings))
|
||||
fi
|
||||
if [ "$TARGET_ARCH" == "ia32" ]; then
|
||||
npm_config_arch=x64 node electron/node_modules/dugite/script/download-git.js
|
||||
fi
|
||||
(cd electron && (circleci tests glob "spec/*-spec.ts" | xargs -I@ -P4 bash -c "echo $(pwd)/@" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings))
|
||||
fi
|
||||
- store_test_results:
|
||||
path: src/junit
|
||||
@@ -2297,6 +2297,7 @@ jobs:
|
||||
<<: *env-global
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
parallelism: 3
|
||||
steps:
|
||||
- electron-tests:
|
||||
artifact-key: linux-arm
|
||||
@@ -2308,6 +2309,7 @@ jobs:
|
||||
<<: *env-global
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
parallelism: 3
|
||||
steps:
|
||||
- electron-tests:
|
||||
artifact-key: linux-arm64
|
||||
@@ -2325,8 +2327,11 @@ jobs:
|
||||
- electron-tests:
|
||||
artifact-key: darwin-x64
|
||||
|
||||
darwin-testing-arm64-tests:
|
||||
executor: apple-silicon
|
||||
darwin-testing-arm64-tests:
|
||||
executor:
|
||||
name: macos
|
||||
size: macos.m1.medium.gen1
|
||||
version: 14.0.0
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
<<: *env-stack-dumping
|
||||
@@ -2350,7 +2355,10 @@ jobs:
|
||||
artifact-key: mas-x64
|
||||
|
||||
mas-testing-arm64-tests:
|
||||
executor: apple-silicon
|
||||
executor:
|
||||
name: macos
|
||||
size: macos.m1.medium.gen1
|
||||
version: 14.0.0
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
<<: *env-stack-dumping
|
||||
|
||||
22
BUILD.gn
22
BUILD.gn
@@ -165,15 +165,6 @@ npm_action("build_electron_definitions") {
|
||||
outputs = [ "$target_gen_dir/tsc/typings/electron.d.ts" ]
|
||||
}
|
||||
|
||||
webpack_build("electron_asar_bundle") {
|
||||
deps = [ ":build_electron_definitions" ]
|
||||
|
||||
inputs = auto_filenames.asar_bundle_deps
|
||||
|
||||
config_file = "//electron/build/webpack/webpack.config.asar.js"
|
||||
out_file = "$target_gen_dir/js2c/asar_bundle.js"
|
||||
}
|
||||
|
||||
webpack_build("electron_browser_bundle") {
|
||||
deps = [ ":build_electron_definitions" ]
|
||||
|
||||
@@ -219,6 +210,15 @@ webpack_build("electron_isolated_renderer_bundle") {
|
||||
out_file = "$target_gen_dir/js2c/isolated_bundle.js"
|
||||
}
|
||||
|
||||
webpack_build("electron_node_bundle") {
|
||||
deps = [ ":build_electron_definitions" ]
|
||||
|
||||
inputs = auto_filenames.node_bundle_deps
|
||||
|
||||
config_file = "//electron/build/webpack/webpack.config.node.js"
|
||||
out_file = "$target_gen_dir/js2c/node_init.js"
|
||||
}
|
||||
|
||||
webpack_build("electron_utility_bundle") {
|
||||
deps = [ ":build_electron_definitions" ]
|
||||
|
||||
@@ -230,9 +230,9 @@ webpack_build("electron_utility_bundle") {
|
||||
|
||||
action("electron_js2c") {
|
||||
deps = [
|
||||
":electron_asar_bundle",
|
||||
":electron_browser_bundle",
|
||||
":electron_isolated_renderer_bundle",
|
||||
":electron_node_bundle",
|
||||
":electron_renderer_bundle",
|
||||
":electron_sandboxed_renderer_bundle",
|
||||
":electron_utility_bundle",
|
||||
@@ -240,9 +240,9 @@ action("electron_js2c") {
|
||||
]
|
||||
|
||||
sources = [
|
||||
"$target_gen_dir/js2c/asar_bundle.js",
|
||||
"$target_gen_dir/js2c/browser_init.js",
|
||||
"$target_gen_dir/js2c/isolated_bundle.js",
|
||||
"$target_gen_dir/js2c/node_init.js",
|
||||
"$target_gen_dir/js2c/renderer_init.js",
|
||||
"$target_gen_dir/js2c/sandbox_bundle.js",
|
||||
"$target_gen_dir/js2c/utility_init.js",
|
||||
|
||||
2
DEPS
2
DEPS
@@ -2,7 +2,7 @@ gclient_gn_args_from = 'src'
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'120.0.6099.199',
|
||||
'120.0.6099.291',
|
||||
'node_version':
|
||||
'v18.18.2',
|
||||
'nan_version':
|
||||
|
||||
@@ -112,4 +112,4 @@ and more can be found on the [Community page](https://www.electronjs.org/communi
|
||||
|
||||
[MIT](https://github.com/electron/electron/blob/main/LICENSE)
|
||||
|
||||
When using Electron logos, make sure to follow [OpenJS Foundation Trademark Policy](https://openjsf.org/wp-content/uploads/sites/84/2021/01/OpenJS-Foundation-Trademark-Policy-2021-01-12.docx.pdf).
|
||||
When using Electron logos, make sure to follow [OpenJS Foundation Trademark Policy](https://trademark-policy.openjsf.org/).
|
||||
|
||||
@@ -94,6 +94,11 @@ for:
|
||||
Remove-Item -Recurse -Force $pwd\build-tools
|
||||
}
|
||||
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
- ps: |
|
||||
cd depot_tools
|
||||
git fetch --depth 1 origin f76550541c751f956ef9287f2695a6c8a74bf709
|
||||
git checkout f76550541c751f956ef9287f2695a6c8a74bf709
|
||||
cd ..
|
||||
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
|
||||
- depot_tools\bootstrap\win_tools.bat
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
@@ -188,7 +193,12 @@ for:
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
}
|
||||
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
- ps: |
|
||||
$manifest_file = "electron/script/zip_manifests/dist_zip.win.$env:TARGET_ARCH.manifest"
|
||||
python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip $manifest_file
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Zip contains files not listed in the manifest $manifest_file"
|
||||
}
|
||||
- ps: |
|
||||
cd C:\projects\src
|
||||
$missing_artifacts = $false
|
||||
|
||||
12
appveyor.yml
12
appveyor.yml
@@ -92,6 +92,11 @@ for:
|
||||
Remove-Item -Recurse -Force $pwd\build-tools
|
||||
}
|
||||
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
- ps: |
|
||||
cd depot_tools
|
||||
git fetch --depth 1 origin f76550541c751f956ef9287f2695a6c8a74bf709
|
||||
git checkout f76550541c751f956ef9287f2695a6c8a74bf709
|
||||
cd ..
|
||||
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
|
||||
- depot_tools\bootstrap\win_tools.bat
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
@@ -186,7 +191,12 @@ for:
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
}
|
||||
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
- ps: |
|
||||
$manifest_file = "electron/script/zip_manifests/dist_zip.win.$env:TARGET_ARCH.manifest"
|
||||
python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip $manifest_file
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Zip contains files not listed in the manifest $manifest_file"
|
||||
}
|
||||
- ps: |
|
||||
cd C:\projects\src
|
||||
$missing_artifacts = $false
|
||||
|
||||
@@ -24,6 +24,10 @@ enable_printing = true
|
||||
angle_enable_vulkan_validation_layers = false
|
||||
dawn_enable_vulkan_validation_layers = false
|
||||
|
||||
# Removes dxc dll's that are only used experimentally.
|
||||
# See https://bugs.chromium.org/p/chromium/issues/detail?id=1474897
|
||||
dawn_use_built_dxc = false
|
||||
|
||||
# These are disabled because they cause the zip manifest to differ between
|
||||
# testing and release builds.
|
||||
# See https://chromium-review.googlesource.com/c/chromium/src/+/2774898.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
module.exports = require('./webpack.config.base')({
|
||||
target: 'asar',
|
||||
alwaysHasNode: true,
|
||||
targetDeletesNodeGlobals: true
|
||||
});
|
||||
4
build/webpack/webpack.config.node.js
Normal file
4
build/webpack/webpack.config.node.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = require('./webpack.config.base')({
|
||||
target: 'node',
|
||||
alwaysHasNode: true
|
||||
});
|
||||
@@ -15,4 +15,15 @@ buildflag_header("buildflags") {
|
||||
"ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
|
||||
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
|
||||
]
|
||||
|
||||
if (electron_vendor_version != "") {
|
||||
result = string_split(electron_vendor_version, ":")
|
||||
flags += [
|
||||
"HAS_VENDOR_VERSION=true",
|
||||
"VENDOR_VERSION_NAME=\"${result[0]}\"",
|
||||
"VENDOR_VERSION_VALUE=\"${result[1]}\"",
|
||||
]
|
||||
} else {
|
||||
flags += [ "HAS_VENDOR_VERSION=false" ]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,4 +23,10 @@ declare_args() {
|
||||
# Packagers and vendor builders should set this in gn args to avoid running
|
||||
# the script that reads git tag.
|
||||
override_electron_version = ""
|
||||
|
||||
# Define an extra item that will show in process.versions, the value must
|
||||
# be in the format of "key:value".
|
||||
# Packagers and vendor builders can set this in gn args to attach extra info
|
||||
# about the build in the binary.
|
||||
electron_vendor_version = ""
|
||||
}
|
||||
|
||||
@@ -1496,6 +1496,24 @@ details.
|
||||
|
||||
**Note:** Enable `Secure Keyboard Entry` only when it is needed and disable it when it is no longer needed.
|
||||
|
||||
### `app.setProxy(config)`
|
||||
|
||||
* `config` [ProxyConfig](structures/proxy-config.md)
|
||||
|
||||
Returns `Promise<void>` - Resolves when the proxy setting process is complete.
|
||||
|
||||
Sets the proxy settings for networks requests made without an associated [Session](session.md).
|
||||
Currently this will affect requests made with [Net](net.md) in the [utility process](../glossary.md#utility-process)
|
||||
and internal requests made by the runtime (ex: geolocation queries).
|
||||
|
||||
This method can only be called after app is ready.
|
||||
|
||||
#### `app.resolveProxy(url)`
|
||||
|
||||
* `url` URL
|
||||
|
||||
Returns `Promise<string>` - Resolves with the proxy information for `url` that will be used when attempting to make requests using [Net](net.md) in the [utility process](../glossary.md#utility-process).
|
||||
|
||||
## Properties
|
||||
|
||||
### `app.accessibilitySupportEnabled` _macOS_ _Windows_
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> Make HTTP/HTTPS requests.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)<br />
|
||||
Process: [Main](../glossary.md#main-process), [Utility](../glossary.md#utility-process)<br />
|
||||
_This class is not exported from the `'electron'` module. It is only available as a return value of other methods in the Electron API._
|
||||
|
||||
`ClientRequest` implements the [Writable Stream](https://nodejs.org/api/stream.html#stream_writable_streams)
|
||||
@@ -17,6 +17,8 @@ following properties:
|
||||
method.
|
||||
* `url` string (optional) - The request URL. Must be provided in the absolute
|
||||
form with the protocol scheme specified as http or https.
|
||||
* `headers` Record<string, string | string[]> (optional) - Headers to be sent
|
||||
with the request.
|
||||
* `session` Session (optional) - The [`Session`](session.md) instance with
|
||||
which the request is associated.
|
||||
* `partition` string (optional) - The name of the [`partition`](session.md)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> Handle responses to HTTP/HTTPS requests.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)<br />
|
||||
Process: [Main](../glossary.md#main-process), [Utility](../glossary.md#utility-process)<br />
|
||||
_This class is not exported from the `'electron'` module. It is only available as a return value of other methods in the Electron API._
|
||||
|
||||
`IncomingMessage` implements the [Readable Stream](https://nodejs.org/api/stream.html#stream_readable_streams)
|
||||
|
||||
@@ -51,6 +51,13 @@ Check the _Size requirements_ section in [this article][icons].
|
||||
|
||||
[icons]: https://learn.microsoft.com/en-us/windows/win32/uxguide/vis-icons
|
||||
|
||||
:::note
|
||||
|
||||
EXIF metadata is currently not supported and will not be taken into account during
|
||||
image encoding and decoding.
|
||||
|
||||
:::
|
||||
|
||||
## High Resolution Image
|
||||
|
||||
On platforms that have high-DPI support such as Apple Retina displays, you can
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> Issue HTTP/HTTPS requests using Chromium's native networking library
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
Process: [Main](../glossary.md#main-process), [Utility](../glossary.md#utility-process)
|
||||
|
||||
The `net` module is a client-side API for issuing HTTP(S) requests. It is
|
||||
similar to the [HTTP](https://nodejs.org/api/http.html) and
|
||||
@@ -119,6 +119,9 @@ protocol.handle('https', (req) => {
|
||||
})
|
||||
```
|
||||
|
||||
Note: in the [utility process](../glossary.md#utility-process) custom protocols
|
||||
are not supported.
|
||||
|
||||
### `net.isOnline()`
|
||||
|
||||
Returns `boolean` - Whether there is currently internet connection.
|
||||
|
||||
@@ -589,105 +589,15 @@ Writes any unwritten DOMStorage data to disk.
|
||||
|
||||
#### `ses.setProxy(config)`
|
||||
|
||||
* `config` Object
|
||||
* `mode` string (optional) - The proxy mode. Should be one of `direct`,
|
||||
`auto_detect`, `pac_script`, `fixed_servers` or `system`. If it's
|
||||
unspecified, it will be automatically determined based on other specified
|
||||
options.
|
||||
* `direct`
|
||||
In direct mode all connections are created directly, without any proxy involved.
|
||||
* `auto_detect`
|
||||
In auto_detect mode the proxy configuration is determined by a PAC script that can
|
||||
be downloaded at http://wpad/wpad.dat.
|
||||
* `pac_script`
|
||||
In pac_script mode the proxy configuration is determined by a PAC script that is
|
||||
retrieved from the URL specified in the `pacScript`. This is the default mode
|
||||
if `pacScript` is specified.
|
||||
* `fixed_servers`
|
||||
In fixed_servers mode the proxy configuration is specified in `proxyRules`.
|
||||
This is the default mode if `proxyRules` is specified.
|
||||
* `system`
|
||||
In system mode the proxy configuration is taken from the operating system.
|
||||
Note that the system mode is different from setting no proxy configuration.
|
||||
In the latter case, Electron falls back to the system settings
|
||||
only if no command-line options influence the proxy configuration.
|
||||
* `pacScript` string (optional) - The URL associated with the PAC file.
|
||||
* `proxyRules` string (optional) - Rules indicating which proxies to use.
|
||||
* `proxyBypassRules` string (optional) - Rules indicating which URLs should
|
||||
bypass the proxy settings.
|
||||
* `config` [ProxyConfig](structures/proxy-config.md)
|
||||
|
||||
Returns `Promise<void>` - Resolves when the proxy setting process is complete.
|
||||
|
||||
Sets the proxy settings.
|
||||
|
||||
When `mode` is unspecified, `pacScript` and `proxyRules` are provided together, the `proxyRules`
|
||||
option is ignored and `pacScript` configuration is applied.
|
||||
|
||||
You may need `ses.closeAllConnections` to close currently in flight connections to prevent
|
||||
pooled sockets using previous proxy from being reused by future requests.
|
||||
|
||||
The `proxyRules` has to follow the rules below:
|
||||
|
||||
```sh
|
||||
proxyRules = schemeProxies[";"<schemeProxies>]
|
||||
schemeProxies = [<urlScheme>"="]<proxyURIList>
|
||||
urlScheme = "http" | "https" | "ftp" | "socks"
|
||||
proxyURIList = <proxyURL>[","<proxyURIList>]
|
||||
proxyURL = [<proxyScheme>"://"]<proxyHost>[":"<proxyPort>]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
* `http=foopy:80;ftp=foopy2` - Use HTTP proxy `foopy:80` for `http://` URLs, and
|
||||
HTTP proxy `foopy2:80` for `ftp://` URLs.
|
||||
* `foopy:80` - Use HTTP proxy `foopy:80` for all URLs.
|
||||
* `foopy:80,bar,direct://` - Use HTTP proxy `foopy:80` for all URLs, failing
|
||||
over to `bar` if `foopy:80` is unavailable, and after that using no proxy.
|
||||
* `socks4://foopy` - Use SOCKS v4 proxy `foopy:1080` for all URLs.
|
||||
* `http=foopy,socks5://bar.com` - Use HTTP proxy `foopy` for http URLs, and fail
|
||||
over to the SOCKS5 proxy `bar.com` if `foopy` is unavailable.
|
||||
* `http=foopy,direct://` - Use HTTP proxy `foopy` for http URLs, and use no
|
||||
proxy if `foopy` is unavailable.
|
||||
* `http=foopy;socks=foopy2` - Use HTTP proxy `foopy` for http URLs, and use
|
||||
`socks4://foopy2` for all other URLs.
|
||||
|
||||
The `proxyBypassRules` is a comma separated list of rules described below:
|
||||
|
||||
* `[ URL_SCHEME "://" ] HOSTNAME_PATTERN [ ":" <port> ]`
|
||||
|
||||
Match all hostnames that match the pattern HOSTNAME_PATTERN.
|
||||
|
||||
Examples:
|
||||
"foobar.com", "\*foobar.com", "\*.foobar.com", "\*foobar.com:99",
|
||||
"https://x.\*.y.com:99"
|
||||
|
||||
* `"." HOSTNAME_SUFFIX_PATTERN [ ":" PORT ]`
|
||||
|
||||
Match a particular domain suffix.
|
||||
|
||||
Examples:
|
||||
".google.com", ".com", "http://.google.com"
|
||||
|
||||
* `[ SCHEME "://" ] IP_LITERAL [ ":" PORT ]`
|
||||
|
||||
Match URLs which are IP address literals.
|
||||
|
||||
Examples:
|
||||
"127.0.1", "\[0:0::1]", "\[::1]", "http://\[::1]:99"
|
||||
|
||||
* `IP_LITERAL "/" PREFIX_LENGTH_IN_BITS`
|
||||
|
||||
Match any URL that is to an IP literal that falls between the
|
||||
given range. IP range is specified using CIDR notation.
|
||||
|
||||
Examples:
|
||||
"192.168.1.1/16", "fefe:13::abc/33".
|
||||
|
||||
* `<local>`
|
||||
|
||||
Match local addresses. The meaning of `<local>` is whether the
|
||||
host matches one of: "127.0.0.1", "::1", "localhost".
|
||||
|
||||
#### `ses.resolveHost(host, [options])`
|
||||
|
||||
* `host` string - Hostname to resolve.
|
||||
|
||||
86
docs/api/structures/proxy-config.md
Normal file
86
docs/api/structures/proxy-config.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# ProxyConfig Object
|
||||
|
||||
* `mode` string (optional) - The proxy mode. Should be one of `direct`,
|
||||
`auto_detect`, `pac_script`, `fixed_servers` or `system`.
|
||||
Defaults to `pac_script` proxy mode if `pacScript` option is specified
|
||||
otherwise defaults to `fixed_servers`.
|
||||
* `direct` - In direct mode all connections are created directly, without any proxy involved.
|
||||
* `auto_detect` - In auto_detect mode the proxy configuration is determined by a PAC script that can
|
||||
be downloaded at http://wpad/wpad.dat.
|
||||
* `pac_script` - In pac_script mode the proxy configuration is determined by a PAC script that is
|
||||
retrieved from the URL specified in the `pacScript`. This is the default mode if `pacScript` is specified.
|
||||
* `fixed_servers` - In fixed_servers mode the proxy configuration is specified in `proxyRules`.
|
||||
This is the default mode if `proxyRules` is specified.
|
||||
* `system` - In system mode the proxy configuration is taken from the operating system.
|
||||
Note that the system mode is different from setting no proxy configuration.
|
||||
In the latter case, Electron falls back to the system settings only if no
|
||||
command-line options influence the proxy configuration.
|
||||
* `pacScript` string (optional) - The URL associated with the PAC file.
|
||||
* `proxyRules` string (optional) - Rules indicating which proxies to use.
|
||||
* `proxyBypassRules` string (optional) - Rules indicating which URLs should
|
||||
bypass the proxy settings.
|
||||
|
||||
When `mode` is unspecified, `pacScript` and `proxyRules` are provided together, the `proxyRules`
|
||||
option is ignored and `pacScript` configuration is applied.
|
||||
|
||||
The `proxyRules` has to follow the rules below:
|
||||
|
||||
```sh
|
||||
proxyRules = schemeProxies[";"<schemeProxies>]
|
||||
schemeProxies = [<urlScheme>"="]<proxyURIList>
|
||||
urlScheme = "http" | "https" | "ftp" | "socks"
|
||||
proxyURIList = <proxyURL>[","<proxyURIList>]
|
||||
proxyURL = [<proxyScheme>"://"]<proxyHost>[":"<proxyPort>]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
* `http=foopy:80;ftp=foopy2` - Use HTTP proxy `foopy:80` for `http://` URLs, and
|
||||
HTTP proxy `foopy2:80` for `ftp://` URLs.
|
||||
* `foopy:80` - Use HTTP proxy `foopy:80` for all URLs.
|
||||
* `foopy:80,bar,direct://` - Use HTTP proxy `foopy:80` for all URLs, failing
|
||||
over to `bar` if `foopy:80` is unavailable, and after that using no proxy.
|
||||
* `socks4://foopy` - Use SOCKS v4 proxy `foopy:1080` for all URLs.
|
||||
* `http=foopy,socks5://bar.com` - Use HTTP proxy `foopy` for http URLs, and fail
|
||||
over to the SOCKS5 proxy `bar.com` if `foopy` is unavailable.
|
||||
* `http=foopy,direct://` - Use HTTP proxy `foopy` for http URLs, and use no
|
||||
proxy if `foopy` is unavailable.
|
||||
* `http=foopy;socks=foopy2` - Use HTTP proxy `foopy` for http URLs, and use
|
||||
`socks4://foopy2` for all other URLs.
|
||||
|
||||
The `proxyBypassRules` is a comma separated list of rules described below:
|
||||
|
||||
* `[ URL_SCHEME "://" ] HOSTNAME_PATTERN [ ":" <port> ]`
|
||||
|
||||
Match all hostnames that match the pattern HOSTNAME_PATTERN.
|
||||
|
||||
Examples:
|
||||
"foobar.com", "\*foobar.com", "\*.foobar.com", "\*foobar.com:99",
|
||||
"https://x.\*.y.com:99"
|
||||
|
||||
* `"." HOSTNAME_SUFFIX_PATTERN [ ":" PORT ]`
|
||||
|
||||
Match a particular domain suffix.
|
||||
|
||||
Examples:
|
||||
".google.com", ".com", "http://.google.com"
|
||||
|
||||
* `[ SCHEME "://" ] IP_LITERAL [ ":" PORT ]`
|
||||
|
||||
Match URLs which are IP address literals.
|
||||
|
||||
Examples:
|
||||
"127.0.1", "\[0:0::1]", "\[::1]", "http://\[::1]:99"
|
||||
|
||||
* `IP_LITERAL "/" PREFIX_LENGTH_IN_BITS`
|
||||
|
||||
Match any URL that is to an IP literal that falls between the
|
||||
given range. IP range is specified using CIDR notation.
|
||||
|
||||
Examples:
|
||||
"192.168.1.1/16", "fefe:13::abc/33".
|
||||
|
||||
* `<local>`
|
||||
|
||||
Match local addresses. The meaning of `<local>` is whether the
|
||||
host matches one of: "127.0.0.1", "::1", "localhost".
|
||||
@@ -196,32 +196,19 @@ support via Electron's support for the [Chrome DevTools Protocol][] (CDP).
|
||||
|
||||
### Install dependencies
|
||||
|
||||
You can install Playwright through your preferred Node.js package manager. The Playwright team
|
||||
recommends using the `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` environment variable to avoid
|
||||
unnecessary browser downloads when testing an Electron app.
|
||||
|
||||
```sh npm2yarn
|
||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install --save-dev playwright
|
||||
```
|
||||
|
||||
Playwright also comes with its own test runner, Playwright Test, which is built for end-to-end
|
||||
testing. You can also install it as a dev dependency in your project:
|
||||
You can install Playwright through your preferred Node.js package manager. It comes with its
|
||||
own [test runner][playwright-intro], which is built for end-to-end testing:
|
||||
|
||||
```sh npm2yarn
|
||||
npm install --save-dev @playwright/test
|
||||
```
|
||||
|
||||
:::caution Dependencies
|
||||
This tutorial was written `playwright@1.16.3` and `@playwright/test@1.16.3`. Check out
|
||||
This tutorial was written with `@playwright/test@1.41.1`. Check out
|
||||
[Playwright's releases][playwright-releases] page to learn about
|
||||
changes that might affect the code below.
|
||||
:::
|
||||
|
||||
:::info Using third-party test runners
|
||||
If you're interested in using an alternative test runner (e.g. Jest or Mocha), check out
|
||||
Playwright's [Third-Party Test Runner][playwright-test-runners] guide.
|
||||
:::
|
||||
|
||||
### Write your tests
|
||||
|
||||
Playwright launches your app in development mode through the `_electron.launch` API.
|
||||
@@ -229,8 +216,7 @@ To point this API to your Electron app, you can pass the path to your main proce
|
||||
entry point (here, it is `main.js`).
|
||||
|
||||
```js {5} @ts-nocheck
|
||||
const { _electron: electron } = require('playwright')
|
||||
const { test } = require('@playwright/test')
|
||||
const { test, _electron: electron } = require('@playwright/test')
|
||||
|
||||
test('launch app', async () => {
|
||||
const electronApp = await electron.launch({ args: ['main.js'] })
|
||||
@@ -242,9 +228,8 @@ test('launch app', async () => {
|
||||
After that, you will access to an instance of Playwright's `ElectronApp` class. This
|
||||
is a powerful class that has access to main process modules for example:
|
||||
|
||||
```js {6-11} @ts-nocheck
|
||||
const { _electron: electron } = require('playwright')
|
||||
const { test } = require('@playwright/test')
|
||||
```js {5-10} @ts-nocheck
|
||||
const { test, _electron: electron } = require('@playwright/test')
|
||||
|
||||
test('get isPackaged', async () => {
|
||||
const electronApp = await electron.launch({ args: ['main.js'] })
|
||||
@@ -263,8 +248,7 @@ It can also create individual [Page][playwright-page] objects from Electron Brow
|
||||
For example, to grab the first BrowserWindow and save a screenshot:
|
||||
|
||||
```js {6-7} @ts-nocheck
|
||||
const { _electron: electron } = require('playwright')
|
||||
const { test } = require('@playwright/test')
|
||||
const { test, _electron: electron } = require('@playwright/test')
|
||||
|
||||
test('save screenshot', async () => {
|
||||
const electronApp = await electron.launch({ args: ['main.js'] })
|
||||
@@ -275,12 +259,11 @@ test('save screenshot', async () => {
|
||||
})
|
||||
```
|
||||
|
||||
Putting all this together using the PlayWright Test runner, let's create a `example.spec.js`
|
||||
Putting all this together using the Playwright test-runner, let's create a `example.spec.js`
|
||||
test file with a single test and assertion:
|
||||
|
||||
```js title='example.spec.js' @ts-nocheck
|
||||
const { _electron: electron } = require('playwright')
|
||||
const { test, expect } = require('@playwright/test')
|
||||
const { test, expect, _electron: electron } = require('@playwright/test')
|
||||
|
||||
test('example test', async () => {
|
||||
const electronApp = await electron.launch({ args: ['.'] })
|
||||
@@ -316,6 +299,7 @@ Running 1 test using 1 worker
|
||||
:::info
|
||||
Playwright Test will automatically run any files matching the `.*(test|spec)\.(js|ts|mjs)` regex.
|
||||
You can customize this match in the [Playwright Test configuration options][playwright-test-config].
|
||||
It also works with TypeScript out of the box.
|
||||
:::
|
||||
|
||||
:::tip Further reading
|
||||
@@ -473,10 +457,10 @@ test.after.always('cleanup', async t => {
|
||||
|
||||
[chrome-driver]: https://sites.google.com/chromium.org/driver/
|
||||
[Puppeteer]: https://github.com/puppeteer/puppeteer
|
||||
[playwright-intro]: https://playwright.dev/docs/intro
|
||||
[playwright-electron]: https://playwright.dev/docs/api/class-electron/
|
||||
[playwright-electronapplication]: https://playwright.dev/docs/api/class-electronapplication
|
||||
[playwright-page]: https://playwright.dev/docs/api/class-page
|
||||
[playwright-releases]: https://github.com/microsoft/playwright/releases
|
||||
[playwright-releases]: https://playwright.dev/docs/release-notes
|
||||
[playwright-test-config]: https://playwright.dev/docs/api/class-testconfig#test-config-test-match
|
||||
[playwright-test-runners]: https://playwright.dev/docs/test-runners/
|
||||
[Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/
|
||||
|
||||
@@ -77,6 +77,7 @@ template("electron_extra_paks") {
|
||||
"//content:content_resources",
|
||||
"//content/browser/resources/gpu:resources",
|
||||
"//content/browser/resources/media:resources",
|
||||
"//content/browser/resources/process:resources",
|
||||
"//content/browser/tracing:resources",
|
||||
"//content/browser/webrtc/resources",
|
||||
"//electron:resources",
|
||||
@@ -96,6 +97,7 @@ template("electron_extra_paks") {
|
||||
# New paks should be added here by default.
|
||||
sources += [
|
||||
"$root_gen_dir/content/browser/devtools/devtools_resources.pak",
|
||||
"$root_gen_dir/content/process_resources.pak",
|
||||
"$root_gen_dir/ui/resources/webui_resources.pak",
|
||||
]
|
||||
deps += [ "//content/browser/devtools:devtools_resources" ]
|
||||
|
||||
@@ -113,6 +113,7 @@ auto_filenames = {
|
||||
"docs/api/structures/protocol-request.md",
|
||||
"docs/api/structures/protocol-response-upload-data.md",
|
||||
"docs/api/structures/protocol-response.md",
|
||||
"docs/api/structures/proxy-config.md",
|
||||
"docs/api/structures/rectangle.md",
|
||||
"docs/api/structures/referrer.md",
|
||||
"docs/api/structures/render-process-gone-details.md",
|
||||
@@ -213,7 +214,6 @@ auto_filenames = {
|
||||
"lib/browser/api/message-channel.ts",
|
||||
"lib/browser/api/module-list.ts",
|
||||
"lib/browser/api/native-theme.ts",
|
||||
"lib/browser/api/net-client-request.ts",
|
||||
"lib/browser/api/net-fetch.ts",
|
||||
"lib/browser/api/net-log.ts",
|
||||
"lib/browser/api/net.ts",
|
||||
@@ -249,12 +249,12 @@ auto_filenames = {
|
||||
"lib/browser/web-view-events.ts",
|
||||
"lib/common/api/module-list.ts",
|
||||
"lib/common/api/native-image.ts",
|
||||
"lib/common/api/net-client-request.ts",
|
||||
"lib/common/api/shell.ts",
|
||||
"lib/common/define-properties.ts",
|
||||
"lib/common/deprecate.ts",
|
||||
"lib/common/init.ts",
|
||||
"lib/common/ipc-messages.ts",
|
||||
"lib/common/reset-search-paths.ts",
|
||||
"lib/common/web-view-methods.ts",
|
||||
"lib/common/webpack-globals-provider.ts",
|
||||
"package.json",
|
||||
@@ -271,7 +271,6 @@ auto_filenames = {
|
||||
"lib/common/define-properties.ts",
|
||||
"lib/common/init.ts",
|
||||
"lib/common/ipc-messages.ts",
|
||||
"lib/common/reset-search-paths.ts",
|
||||
"lib/common/web-view-methods.ts",
|
||||
"lib/common/webpack-provider.ts",
|
||||
"lib/renderer/api/clipboard.ts",
|
||||
@@ -309,7 +308,6 @@ auto_filenames = {
|
||||
"lib/common/define-properties.ts",
|
||||
"lib/common/init.ts",
|
||||
"lib/common/ipc-messages.ts",
|
||||
"lib/common/reset-search-paths.ts",
|
||||
"lib/common/webpack-provider.ts",
|
||||
"lib/renderer/api/clipboard.ts",
|
||||
"lib/renderer/api/context-bridge.ts",
|
||||
@@ -328,10 +326,9 @@ auto_filenames = {
|
||||
"typings/internal-electron.d.ts",
|
||||
]
|
||||
|
||||
asar_bundle_deps = [
|
||||
"lib/asar/fs-wrapper.ts",
|
||||
"lib/asar/init.ts",
|
||||
"lib/common/webpack-provider.ts",
|
||||
node_bundle_deps = [
|
||||
"lib/node/asar-fs-wrapper.ts",
|
||||
"lib/node/init.ts",
|
||||
"package.json",
|
||||
"tsconfig.electron.json",
|
||||
"tsconfig.json",
|
||||
@@ -340,12 +337,15 @@ auto_filenames = {
|
||||
]
|
||||
|
||||
utility_bundle_deps = [
|
||||
"lib/browser/api/net-fetch.ts",
|
||||
"lib/browser/message-port-main.ts",
|
||||
"lib/common/api/net-client-request.ts",
|
||||
"lib/common/define-properties.ts",
|
||||
"lib/common/init.ts",
|
||||
"lib/common/reset-search-paths.ts",
|
||||
"lib/common/webpack-globals-provider.ts",
|
||||
"lib/utility/api/exports/electron.ts",
|
||||
"lib/utility/api/module-list.ts",
|
||||
"lib/utility/api/net.ts",
|
||||
"lib/utility/init.ts",
|
||||
"lib/utility/parent-port.ts",
|
||||
"package.json",
|
||||
|
||||
@@ -283,7 +283,6 @@ filenames = {
|
||||
"shell/browser/api/electron_api_menu.h",
|
||||
"shell/browser/api/electron_api_native_theme.cc",
|
||||
"shell/browser/api/electron_api_native_theme.h",
|
||||
"shell/browser/api/electron_api_net.cc",
|
||||
"shell/browser/api/electron_api_net_log.cc",
|
||||
"shell/browser/api/electron_api_net_log.h",
|
||||
"shell/browser/api/electron_api_notification.cc",
|
||||
@@ -309,8 +308,6 @@ filenames = {
|
||||
"shell/browser/api/electron_api_system_preferences.h",
|
||||
"shell/browser/api/electron_api_tray.cc",
|
||||
"shell/browser/api/electron_api_tray.h",
|
||||
"shell/browser/api/electron_api_url_loader.cc",
|
||||
"shell/browser/api/electron_api_url_loader.h",
|
||||
"shell/browser/api/electron_api_utility_process.cc",
|
||||
"shell/browser/api/electron_api_utility_process.h",
|
||||
"shell/browser/api/electron_api_view.cc",
|
||||
@@ -550,8 +547,11 @@ filenames = {
|
||||
"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",
|
||||
"shell/common/api/electron_api_shell.cc",
|
||||
"shell/common/api/electron_api_testing.cc",
|
||||
"shell/common/api/electron_api_url_loader.cc",
|
||||
"shell/common/api/electron_api_url_loader.h",
|
||||
"shell/common/api/electron_api_v8_util.cc",
|
||||
"shell/common/api/electron_bindings.cc",
|
||||
"shell/common/api/electron_bindings.h",
|
||||
@@ -662,7 +662,6 @@ filenames = {
|
||||
"shell/common/node_includes.h",
|
||||
"shell/common/node_util.cc",
|
||||
"shell/common/node_util.h",
|
||||
"shell/common/node_util_mac.mm",
|
||||
"shell/common/options_switches.cc",
|
||||
"shell/common/options_switches.h",
|
||||
"shell/common/platform_util.cc",
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
import { wrapFsWithAsar } from './fs-wrapper';
|
||||
|
||||
wrapFsWithAsar(require('fs'));
|
||||
@@ -50,6 +50,8 @@ const spawnUpdate = function (args: string[], detached: boolean, callback: Funct
|
||||
errorEmitted = false;
|
||||
spawnedProcess.on('error', (error) => {
|
||||
errorEmitted = true;
|
||||
spawnedProcess = undefined;
|
||||
spawnedArgs = [];
|
||||
callback(error);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { net, IncomingMessage, Session as SessionT } from 'electron/main';
|
||||
import { ClientRequestConstructorOptions, ClientRequest, IncomingMessage, Session as SessionT } from 'electron/main';
|
||||
import { Readable, Writable, isReadable } from 'stream';
|
||||
import { allowAnyProtocol } from '@electron/internal/browser/api/net-client-request';
|
||||
import { allowAnyProtocol } from '@electron/internal/common/api/net-client-request';
|
||||
|
||||
function createDeferredPromise<T, E extends Error = Error> (): { promise: Promise<T>; resolve: (x: T) => void; reject: (e: E) => void; } {
|
||||
let res: (x: T) => void;
|
||||
@@ -13,7 +13,8 @@ function createDeferredPromise<T, E extends Error = Error> (): { promise: Promis
|
||||
return { promise, resolve: res!, reject: rej! };
|
||||
}
|
||||
|
||||
export function fetchWithSession (input: RequestInfo, init: (RequestInit & {bypassCustomProtocolHandlers?: boolean}) | undefined, session: SessionT): Promise<Response> {
|
||||
export function fetchWithSession (input: RequestInfo, init: (RequestInit & {bypassCustomProtocolHandlers?: boolean}) | undefined, session: SessionT | undefined,
|
||||
request: (options: ClientRequestConstructorOptions | string) => ClientRequest) {
|
||||
const p = createDeferredPromise<Response>();
|
||||
let req: Request;
|
||||
try {
|
||||
@@ -73,7 +74,7 @@ export function fetchWithSession (input: RequestInfo, init: (RequestInit & {bypa
|
||||
// We can't set credentials to same-origin unless there's an origin set.
|
||||
const credentials = req.credentials === 'same-origin' && !origin ? 'include' : req.credentials;
|
||||
|
||||
const r = net.request(allowAnyProtocol({
|
||||
const r = request(allowAnyProtocol({
|
||||
session,
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { IncomingMessage, session } from 'electron/main';
|
||||
import { app, IncomingMessage, session } from 'electron/main';
|
||||
import type { ClientRequestConstructorOptions } from 'electron/main';
|
||||
import { ClientRequest } from '@electron/internal/browser/api/net-client-request';
|
||||
import { ClientRequest } from '@electron/internal/common/api/net-client-request';
|
||||
|
||||
const { isOnline } = process._linkedBinding('electron_browser_net');
|
||||
const { isOnline } = process._linkedBinding('electron_common_net');
|
||||
|
||||
export function request (options: ClientRequestConstructorOptions | string, callback?: (message: IncomingMessage) => void) {
|
||||
if (!app.isReady()) {
|
||||
throw new Error('net module can only be used after app is ready');
|
||||
}
|
||||
return new ClientRequest(options, callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { fetchWithSession } from '@electron/internal/browser/api/net-fetch';
|
||||
import { net } from 'electron/main';
|
||||
const { fromPartition, fromPath, Session } = process._linkedBinding('electron_browser_session');
|
||||
|
||||
Session.prototype.fetch = function (input: RequestInfo, init?: RequestInit) {
|
||||
return fetchWithSession(input, init, this);
|
||||
return fetchWithSession(input, init, this, net.request);
|
||||
};
|
||||
|
||||
export default {
|
||||
|
||||
@@ -220,6 +220,16 @@ function parsePageSize (pageSize: string | ElectronInternal.PageSize) {
|
||||
let pendingPromise: Promise<any> | undefined;
|
||||
WebContents.prototype.printToPDF = async function (options) {
|
||||
const margins = checkType(options.margins ?? {}, 'object', 'margins');
|
||||
const pageSize = parsePageSize(options.pageSize ?? 'letter');
|
||||
|
||||
const { top, bottom, left, right } = margins;
|
||||
const validHeight = [top, bottom].every(u => u === undefined || u <= pageSize.paperHeight);
|
||||
const validWidth = [left, right].every(u => u === undefined || u <= pageSize.paperWidth);
|
||||
|
||||
if (!validHeight || !validWidth) {
|
||||
throw new Error('margins must be less than or equal to pageSize');
|
||||
}
|
||||
|
||||
const printSettings = {
|
||||
requestID: getNextId(),
|
||||
landscape: checkType(options.landscape ?? false, 'boolean', 'landscape'),
|
||||
@@ -235,7 +245,7 @@ WebContents.prototype.printToPDF = async function (options) {
|
||||
pageRanges: checkType(options.pageRanges ?? '', 'string', 'pageRanges'),
|
||||
preferCSSPageSize: checkType(options.preferCSSPageSize ?? false, 'boolean', 'preferCSSPageSize'),
|
||||
generateTaggedPDF: checkType(options.generateTaggedPDF ?? false, 'boolean', 'generateTaggedPDF'),
|
||||
...parsePageSize(options.pageSize ?? 'letter')
|
||||
...pageSize
|
||||
};
|
||||
|
||||
if (this._printToPDF) {
|
||||
@@ -252,13 +262,11 @@ WebContents.prototype.printToPDF = async function (options) {
|
||||
|
||||
// TODO(codebytere): deduplicate argument sanitization by moving rest of
|
||||
// print param logic into new file shared between printToPDF and print
|
||||
WebContents.prototype.print = function (options: ElectronInternal.WebContentsPrintOptions, callback) {
|
||||
if (typeof options !== 'object') {
|
||||
WebContents.prototype.print = function (options: ElectronInternal.WebContentsPrintOptions = {}, callback) {
|
||||
if (typeof options !== 'object' || options == null) {
|
||||
throw new TypeError('webContents.print(): Invalid print settings specified.');
|
||||
}
|
||||
|
||||
const printSettings: Record<string, any> = { ...options };
|
||||
|
||||
const pageSize = options.pageSize ?? 'A4';
|
||||
if (typeof pageSize === 'object') {
|
||||
if (!pageSize.height || !pageSize.width) {
|
||||
@@ -272,7 +280,7 @@ WebContents.prototype.print = function (options: ElectronInternal.WebContentsPri
|
||||
throw new RangeError('height and width properties must be minimum 352 microns.');
|
||||
}
|
||||
|
||||
printSettings.mediaSize = {
|
||||
options.mediaSize = {
|
||||
name: 'CUSTOM',
|
||||
custom_display_name: 'Custom',
|
||||
height_microns: height,
|
||||
@@ -284,7 +292,7 @@ WebContents.prototype.print = function (options: ElectronInternal.WebContentsPri
|
||||
};
|
||||
} else if (typeof pageSize === 'string' && PDFPageSizes[pageSize]) {
|
||||
const mediaSize = PDFPageSizes[pageSize];
|
||||
printSettings.mediaSize = {
|
||||
options.mediaSize = {
|
||||
...mediaSize,
|
||||
imageable_area_left_microns: 0,
|
||||
imageable_area_bottom_microns: 0,
|
||||
@@ -297,9 +305,9 @@ WebContents.prototype.print = function (options: ElectronInternal.WebContentsPri
|
||||
|
||||
if (this._print) {
|
||||
if (callback) {
|
||||
this._print(printSettings, callback);
|
||||
this._print(options, callback);
|
||||
} else {
|
||||
this._print(printSettings);
|
||||
this._print(options);
|
||||
}
|
||||
} else {
|
||||
console.error('Error: Printing feature is disabled.');
|
||||
|
||||
@@ -14,7 +14,7 @@ interface GuestInstance {
|
||||
}
|
||||
|
||||
const webViewManager = process._linkedBinding('electron_browser_web_view_manager');
|
||||
const netBinding = process._linkedBinding('electron_browser_net');
|
||||
const netBinding = process._linkedBinding('electron_common_net');
|
||||
|
||||
const supportedWebViewEvents = Object.keys(webViewEvents);
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
import type * as defaultMenuModule from '@electron/internal/browser/default-menu';
|
||||
import type * as url from 'url';
|
||||
import type * as v8 from 'v8';
|
||||
|
||||
const Module = require('module') as NodeJS.ModuleInternal;
|
||||
|
||||
@@ -10,9 +12,6 @@ const Module = require('module') as NodeJS.ModuleInternal;
|
||||
// we need to restore it here.
|
||||
process.argv.splice(1, 1);
|
||||
|
||||
// Clear search paths.
|
||||
require('../common/reset-search-paths');
|
||||
|
||||
// Import common settings.
|
||||
require('@electron/internal/common/init');
|
||||
|
||||
@@ -135,7 +134,7 @@ if (packageJson.desktopName != null) {
|
||||
// Set v8 flags, deliberately lazy load so that apps that do not use this
|
||||
// feature do not pay the price
|
||||
if (packageJson.v8Flags != null) {
|
||||
require('v8').setFlagsFromString(packageJson.v8Flags);
|
||||
(require('v8') as typeof v8).setFlagsFromString(packageJson.v8Flags);
|
||||
}
|
||||
|
||||
app.setAppPath(packagePath);
|
||||
@@ -198,7 +197,7 @@ if (packagePath) {
|
||||
// Finally load app's main.js and transfer control to C++.
|
||||
if ((packageJson.type === 'module' && !mainStartupScript.endsWith('.cjs')) || mainStartupScript.endsWith('.mjs')) {
|
||||
const { loadESM } = __non_webpack_require__('internal/process/esm_loader');
|
||||
const main = require('url').pathToFileURL(path.join(packagePath, mainStartupScript));
|
||||
const main = (require('url') as typeof url).pathToFileURL(path.join(packagePath, mainStartupScript));
|
||||
loadESM(async (esmLoader: any) => {
|
||||
try {
|
||||
await esmLoader.import(main.toString(), undefined, Object.create(null));
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import * as url from 'url';
|
||||
import { Readable, Writable } from 'stream';
|
||||
import { app } from 'electron/main';
|
||||
import type { ClientRequestConstructorOptions, UploadProgress } from 'electron/main';
|
||||
import type {
|
||||
ClientRequestConstructorOptions,
|
||||
UploadProgress
|
||||
} from 'electron/common';
|
||||
|
||||
const {
|
||||
isValidHeaderName,
|
||||
isValidHeaderValue,
|
||||
createURLLoader
|
||||
} = process._linkedBinding('electron_browser_net');
|
||||
const { Session } = process._linkedBinding('electron_browser_session');
|
||||
} = process._linkedBinding('electron_common_net');
|
||||
|
||||
const kHttpProtocols = new Set(['http:', 'https:']);
|
||||
|
||||
@@ -283,14 +284,17 @@ function parseOptions (optionsIn: ClientRequestConstructorOptions | string): Nod
|
||||
const key = name.toLowerCase();
|
||||
urlLoaderOptions.headers[key] = { name, value };
|
||||
}
|
||||
if (options.session) {
|
||||
if (!(options.session instanceof Session)) { throw new TypeError('`session` should be an instance of the Session class'); }
|
||||
urlLoaderOptions.session = options.session;
|
||||
} else if (options.partition) {
|
||||
if (typeof options.partition === 'string') {
|
||||
urlLoaderOptions.partition = options.partition;
|
||||
} else {
|
||||
throw new TypeError('`partition` should be a string');
|
||||
if (process.type !== 'utility') {
|
||||
const { Session } = process._linkedBinding('electron_browser_session');
|
||||
if (options.session) {
|
||||
if (!(options.session instanceof Session)) { throw new TypeError('`session` should be an instance of the Session class'); }
|
||||
urlLoaderOptions.session = options.session;
|
||||
} else if (options.partition) {
|
||||
if (typeof options.partition === 'string') {
|
||||
urlLoaderOptions.partition = options.partition;
|
||||
} else {
|
||||
throw new TypeError('`partition` should be a string');
|
||||
}
|
||||
}
|
||||
}
|
||||
return urlLoaderOptions;
|
||||
@@ -312,10 +316,6 @@ export class ClientRequest extends Writable implements Electron.ClientRequest {
|
||||
constructor (options: ClientRequestConstructorOptions | string, callback?: (message: IncomingMessage) => void) {
|
||||
super({ autoDestroy: true });
|
||||
|
||||
if (!app.isReady()) {
|
||||
throw new Error('net module can only be used after app is ready');
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
this.once('response', callback);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as util from 'util';
|
||||
import type * as stream from 'stream';
|
||||
|
||||
const timers = require('timers');
|
||||
import timers = require('timers');
|
||||
|
||||
type AnyFn = (...args: any[]) => any
|
||||
|
||||
@@ -62,7 +63,7 @@ if (process.type === 'browser' ||
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
// Always returns EOF for stdin stream.
|
||||
const { Readable } = require('stream');
|
||||
const { Readable } = require('stream') as typeof stream;
|
||||
const stdin = new Readable();
|
||||
stdin.push(null);
|
||||
Object.defineProperty(process, 'stdin', {
|
||||
@@ -73,3 +74,43 @@ if (process.platform === 'win32') {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const Module = require('module') as NodeJS.ModuleInternal;
|
||||
|
||||
// Make a fake Electron module that we will insert into the module cache
|
||||
const makeElectronModule = (name: string) => {
|
||||
const electronModule = new Module('electron', null);
|
||||
electronModule.id = 'electron';
|
||||
electronModule.loaded = true;
|
||||
electronModule.filename = name;
|
||||
Object.defineProperty(electronModule, 'exports', {
|
||||
get: () => require('electron')
|
||||
});
|
||||
Module._cache[name] = electronModule;
|
||||
};
|
||||
|
||||
makeElectronModule('electron');
|
||||
makeElectronModule('electron/common');
|
||||
if (process.type === 'browser') {
|
||||
makeElectronModule('electron/main');
|
||||
}
|
||||
if (process.type === 'renderer') {
|
||||
makeElectronModule('electron/renderer');
|
||||
}
|
||||
|
||||
const originalResolveFilename = Module._resolveFilename;
|
||||
|
||||
// 'electron/main', 'electron/renderer' and 'electron/common' are module aliases
|
||||
// of the 'electron' module for TypeScript purposes, i.e., the types for
|
||||
// 'electron/main' consist of only main process modules, etc. It is intentional
|
||||
// that these can be `require()`-ed from both the main process as well as the
|
||||
// renderer process regardless of the names, they're superficial for TypeScript
|
||||
// only.
|
||||
const electronModuleNames = new Set(['electron', 'electron/main', 'electron/renderer', 'electron/common']);
|
||||
Module._resolveFilename = function (request, parent, isMain, options) {
|
||||
if (electronModuleNames.has(request)) {
|
||||
return 'electron';
|
||||
} else {
|
||||
return originalResolveFilename(request, parent, isMain, options);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
import * as path from 'path';
|
||||
|
||||
const Module = require('module') as NodeJS.ModuleInternal;
|
||||
|
||||
// We do not want to allow use of the VM module in the renderer process as
|
||||
// it conflicts with Blink's V8::Context internal logic.
|
||||
if (process.type === 'renderer') {
|
||||
const _load = Module._load;
|
||||
Module._load = function (request: string) {
|
||||
if (request === 'vm') {
|
||||
console.warn('The vm module of Node.js is deprecated in the renderer process and will be removed.');
|
||||
}
|
||||
return _load.apply(this, arguments as any);
|
||||
};
|
||||
}
|
||||
|
||||
// Prevent Node from adding paths outside this app to search paths.
|
||||
const resourcesPathWithTrailingSlash = process.resourcesPath + path.sep;
|
||||
const originalNodeModulePaths = Module._nodeModulePaths;
|
||||
Module._nodeModulePaths = function (from: string) {
|
||||
const paths: string[] = originalNodeModulePaths(from);
|
||||
const fromPath = path.resolve(from) + path.sep;
|
||||
// If "from" is outside the app then we do nothing.
|
||||
if (fromPath.startsWith(resourcesPathWithTrailingSlash)) {
|
||||
return paths.filter(function (candidate) {
|
||||
return candidate.startsWith(resourcesPathWithTrailingSlash);
|
||||
});
|
||||
} else {
|
||||
return paths;
|
||||
}
|
||||
};
|
||||
|
||||
// Make a fake Electron module that we will insert into the module cache
|
||||
const makeElectronModule = (name: string) => {
|
||||
const electronModule = new Module('electron', null);
|
||||
electronModule.id = 'electron';
|
||||
electronModule.loaded = true;
|
||||
electronModule.filename = name;
|
||||
Object.defineProperty(electronModule, 'exports', {
|
||||
get: () => require('electron')
|
||||
});
|
||||
Module._cache[name] = electronModule;
|
||||
};
|
||||
|
||||
makeElectronModule('electron');
|
||||
makeElectronModule('electron/common');
|
||||
if (process.type === 'browser') {
|
||||
makeElectronModule('electron/main');
|
||||
}
|
||||
if (process.type === 'renderer') {
|
||||
makeElectronModule('electron/renderer');
|
||||
}
|
||||
|
||||
const originalResolveFilename = Module._resolveFilename;
|
||||
|
||||
// 'electron/main', 'electron/renderer' and 'electron/common' are module aliases
|
||||
// of the 'electron' module for TypeScript purposes, i.e., the types for
|
||||
// 'electron/main' consist of only main process modules, etc. It is intentional
|
||||
// that these can be `require()`-ed from both the main process as well as the
|
||||
// renderer process regardless of the names, they're superficial for TypeScript
|
||||
// only.
|
||||
const electronModuleNames = new Set(['electron', 'electron/main', 'electron/renderer', 'electron/common']);
|
||||
Module._resolveFilename = function (request, parent, isMain, options) {
|
||||
if (electronModuleNames.has(request)) {
|
||||
return 'electron';
|
||||
} else {
|
||||
return originalResolveFilename(request, parent, isMain, options);
|
||||
}
|
||||
};
|
||||
@@ -2,7 +2,9 @@ import { Buffer } from 'buffer';
|
||||
import { constants } from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as util from 'util';
|
||||
|
||||
import type * as Crypto from 'crypto';
|
||||
import type * as os from 'os';
|
||||
|
||||
const asar = process._linkedBinding('electron_common_asar');
|
||||
|
||||
@@ -255,7 +257,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
if (!process.env.ELECTRON_LOG_ASAR_READS) return;
|
||||
if (!logFDs.has(asarPath)) {
|
||||
const logFilename = `${path.basename(asarPath, '.asar')}-access-log.txt`;
|
||||
const logPath = path.join(require('os').tmpdir(), logFilename);
|
||||
const logPath = path.join((require('os') as typeof os).tmpdir(), logFilename);
|
||||
logFDs.set(asarPath, fs.openSync(logPath, 'a'));
|
||||
}
|
||||
fs.writeSync(logFDs.get(asarPath), `${offset}: ${filePath}\n`);
|
||||
49
lib/node/init.ts
Normal file
49
lib/node/init.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
// Initialize ASAR support in fs module.
|
||||
import { wrapFsWithAsar } from './asar-fs-wrapper';
|
||||
wrapFsWithAsar(require('fs'));
|
||||
|
||||
// Hook child_process.fork.
|
||||
import cp = require('child_process'); // eslint-disable-line import/first
|
||||
const originalFork = cp.fork;
|
||||
cp.fork = (modulePath, args?, options?: cp.ForkOptions) => {
|
||||
// Parse optional args.
|
||||
if (args == null) {
|
||||
args = [];
|
||||
} else if (typeof args === 'object' && !Array.isArray(args)) {
|
||||
options = args as cp.ForkOptions;
|
||||
args = [];
|
||||
}
|
||||
// Fallback to original fork to report arg type errors.
|
||||
if (typeof modulePath !== 'string' || !Array.isArray(args) ||
|
||||
(typeof options !== 'object' && typeof options !== 'undefined')) {
|
||||
return originalFork(modulePath, args, options);
|
||||
}
|
||||
// When forking a child script, we setup a special environment to make
|
||||
// the electron binary run like upstream Node.js.
|
||||
options = options ?? {};
|
||||
options.env = Object.create(options.env || process.env);
|
||||
options.env!.ELECTRON_RUN_AS_NODE = '1';
|
||||
// On mac the child script runs in helper executable.
|
||||
if (!options.execPath && process.platform === 'darwin') {
|
||||
options.execPath = process.helperExecPath;
|
||||
}
|
||||
return originalFork(modulePath, args, options);
|
||||
};
|
||||
|
||||
// Prevent Node from adding paths outside this app to search paths.
|
||||
import path = require('path'); // eslint-disable-line import/first
|
||||
const Module = require('module') as NodeJS.ModuleInternal;
|
||||
const resourcesPathWithTrailingSlash = process.resourcesPath + path.sep;
|
||||
const originalNodeModulePaths = Module._nodeModulePaths;
|
||||
Module._nodeModulePaths = function (from) {
|
||||
const paths: string[] = originalNodeModulePaths(from);
|
||||
const fromPath = path.resolve(from) + path.sep;
|
||||
// If "from" is outside the app then we do nothing.
|
||||
if (fromPath.startsWith(resourcesPathWithTrailingSlash)) {
|
||||
return paths.filter(function (candidate) {
|
||||
return candidate.startsWith(resourcesPathWithTrailingSlash);
|
||||
});
|
||||
} else {
|
||||
return paths;
|
||||
}
|
||||
};
|
||||
@@ -7,6 +7,16 @@ import type * as ipcRendererUtilsModule from '@electron/internal/renderer/ipc-re
|
||||
|
||||
const Module = require('module') as NodeJS.ModuleInternal;
|
||||
|
||||
// We do not want to allow use of the VM module in the renderer process as
|
||||
// it conflicts with Blink's V8::Context internal logic.
|
||||
const originalModuleLoad = Module._load;
|
||||
Module._load = function (request: string) {
|
||||
if (request === 'vm') {
|
||||
console.warn('The vm module of Node.js is deprecated in the renderer process and will be removed.');
|
||||
}
|
||||
return originalModuleLoad.apply(this, arguments as any);
|
||||
};
|
||||
|
||||
// Make sure globals like "process" and "global" are always available in preload
|
||||
// scripts even after they are deleted in "loaded" script.
|
||||
//
|
||||
@@ -33,9 +43,6 @@ Module.wrapper = [
|
||||
// init.js, we need to restore it here.
|
||||
process.argv.splice(1, 1);
|
||||
|
||||
// Clear search paths.
|
||||
require('../common/reset-search-paths');
|
||||
|
||||
// Import common settings.
|
||||
require('@electron/internal/common/init');
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as events from 'events';
|
||||
import { setImmediate, clearImmediate } from 'timers';
|
||||
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
|
||||
|
||||
import type * as ipcRendererUtilsModule from '@electron/internal/renderer/ipc-renderer-internal-utils';
|
||||
@@ -126,7 +127,6 @@ function runPreloadScript (preloadSrc: string) {
|
||||
|
||||
// eval in window scope
|
||||
const preloadFn = binding.createPreloadScript(preloadWrapperSrc);
|
||||
const { setImmediate, clearImmediate } = require('timers');
|
||||
const exports = {};
|
||||
|
||||
preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate, clearImmediate, exports, { exports });
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
// Utility side modules, please sort alphabetically.
|
||||
export const utilityNodeModuleList: ElectronInternal.ModuleEntry[] = [];
|
||||
export const utilityNodeModuleList: ElectronInternal.ModuleEntry[] = [
|
||||
{ name: 'net', loader: () => require('./net') }
|
||||
];
|
||||
|
||||
22
lib/utility/api/net.ts
Normal file
22
lib/utility/api/net.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { IncomingMessage } from 'electron/utility';
|
||||
import type { ClientRequestConstructorOptions } from 'electron/utility';
|
||||
import { ClientRequest } from '@electron/internal/common/api/net-client-request';
|
||||
import { fetchWithSession } from '@electron/internal/browser/api/net-fetch';
|
||||
|
||||
const { isOnline, resolveHost } = process._linkedBinding('electron_common_net');
|
||||
|
||||
export function request (options: ClientRequestConstructorOptions | string, callback?: (message: IncomingMessage) => void) {
|
||||
return new ClientRequest(options, callback);
|
||||
}
|
||||
|
||||
export function fetch (input: RequestInfo, init?: RequestInit): Promise<Response> {
|
||||
return fetchWithSession(input, init, undefined, request);
|
||||
}
|
||||
|
||||
exports.resolveHost = resolveHost;
|
||||
|
||||
exports.isOnline = isOnline;
|
||||
|
||||
Object.defineProperty(exports, 'online', {
|
||||
get: () => isOnline()
|
||||
});
|
||||
@@ -1,3 +1,4 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import { pathToFileURL } from 'url';
|
||||
|
||||
import { ParentPort } from '@electron/internal/utility/parent-port';
|
||||
@@ -9,12 +10,11 @@ const entryScript: string = v8Util.getHiddenValue(process, '_serviceStartupScrip
|
||||
// we need to restore it here.
|
||||
process.argv.splice(1, 1, entryScript);
|
||||
|
||||
// Clear search paths.
|
||||
require('../common/reset-search-paths');
|
||||
|
||||
// Import common settings.
|
||||
require('@electron/internal/common/init');
|
||||
|
||||
process._linkedBinding('electron_browser_event_emitter').setEventEmitterPrototype(EventEmitter.prototype);
|
||||
|
||||
const parentPort: ParentPort = new ParentPort();
|
||||
Object.defineProperty(process, 'parentPort', {
|
||||
enumerable: true,
|
||||
|
||||
@@ -6,9 +6,6 @@ const Module = require('module') as NodeJS.ModuleInternal;
|
||||
// init.js, we need to restore it here.
|
||||
process.argv.splice(1, 1);
|
||||
|
||||
// Clear search paths.
|
||||
require('../common/reset-search-paths');
|
||||
|
||||
// Import common settings.
|
||||
require('@electron/internal/common/init');
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
"devDependencies": {
|
||||
"@azure/storage-blob": "^12.9.0",
|
||||
"@electron/asar": "^3.2.1",
|
||||
"@electron/docs-parser": "^1.1.1",
|
||||
"@electron/docs-parser": "^1.2.0",
|
||||
"@electron/fiddle-core": "^1.0.4",
|
||||
"@electron/github-app-auth": "^2.0.0",
|
||||
"@electron/lint-roller": "^1.9.0",
|
||||
"@electron/typescript-definitions": "^8.14.5",
|
||||
"@electron/typescript-definitions": "^8.15.2",
|
||||
"@octokit/rest": "^19.0.7",
|
||||
"@primer/octicons": "^10.0.0",
|
||||
"@types/basic-auth": "^1.1.3",
|
||||
|
||||
1
patches/angle/.patches
Normal file
1
patches/angle/.patches
Normal file
@@ -0,0 +1 @@
|
||||
m123_vulkan_fix_access_to_inactive_attributes.patch
|
||||
@@ -0,0 +1,112 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Lang <geofflang@chromium.org>
|
||||
Date: Tue, 12 Mar 2024 16:06:37 -0400
|
||||
Subject: M123: Vulkan: Fix access to inactive attributes
|
||||
|
||||
... within range of active ones. Since a buffer is bound for inactive
|
||||
attributes, it must be considered accessed.
|
||||
|
||||
Ultimately, the nullDescriptor feature could be used to avoid binding a
|
||||
buffer for inactive attributes.
|
||||
|
||||
Bug: chromium:327807820
|
||||
Change-Id: I953b419d8ec51760e8848409024cad5083888fa2
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5386431
|
||||
Reviewed-by: Shahbaz Youssefi <syoussefi@google.com>
|
||||
|
||||
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
|
||||
index 4849b95b25309a191e45a7eb39bb114ebc7376b1..a37e2865f9d49f576cec39845b66f3a0bdfd1652 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
|
||||
@@ -2607,8 +2607,7 @@ angle::Result ContextVk::handleDirtyGraphicsVertexBuffers(DirtyBits::Iterator *d
|
||||
vertexArrayVk->getCurrentArrayBuffers();
|
||||
|
||||
// Mark all active vertex buffers as accessed.
|
||||
- const gl::AttributesMask attribsMask = executable->getActiveAttribLocationsMask();
|
||||
- for (size_t attribIndex : attribsMask)
|
||||
+ for (uint32_t attribIndex = 0; attribIndex < maxAttrib; ++attribIndex)
|
||||
{
|
||||
vk::BufferHelper *arrayBuffer = arrayBufferResources[attribIndex];
|
||||
if (arrayBuffer)
|
||||
diff --git a/src/tests/gl_tests/VertexAttributeTest.cpp b/src/tests/gl_tests/VertexAttributeTest.cpp
|
||||
index 010662aded3f22a487230c24de1cda9de42cc334..a51322ee27309c8aeb146b1288099a68b258386f 100644
|
||||
--- a/src/tests/gl_tests/VertexAttributeTest.cpp
|
||||
+++ b/src/tests/gl_tests/VertexAttributeTest.cpp
|
||||
@@ -1200,6 +1200,19 @@ class VertexAttributeOORTest : public VertexAttributeTest
|
||||
}
|
||||
};
|
||||
|
||||
+class RobustVertexAttributeTest : public VertexAttributeTest
|
||||
+{
|
||||
+ public:
|
||||
+ RobustVertexAttributeTest()
|
||||
+ {
|
||||
+ // mac GL and metal do not support robustness.
|
||||
+ if (!IsMac() && !IsIOS())
|
||||
+ {
|
||||
+ setRobustAccess(true);
|
||||
+ }
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
// Verify that drawing with a large out-of-range offset generates INVALID_OPERATION.
|
||||
// Requires WebGL compatibility with robust access behaviour disabled.
|
||||
TEST_P(VertexAttributeOORTest, ANGLEDrawArraysBufferTooSmall)
|
||||
@@ -1260,6 +1273,48 @@ TEST_P(VertexAttributeOORTest, ANGLEDrawArraysOutOfBoundsCases)
|
||||
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
|
||||
}
|
||||
|
||||
+// Test that enabling a buffer in an unused attribute doesn't crash. There should be an active
|
||||
+// attribute after that.
|
||||
+TEST_P(RobustVertexAttributeTest, BoundButUnusedBuffer)
|
||||
+{
|
||||
+ constexpr char kVS[] = R"(attribute vec2 offset;
|
||||
+void main()
|
||||
+{
|
||||
+ gl_Position = vec4(offset.xy, 0, 1);
|
||||
+ gl_PointSize = 1.0;
|
||||
+})";
|
||||
+
|
||||
+ constexpr char kFS[] = R"(precision mediump float;
|
||||
+void main()
|
||||
+{
|
||||
+ gl_FragColor = vec4(1.0, 0, 0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ const GLuint vs = CompileShader(GL_VERTEX_SHADER, kVS);
|
||||
+ const GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
|
||||
+
|
||||
+ GLuint program = glCreateProgram();
|
||||
+ glBindAttribLocation(program, 1, "offset");
|
||||
+ glAttachShader(program, vs);
|
||||
+ glAttachShader(program, fs);
|
||||
+ glLinkProgram(program);
|
||||
+
|
||||
+ GLBuffer buffer;
|
||||
+ glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
+ glBufferData(GL_ARRAY_BUFFER, 100, nullptr, GL_STATIC_DRAW);
|
||||
+
|
||||
+ // Enable an unused attribute that is within the range of active attributes (not beyond it)
|
||||
+ glEnableVertexAttribArray(0);
|
||||
+ glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
|
||||
+
|
||||
+ glUseProgram(program);
|
||||
+ glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
+
|
||||
+ // Destroy the buffer. Regression test for a tracking bug where the buffer was used by
|
||||
+ // SwiftShader (even though location 1 is inactive), but not marked as used by ANGLE.
|
||||
+ buffer.reset();
|
||||
+}
|
||||
+
|
||||
// Verify that using a different start vertex doesn't mess up the draw.
|
||||
TEST_P(VertexAttributeTest, DrawArraysWithBufferOffset)
|
||||
{
|
||||
@@ -4739,6 +4794,8 @@ ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(
|
||||
ES3_METAL().disable(Feature::HasExplicitMemBarrier).disable(Feature::HasCheapRenderPass),
|
||||
ES3_METAL().disable(Feature::HasExplicitMemBarrier).enable(Feature::HasCheapRenderPass));
|
||||
|
||||
+ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(RobustVertexAttributeTest);
|
||||
+
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VertexAttributeTestES3);
|
||||
ANGLE_INSTANTIATE_TEST_ES3_AND(
|
||||
VertexAttributeTestES3,
|
||||
@@ -142,3 +142,12 @@ fix_restore_original_resize_performance_on_macos.patch
|
||||
fix_font_flooding_in_dev_tools.patch
|
||||
feat_allow_code_cache_in_custom_schemes.patch
|
||||
enable_partition_alloc_ref_count_size.patch
|
||||
ensure_an_axcontext_before_painting.patch
|
||||
safely_crash_on_dangling_profile.patch
|
||||
prevent_mojotrap_event_re-ordering.patch
|
||||
m122_cherry_pick_cve-2024-25062_libxml_fix.patch
|
||||
allowlist_devtools_for_file_access_permission.patch
|
||||
update_crashpad_to_37afd37401253ebcebcf6e07ce15c8cfecb1a1cc.patch
|
||||
m122_webcodecs_disable_async_videoframe_readback_to_mitigate_a.patch
|
||||
fix_paintimage_deserialization_arbitrary-read_issue.patch
|
||||
reland_sensors_winrt_call_onreadingchangedcallback_via.patch
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yang Guo <yangguo@chromium.org>
|
||||
Date: Tue, 19 Dec 2023 19:34:20 +0000
|
||||
Subject: Allowlist devtools:// for file access permission
|
||||
|
||||
Otherwise DevTools features which save logs to the filesystem are
|
||||
affected by content permissions, which contradicts developer
|
||||
expectations.
|
||||
|
||||
Fixed: 1483230
|
||||
Change-Id: Ia0848a9a192b2803a64f4104f4032219d6f3a885
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5132146
|
||||
Auto-Submit: Yang Guo <yangguo@chromium.org>
|
||||
Reviewed-by: Christian Dullweber <dullweber@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1239281}
|
||||
|
||||
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
|
||||
index 38464529cc74e7b17373e1dd4f7bfd8cc68ff796..99323d6453749edd98f0cace905e9c5312620825 100644
|
||||
--- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc
|
||||
+++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
|
||||
@@ -2354,3 +2354,26 @@ TEST_F(HostContentSettingsMapTest, IncognitoInheritSaaAndRenew) {
|
||||
ContentSetting::CONTENT_SETTING_ALLOW);
|
||||
EXPECT_EQ(CONTENT_SETTING_ASK, otr_map->GetContentSetting(host, host, type));
|
||||
}
|
||||
+
|
||||
+// File access is not implemented on Android. Luckily we don't need it for DevTools.
|
||||
+#if !BUILDFLAG(IS_ANDROID)
|
||||
+TEST_F(HostContentSettingsMapTest, DevToolsFileAccess) {
|
||||
+ TestingProfile profile;
|
||||
+ HostContentSettingsMap* host_content_settings_map =
|
||||
+ HostContentSettingsMapFactory::GetForProfile(&profile);
|
||||
+
|
||||
+ GURL devtools_host("devtools://devtools/bundled/devtools_app.html");
|
||||
+ GURL example_host("https://example.com");
|
||||
+
|
||||
+ host_content_settings_map->SetDefaultContentSetting(
|
||||
+ ContentSettingsType::FILE_SYSTEM_WRITE_GUARD, CONTENT_SETTING_BLOCK);
|
||||
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
|
||||
+ host_content_settings_map->GetContentSetting(
|
||||
+ devtools_host, devtools_host,
|
||||
+ ContentSettingsType::FILE_SYSTEM_WRITE_GUARD));
|
||||
+ EXPECT_EQ(CONTENT_SETTING_BLOCK,
|
||||
+ host_content_settings_map->GetContentSetting(
|
||||
+ example_host, example_host,
|
||||
+ ContentSettingsType::FILE_SYSTEM_WRITE_GUARD));
|
||||
+}
|
||||
+#endif // !BUILDFLAG(IS_ANDROID)
|
||||
diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc
|
||||
index 8021bd809315debd7171350187bbd684c23fd882..69c66a5e68f6a137875df19993a959000c56a2e6 100644
|
||||
--- a/components/content_settings/core/browser/content_settings_registry.cc
|
||||
+++ b/components/content_settings/core/browser/content_settings_registry.cc
|
||||
@@ -425,7 +425,8 @@ void ContentSettingsRegistry::Init() {
|
||||
|
||||
Register(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
|
||||
"file-system-write-guard", CONTENT_SETTING_ASK,
|
||||
- WebsiteSettingsInfo::UNSYNCABLE, /*allowlisted_schemes=*/{},
|
||||
+ WebsiteSettingsInfo::UNSYNCABLE,
|
||||
+ /*allowlisted_primary_schemes=*/{kChromeDevToolsScheme},
|
||||
/*valid_settings=*/
|
||||
{CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK},
|
||||
WebsiteSettingsInfo::TOP_ORIGIN_ONLY_SCOPE,
|
||||
@@ -33,7 +33,7 @@ index 0594fc8f8122b5f66457c262890ea93be3a579d8..19f045d14c6072c1b0b8fb6a50bf4caf
|
||||
"//base",
|
||||
"//build:branding_buildflags",
|
||||
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
|
||||
index 44d3b5e543101ce7ff5fed778fc430532e7ae9fb..48799f517e4b83f157c86e9b579cd98007fa47d7 100644
|
||||
index cd46c4c79d47637d3b1364a44f6b2fb54976a979..2ca8c638b78dfba0e2dc491163f028892c4d5376 100644
|
||||
--- a/chrome/browser/BUILD.gn
|
||||
+++ b/chrome/browser/BUILD.gn
|
||||
@@ -4821,7 +4821,7 @@ static_library("browser") {
|
||||
|
||||
@@ -21,10 +21,10 @@ index c1a712883d4b5af6d77d2174589f2f95625cb05e..390866ca02889c9c7dc58561f32d2e19
|
||||
&no_javascript_access);
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 63eafd910dad5686ca4114468e4563082821dd01..daeece42f6fe4e57ca3f88ff7b5d9d0a1c142b9f 100644
|
||||
index dba3fa7b487fe9fb7ff975df647ac30f2ffbd202..910ea0d1e11e1dc3deb660b322b67bf223735822 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -4487,6 +4487,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -4492,6 +4492,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
|
||||
auto* new_contents_impl = new_contents.get();
|
||||
|
||||
@@ -37,7 +37,7 @@ index 63eafd910dad5686ca4114468e4563082821dd01..daeece42f6fe4e57ca3f88ff7b5d9d0a
|
||||
// If the new frame has a name, make sure any SiteInstances that can find
|
||||
// this named frame have proxies for it. Must be called after
|
||||
// SetSessionStorageNamespace, since this calls CreateRenderView, which uses
|
||||
@@ -4528,12 +4534,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -4533,12 +4539,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
AddWebContentsDestructionObserver(new_contents_impl);
|
||||
}
|
||||
|
||||
|
||||
@@ -218,10 +218,10 @@ index 46924048ef26310b25d8ce7dd370c086193cf7ea..28a2b8c99b2cf32bb283ef1474b536ab
|
||||
void AddNewContents(content::WebContents* source,
|
||||
std::unique_ptr<content::WebContents> new_contents,
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 744f3757ab2e7bcf517ddae6f5023ac52822a06a..d36306fc177824701ddde81dbd399e77230b1c48 100644
|
||||
index dc413782fc0e7f33011e80a2357d6eba75a6903a..702fa31c9e95d83cbd856f6592050835cd27ccd2 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -4393,8 +4393,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -4398,8 +4398,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
|
||||
if (delegate_ && delegate_->IsWebContentsCreationOverridden(
|
||||
source_site_instance, params.window_container_type,
|
||||
|
||||
159
patches/chromium/ensure_an_axcontext_before_painting.patch
Normal file
159
patches/chromium/ensure_an_axcontext_before_painting.patch
Normal file
@@ -0,0 +1,159 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Harrelson <chrishtr@chromium.org>
|
||||
Date: Thu, 4 Jan 2024 18:26:31 +0000
|
||||
Subject: Ensure an AXContext before painting.
|
||||
|
||||
Before this CL, if a node was highlighted in an iframe, an AXContext
|
||||
may not have been initialized before painting began, which is a
|
||||
rendering lifecycle error.
|
||||
|
||||
Fixed: 1515088
|
||||
|
||||
Change-Id: I0f95ad59c3c982b43b2ac4beddc76414a67d22c6
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5165954
|
||||
Reviewed-by: Vladimir Levin <vmpstr@chromium.org>
|
||||
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1243003}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.cc b/third_party/blink/renderer/core/inspector/inspect_tools.cc
|
||||
index 4be51d41702c006b89d0e7b57bf10cb7c107bcbb..6fa5b9145903fa09e25513ff860cfc60c03dc689 100644
|
||||
--- a/third_party/blink/renderer/core/inspector/inspect_tools.cc
|
||||
+++ b/third_party/blink/renderer/core/inspector/inspect_tools.cc
|
||||
@@ -179,7 +179,7 @@ void SearchingForNodeTool::Draw(float scale) {
|
||||
!omit_tooltip_ && highlight_config_->show_info &&
|
||||
node->GetLayoutObject() &&
|
||||
node->GetDocument().GetFrame();
|
||||
- overlay_->EnsureAXContext(node);
|
||||
+ DCHECK(overlay_->HasAXContext(node));
|
||||
InspectorHighlight highlight(node, *highlight_config_, contrast_info_,
|
||||
append_element_info, false,
|
||||
content_visibility_state_);
|
||||
@@ -251,6 +251,7 @@ bool SearchingForNodeTool::HandleMouseMove(const WebMouseEvent& event) {
|
||||
// Store values for the highlight.
|
||||
bool hovered_node_changed = node != hovered_node_;
|
||||
hovered_node_ = node;
|
||||
+ overlay_->EnsureAXContext(node);
|
||||
event_target_node_ = (event.GetModifiers() & WebInputEvent::kShiftKey)
|
||||
? HoveredNodeForEvent(frame, event, false)
|
||||
: nullptr;
|
||||
@@ -361,6 +362,7 @@ NodeHighlightTool::NodeHighlightTool(
|
||||
if (auto* flexbox = DynamicTo<LayoutFlexibleBox>(node->GetLayoutObject())) {
|
||||
flexbox->SetNeedsLayoutForDevtools();
|
||||
}
|
||||
+ overlay_->EnsureAXContext(node);
|
||||
}
|
||||
|
||||
String NodeHighlightTool::GetOverlayName() {
|
||||
@@ -406,8 +408,7 @@ void NodeHighlightTool::DrawMatchingSelector() {
|
||||
ContainerNode* query_base = node_->ContainingShadowRoot();
|
||||
if (!query_base)
|
||||
query_base = node_->ownerDocument();
|
||||
-
|
||||
- overlay_->EnsureAXContext(query_base);
|
||||
+ DCHECK(overlay_->HasAXContext(query_base));
|
||||
|
||||
StaticElementList* elements = query_base->QuerySelectorAll(
|
||||
AtomicString(selector_list_), exception_state);
|
||||
@@ -438,7 +439,7 @@ std::unique_ptr<protocol::DictionaryValue>
|
||||
NodeHighlightTool::GetNodeInspectorHighlightAsJson(
|
||||
bool append_element_info,
|
||||
bool append_distance_info) const {
|
||||
- overlay_->EnsureAXContext(node_.Get());
|
||||
+ DCHECK(overlay_->HasAXContext(node_.Get()));
|
||||
InspectorHighlight highlight(node_.Get(), *highlight_config_, contrast_info_,
|
||||
append_element_info, append_distance_info,
|
||||
content_visibility_state_);
|
||||
@@ -717,6 +718,7 @@ bool NearbyDistanceTool::HandleMouseMove(const WebMouseEvent& event) {
|
||||
|
||||
// Store values for the highlight.
|
||||
hovered_node_ = node;
|
||||
+ overlay_->EnsureAXContext(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -728,7 +730,7 @@ void NearbyDistanceTool::Draw(float scale) {
|
||||
Node* node = hovered_node_.Get();
|
||||
if (!node)
|
||||
return;
|
||||
- overlay_->EnsureAXContext(node);
|
||||
+ DCHECK(overlay_->HasAXContext(node));
|
||||
auto content_visibility_state = DetermineSelfContentVisibilityState(node);
|
||||
InspectorHighlight highlight(
|
||||
node, InspectorHighlight::DefaultConfig(),
|
||||
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
|
||||
index 794baa4ca401656601ab078c73974c1a70f4f8bb..437ed5a4abd24cfe1934f3c56fc8096db0d1b9e8 100644
|
||||
--- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
|
||||
+++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
|
||||
@@ -489,6 +489,10 @@ protocol::Response InspectorOverlayAgent::enable() {
|
||||
return protocol::Response::Success();
|
||||
}
|
||||
|
||||
+bool InspectorOverlayAgent::HasAXContext(Node* node) {
|
||||
+ return document_to_ax_context_.Contains(&node->GetDocument());
|
||||
+}
|
||||
+
|
||||
void InspectorOverlayAgent::EnsureAXContext(Node* node) {
|
||||
EnsureAXContext(node->GetDocument());
|
||||
}
|
||||
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
|
||||
index ccaa46dd8a0067fc2d37677862e6345421d70669..1441ee7809851a4529acdde3db314b0c59264162 100644
|
||||
--- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
|
||||
+++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
|
||||
@@ -267,6 +267,7 @@ class CORE_EXPORT InspectorOverlayAgent final
|
||||
void Dispose() override;
|
||||
|
||||
void Inspect(Node*);
|
||||
+ bool HasAXContext(Node*);
|
||||
void EnsureAXContext(Node*);
|
||||
void EnsureAXContext(Document&);
|
||||
void DispatchBufferedTouchEvents();
|
||||
diff --git a/third_party/blink/web_tests/inspector-protocol/overlay/overlay-in-iframe-expected.txt b/third_party/blink/web_tests/inspector-protocol/overlay/overlay-in-iframe-expected.txt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ad0f146f06757b8b85054a2a343ca2a8aeef7bba
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/inspector-protocol/overlay/overlay-in-iframe-expected.txt
|
||||
@@ -0,0 +1,2 @@
|
||||
+Verifies that overlay of an iframe element doesn't crash.
|
||||
+
|
||||
diff --git a/third_party/blink/web_tests/inspector-protocol/overlay/overlay-in-iframe.js b/third_party/blink/web_tests/inspector-protocol/overlay/overlay-in-iframe.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c2fb6822d0afe6ac8f9c6efdb7c97036f7f49502
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/inspector-protocol/overlay/overlay-in-iframe.js
|
||||
@@ -0,0 +1,36 @@
|
||||
+(async function(testRunner) {
|
||||
+ const {page, session, dp} = await testRunner.startHTML(``,
|
||||
+ "Verifies that overlay of an iframe element doesn't crash.");
|
||||
+
|
||||
+ await session.evaluate(() => {
|
||||
+ var iframe = document.createElement('iframe');
|
||||
+ iframe.style.position = 'absolute';
|
||||
+ iframe.style.top = '200px';
|
||||
+ iframe.style.left = '200px';
|
||||
+ iframe.style.width = '500px';
|
||||
+ iframe.style.height = '500px';
|
||||
+ document.body.appendChild(iframe);
|
||||
+ iframe.contentWindow.document.body.innerHTML = `
|
||||
+ <div style="width:100px;height:100px;background:orange"></div>
|
||||
+ `;
|
||||
+ });
|
||||
+
|
||||
+ await dp.DOM.enable();
|
||||
+ await dp.Emulation.enable();
|
||||
+ await dp.Overlay.enable();
|
||||
+
|
||||
+ const root = (await dp.DOM.getDocument()).result.root;
|
||||
+ const iframeDiv = (await dp.DOM.getNodeForLocation({x: 250, y: 250})).result.nodeId;
|
||||
+
|
||||
+ const result = await dp.Overlay.highlightNode({
|
||||
+ highlightConfig: {contentColor: {r: 0, g: 128, b: 0, a: 0.5}},
|
||||
+ nodeId: iframeDiv,
|
||||
+ });
|
||||
+
|
||||
+ // Wait for overlay rendering to finish by requesting an animation frame.
|
||||
+ await session.evaluate(() => {
|
||||
+ return new Promise(resolve => requestAnimationFrame(resolve));
|
||||
+ });
|
||||
+
|
||||
+ testRunner.completeTest();
|
||||
+});
|
||||
@@ -9,15 +9,22 @@ production use cases. This is unlikely to be upstreamed as the change
|
||||
is entirely in //chrome.
|
||||
|
||||
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
|
||||
index 48b7a20c212578ba9055b781b5c05b312fa7e974..3ae8136e5c938be80df141f7ca582d974fb08eed 100644
|
||||
index 48b7a20c212578ba9055b781b5c05b312fa7e974..d7d92f326ba94be7a3960d527bc2b6d8d15890fa 100644
|
||||
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
|
||||
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
|
||||
@@ -49,6 +49,9 @@ namespace {
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/location.h"
|
||||
+#include "base/no_destructor.h"
|
||||
#include "base/notreached.h"
|
||||
#include "base/observer_list.h"
|
||||
#include "base/path_service.h"
|
||||
@@ -49,6 +50,8 @@ namespace {
|
||||
base::LazyInstance<GURL>::Leaky g_download_url_for_testing =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
+base::LazyInstance<GURL>::Leaky g_base_download_url_override =
|
||||
+ LAZY_INSTANCE_INITIALIZER;
|
||||
+base::NoDestructor<GURL> g_base_download_url_override;
|
||||
+
|
||||
// Close the file.
|
||||
void CloseDictionary(base::File file) {
|
||||
@@ -27,7 +34,7 @@ index 48b7a20c212578ba9055b781b5c05b312fa7e974..3ae8136e5c938be80df141f7ca582d97
|
||||
}
|
||||
|
||||
+void SpellcheckHunspellDictionary::SetBaseDownloadURL(const GURL url) {
|
||||
+ g_base_download_url_override.Get() = url;
|
||||
+ *g_base_download_url_override = url;
|
||||
+}
|
||||
+
|
||||
GURL SpellcheckHunspellDictionary::GetDictionaryURL() {
|
||||
@@ -37,8 +44,8 @@ index 48b7a20c212578ba9055b781b5c05b312fa7e974..3ae8136e5c938be80df141f7ca582d97
|
||||
std::string bdict_file = dictionary_file_.path.BaseName().MaybeAsASCII();
|
||||
DCHECK(!bdict_file.empty());
|
||||
|
||||
+ if (g_base_download_url_override.Get() != GURL())
|
||||
+ return GURL(g_base_download_url_override.Get().spec() + base::ToLowerASCII(bdict_file));
|
||||
+ if (*g_base_download_url_override != GURL())
|
||||
+ return GURL(g_base_download_url_override->spec() + base::ToLowerASCII(bdict_file));
|
||||
+
|
||||
static const char kDownloadServerUrl[] =
|
||||
"https://redirector.gvt1.com/edgedl/chrome/dict/";
|
||||
|
||||
@@ -14,10 +14,10 @@ can potentially be upstreamed but it's likely that the better fix for this
|
||||
is to update our OSR code which is several years outdated.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index e02f82ba9fb3b1359c19bd71c0bd94cd46a5ed5e..a92c42ea05d680d435f6f69d9882e85537c995ec 100644
|
||||
index 3ade9312a09494dece3935cc87c56bf464d28399..e49ccf4ffc115a78abceeddd7f452aeeb5c6a917 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -3996,7 +3996,7 @@ void WebContentsImpl::Restore() {
|
||||
@@ -4001,7 +4001,7 @@ void WebContentsImpl::Restore() {
|
||||
ui::WindowShowState WebContentsImpl::GetWindowShowState() {
|
||||
#if defined(USE_AURA)
|
||||
aura::Window* window = GetTopLevelNativeWindow();
|
||||
|
||||
@@ -3,52 +3,94 @@ From: Kyrylo Hrechykhin <khrechykhin@microsoft.com>
|
||||
Date: Thu, 6 Oct 2022 18:30:53 +0200
|
||||
Subject: fix: on-screen-keyboard hides on input blur in webview
|
||||
|
||||
Changes introduced by this patch fix issue where OSK does not hide on
|
||||
input rendered inside webview is blurred. This patch should be removed
|
||||
when proper fix in chromium repo is available.
|
||||
|
||||
Note: the issue still occurs if input rendered in webview blurred due
|
||||
to touch outside of webview. It is caused by webview implementation
|
||||
details. Specificaly due to webview has its own tree nodes and focused
|
||||
node does not change in this case.
|
||||
Work around OSK not hiding by notifying RenderWidgetHostViewAura of
|
||||
focus node change via TextInputManager.
|
||||
|
||||
chromium-bug: https://crbug.com/1369605
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
|
||||
index f5f30d5696bdd2b8b5948b18b3f7959f9078cc72..660dc5f60bad28ce345827767fc508711ea06d31 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
|
||||
@@ -1046,6 +1046,12 @@ RenderWidgetHostViewChildFrame::DidUpdateVisualProperties(
|
||||
return viz::ScopedSurfaceIdAllocator(std::move(allocation_task));
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
index 9840d0e1308bc6e4589f32f6eac5e27f353895dd..366d285bdf5f51a15fd993efba1763cce4461666 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
@@ -2945,6 +2945,12 @@ void RenderWidgetHostViewAura::OnTextSelectionChanged(
|
||||
}
|
||||
}
|
||||
|
||||
+void RenderWidgetHostViewChildFrame::FocusedNodeChanged(
|
||||
+ bool is_editable_node,
|
||||
+ const gfx::Rect& node_bounds_in_screen) {
|
||||
+ NOTREACHED();
|
||||
+void RenderWidgetHostViewAura::OnFocusedInputElementChanged(
|
||||
+ TextInputManager* text_input_manager,
|
||||
+ RenderWidgetHostViewBase* view) {
|
||||
+ FocusedNodeChanged(false, {});
|
||||
+}
|
||||
+
|
||||
ui::TextInputType RenderWidgetHostViewChildFrame::GetTextInputType() const {
|
||||
if (!text_input_manager_)
|
||||
return ui::TEXT_INPUT_TYPE_NONE;
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.h b/content/browser/renderer_host/render_widget_host_view_child_frame.h
|
||||
index 1dfd9c071a41482e0d35257b28522e5b37702f25..41a09e9470dfa5797c69d02fc9b4f5e608a43d94 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.h
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.h
|
||||
@@ -184,6 +184,8 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
|
||||
void DisableAutoResize(const gfx::Size& new_size) override;
|
||||
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(
|
||||
const cc::RenderFrameMetadata& metadata) override;
|
||||
+ void FocusedNodeChanged(bool is_editable_node,
|
||||
+ const gfx::Rect& node_bounds_in_screen) override;
|
||||
void RenderWidgetHostViewAura::SetPopupChild(
|
||||
RenderWidgetHostViewAura* popup_child_host_view) {
|
||||
popup_child_host_view_ = popup_child_host_view;
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
|
||||
index f8a8894f2daddcc6e3c1df6c48645fe8fadeb4b2..da157784415355a2a9f489be96fbbbd333e6afcf 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
|
||||
@@ -628,6 +628,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
|
||||
RenderWidgetHostViewBase* updated_view) override;
|
||||
void OnTextSelectionChanged(TextInputManager* text_input_mangager,
|
||||
RenderWidgetHostViewBase* updated_view) override;
|
||||
+ void OnFocusedInputElementChanged(TextInputManager* text_input_manager,
|
||||
+ RenderWidgetHostViewBase* view) override;
|
||||
|
||||
// RenderFrameMetadataProvider::Observer implementation.
|
||||
void OnRenderFrameMetadataChangedBeforeActivation(
|
||||
// Detaches |this| from the input method object.
|
||||
// is_removed flag is true if this is called while the window is
|
||||
diff --git a/content/browser/renderer_host/text_input_manager.cc b/content/browser/renderer_host/text_input_manager.cc
|
||||
index 6c4403063fd5a57ea1d8ff3446ba74ea10090e5a..269830964194ca8fae6b3bd11d2955ab3e8ab782 100644
|
||||
--- a/content/browser/renderer_host/text_input_manager.cc
|
||||
+++ b/content/browser/renderer_host/text_input_manager.cc
|
||||
@@ -167,6 +167,7 @@ void TextInputManager::UpdateTextInputState(
|
||||
|
||||
if (text_input_state.type == ui::TEXT_INPUT_TYPE_NONE &&
|
||||
active_view_ != view) {
|
||||
+ NotifyFocusedInputElementChanged(active_view_);
|
||||
// We reached here because an IPC is received to reset the TextInputState
|
||||
// for |view|. But |view| != |active_view_|, which suggests that at least
|
||||
// one other view has become active and we have received the corresponding
|
||||
@@ -453,6 +454,12 @@ void TextInputManager::NotifyObserversAboutInputStateUpdate(
|
||||
observer.OnUpdateTextInputStateCalled(this, updated_view, did_update_state);
|
||||
}
|
||||
|
||||
+void TextInputManager::NotifyFocusedInputElementChanged(
|
||||
+ RenderWidgetHostViewBase* view) {
|
||||
+ for (auto& observer : observer_list_)
|
||||
+ observer.OnFocusedInputElementChanged(this, view);
|
||||
+}
|
||||
+
|
||||
TextInputManager::SelectionRegion::SelectionRegion() = default;
|
||||
|
||||
TextInputManager::SelectionRegion::SelectionRegion(
|
||||
diff --git a/content/browser/renderer_host/text_input_manager.h b/content/browser/renderer_host/text_input_manager.h
|
||||
index 35d0355b0e181ecf38146a70559eb6070e83d6d6..47d37b5f7c9a62e1b7c91de5bd0d0d562795bc89 100644
|
||||
--- a/content/browser/renderer_host/text_input_manager.h
|
||||
+++ b/content/browser/renderer_host/text_input_manager.h
|
||||
@@ -71,6 +71,10 @@ class CONTENT_EXPORT TextInputManager {
|
||||
virtual void OnTextSelectionChanged(
|
||||
TextInputManager* text_input_manager,
|
||||
RenderWidgetHostViewBase* updated_view) {}
|
||||
+ // Called when focused input element has changed
|
||||
+ virtual void OnFocusedInputElementChanged(
|
||||
+ TextInputManager* text_input_manager,
|
||||
+ RenderWidgetHostViewBase* updated_view) {}
|
||||
};
|
||||
|
||||
// Text selection bounds.
|
||||
@@ -278,6 +282,7 @@ class CONTENT_EXPORT TextInputManager {
|
||||
|
||||
void NotifyObserversAboutInputStateUpdate(RenderWidgetHostViewBase* view,
|
||||
bool did_update_state);
|
||||
+ void NotifyFocusedInputElementChanged(RenderWidgetHostViewBase* view);
|
||||
|
||||
// The view with active text input state, i.e., a focused <input> element.
|
||||
// It will be nullptr if no such view exists. Note that the active view
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 9d5e099d981f3cd9dde4a07c071a63e6459bd311..e02f82ba9fb3b1359c19bd71c0bd94cd46a5ed5e 100644
|
||||
index 5f7f36a4b77fda73dc77cde23a8671c89a1f2b78..3ade9312a09494dece3935cc87c56bf464d28399 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -8649,7 +8649,7 @@ void WebContentsImpl::OnFocusedElementChangedInFrame(
|
||||
@@ -8654,7 +8654,7 @@ void WebContentsImpl::OnFocusedElementChangedInFrame(
|
||||
"WebContentsImpl::OnFocusedElementChangedInFrame",
|
||||
"render_frame_host", frame);
|
||||
RenderWidgetHostViewBase* root_view =
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Huang <penghuang@chromium.org>
|
||||
Date: Wed, 20 Mar 2024 16:22:16 +0000
|
||||
Subject: Fix PaintImage deserialization arbitrary-read issue
|
||||
|
||||
(cherry picked from commit 47e8386c97ac7a84a96866fbd35422b99a01de5a)
|
||||
|
||||
Bug: 327183408
|
||||
Change-Id: I09927fbae60b666aaa370e3aba01607cdb977a25
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5370455
|
||||
Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org>
|
||||
Commit-Queue: Peng Huang <penghuang@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1272930}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5382202
|
||||
Auto-Submit: Peng Huang <penghuang@chromium.org>
|
||||
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6261@{#1106}
|
||||
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
|
||||
|
||||
diff --git a/cc/paint/paint_op_reader.cc b/cc/paint/paint_op_reader.cc
|
||||
index 128d4306319d039f0a1dc3ab48793dbdcc641da0..936251f2c45c18464bb557bfc9ac600ba5b9510b 100644
|
||||
--- a/cc/paint/paint_op_reader.cc
|
||||
+++ b/cc/paint/paint_op_reader.cc
|
||||
@@ -1568,9 +1568,10 @@ inline void PaintOpReader::DidRead(size_t bytes_read) {
|
||||
// All data are aligned with PaintOpWriter::kDefaultAlignment at least.
|
||||
size_t aligned_bytes =
|
||||
base::bits::AlignUp(bytes_read, PaintOpWriter::kDefaultAlignment);
|
||||
- memory_ += aligned_bytes;
|
||||
DCHECK_LE(aligned_bytes, remaining_bytes_);
|
||||
- remaining_bytes_ -= aligned_bytes;
|
||||
+ bytes_read = std::min(aligned_bytes, remaining_bytes_);
|
||||
+ memory_ += bytes_read;
|
||||
+ remaining_bytes_ -= bytes_read;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
@@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joey Arhar <jarhar@chromium.org>
|
||||
Date: Wed, 21 Feb 2024 21:06:46 +0000
|
||||
Subject: M122: cherry pick CVE-2024-25062 libxml fix
|
||||
|
||||
This patch cherry picks the CVE-2024-25062 fix from libxml:
|
||||
https://gitlab.gnome.org/GNOME/libxml2/-/commit/1a66b176055d25ee635bf328c7b35b381db0b71d
|
||||
|
||||
Bug: 325094430
|
||||
Change-Id: I526ee718269ed8700b90885630b67f00f2f95089
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5310037
|
||||
Auto-Submit: Joey Arhar <jarhar@chromium.org>
|
||||
Commit-Queue: David Baron <dbaron@chromium.org>
|
||||
Reviewed-by: David Baron <dbaron@chromium.org>
|
||||
Commit-Queue: Joey Arhar <jarhar@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6261@{#913}
|
||||
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
|
||||
|
||||
diff --git a/third_party/libxml/README.chromium b/third_party/libxml/README.chromium
|
||||
index 33cfec99e14c5090f6f9ac504689f2c2b482806c..a9a90fccb30f049e544923b5e4e28c67e63794f5 100644
|
||||
--- a/third_party/libxml/README.chromium
|
||||
+++ b/third_party/libxml/README.chromium
|
||||
@@ -36,5 +36,6 @@ Modifications:
|
||||
- LIBXML_XINCLUDE_ENABLED
|
||||
- LIBXML_XPTR_ENABLED
|
||||
- LIBXML_ZLIB_ENABLED
|
||||
+- Cherry picked fix for CVE-2024-25062
|
||||
|
||||
This import was generated by the chromium/roll.py script.
|
||||
diff --git a/third_party/libxml/src/xmlreader.c b/third_party/libxml/src/xmlreader.c
|
||||
index c04cb11311c2af03608f62b54f8d6ae58a6c1d93..9ce8a148b6806f39e5ce14e114bac1af767f5a50 100644
|
||||
--- a/third_party/libxml/src/xmlreader.c
|
||||
+++ b/third_party/libxml/src/xmlreader.c
|
||||
@@ -1378,6 +1378,7 @@ node_found:
|
||||
* Handle XInclude if asked for
|
||||
*/
|
||||
if ((reader->xinclude) && (reader->in_xinclude == 0) &&
|
||||
+ (reader->state != XML_TEXTREADER_BACKTRACK) &&
|
||||
(reader->node != NULL) &&
|
||||
(reader->node->type == XML_ELEMENT_NODE) &&
|
||||
(reader->node->ns != NULL) &&
|
||||
@@ -0,0 +1,80 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eugene Zemtsov <eugene@chromium.org>
|
||||
Date: Mon, 25 Mar 2024 19:28:44 +0000
|
||||
Subject: webcodecs: Disable async VideoFrame readback to mitigate a race
|
||||
|
||||
(cherry picked from commit fdc363eb7a1c1c194a02a4cb340534b1501b0f95)
|
||||
|
||||
Bug: 330575496
|
||||
Change-Id: I187a113528da9d1c4316186e3dd24f91dbfd818b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5386784
|
||||
Commit-Queue: Eugene Zemtsov <eugene@chromium.org>
|
||||
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1277172}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5391828
|
||||
Reviewed-by: Eugene Zemtsov <eugene@chromium.org>
|
||||
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
|
||||
Reviewed-by: Xiaohan Wang <xhwang@chromium.org>
|
||||
Commit-Queue: Xiaohan Wang <xhwang@chromium.org>
|
||||
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6261@{#1124}
|
||||
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
|
||||
|
||||
diff --git a/content/test/data/gpu/webcodecs/copyTo.html b/content/test/data/gpu/webcodecs/copyTo.html
|
||||
index ec2455c9c18900ad911ce98f326139cbdeabd84f..9453c8d361a572b500e86b1249896bc4114ebe27 100644
|
||||
--- a/content/test/data/gpu/webcodecs/copyTo.html
|
||||
+++ b/content/test/data/gpu/webcodecs/copyTo.html
|
||||
@@ -118,6 +118,16 @@ Take frames coming from various sources and read them using copyTo().
|
||||
let frame = await source.getNextFrame();
|
||||
let size = frame.allocationSize();
|
||||
|
||||
+ // Readback a whole frame to a regular buffer detach it
|
||||
+ {
|
||||
+ let buf = new ArrayBuffer(size);
|
||||
+ TEST.assert(readWholeBuffer(buf) == 0, "Buffer should be zero");
|
||||
+ let copy_promise = frame.copyTo(buf);
|
||||
+ buf.transfer(1);
|
||||
+ let layout = await copy_promise;
|
||||
+ TEST.assert(layout, "layout is empty / ArrayBuffer");
|
||||
+ }
|
||||
+
|
||||
// Readback a whole frame to a regular buffer and send it to a worker
|
||||
{
|
||||
let {worker, worker_promise } = makeWorker();
|
||||
@@ -158,4 +168,5 @@ Take frames coming from various sources and read them using copyTo().
|
||||
TEST.log('Test completed');
|
||||
}
|
||||
addManualTestButton([{'source_type': 'offscreen'}]);
|
||||
+ addManualTestButton([{'source_type': 'arraybuffer'}]);
|
||||
</script>
|
||||
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame.cc b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
|
||||
index e5860706c0d9098980ee1e901f1eac048be1a011..af4b7082bebb96b8e6d766c950cf34d5747d10d3 100644
|
||||
--- a/third_party/blink/renderer/modules/webcodecs/video_frame.cc
|
||||
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
|
||||
@@ -80,6 +80,11 @@ namespace blink {
|
||||
|
||||
namespace {
|
||||
|
||||
+// Controls if VideoFrame.copyTo() reads GPU frames asynchronously
|
||||
+BASE_FEATURE(kVideoFrameAsyncCopyTo,
|
||||
+ "VideoFrameAsyncCopyTo",
|
||||
+ base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
+
|
||||
media::VideoPixelFormat ToMediaPixelFormat(V8VideoPixelFormat::Enum fmt) {
|
||||
switch (fmt) {
|
||||
case V8VideoPixelFormat::Enum::kI420:
|
||||
@@ -1157,9 +1162,11 @@ ScriptPromise VideoFrame::copyTo(ScriptState* script_state,
|
||||
} else {
|
||||
DCHECK(local_frame->HasTextures());
|
||||
|
||||
- if (auto* resolver = CopyToAsync(script_state, local_frame, src_rect,
|
||||
- destination, dest_layout)) {
|
||||
- return resolver->Promise();
|
||||
+ if (base::FeatureList::IsEnabled(kVideoFrameAsyncCopyTo)) {
|
||||
+ if (auto* resolver = CopyToAsync(script_state, local_frame, src_rect,
|
||||
+ destination, dest_layout)) {
|
||||
+ return resolver->Promise();
|
||||
+ }
|
||||
}
|
||||
|
||||
if (!CopyTexturablePlanes(*local_frame, src_rect, dest_layout, buffer)) {
|
||||
156
patches/chromium/prevent_mojotrap_event_re-ordering.patch
Normal file
156
patches/chromium/prevent_mojotrap_event_re-ordering.patch
Normal file
@@ -0,0 +1,156 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Rockot <rockot@google.com>
|
||||
Date: Thu, 15 Feb 2024 20:30:22 +0000
|
||||
Subject: Prevent MojoTrap event re-ordering
|
||||
|
||||
(cherry picked from commit 3557a2fcbdd8167f97ca81171be2e0da9c4f0647)
|
||||
|
||||
Fixed: 1508753
|
||||
Change-Id: I9ec14a12e7d1d147bda63703e1d6619fa30c8a51
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5253039
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Reviewed-by: Robert Sesek <rsesek@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1254840}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5299857
|
||||
Reviewed-by: Oksana Zhuravlova <oksamyt@chromium.org>
|
||||
Commit-Queue: Alex Gough <ajgo@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6261@{#794}
|
||||
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
|
||||
|
||||
diff --git a/mojo/core/ipcz_driver/mojo_trap.cc b/mojo/core/ipcz_driver/mojo_trap.cc
|
||||
index 7a5765a74a7f64e584b0a080e659c88c019adcbb..2c98335dd7846fe44fd048265078dfffcb0b63f6 100644
|
||||
--- a/mojo/core/ipcz_driver/mojo_trap.cc
|
||||
+++ b/mojo/core/ipcz_driver/mojo_trap.cc
|
||||
@@ -544,7 +544,15 @@ void MojoTrap::DispatchOrQueueEvent(Trigger& trigger,
|
||||
}
|
||||
|
||||
dispatching_thread_ = base::PlatformThread::CurrentRef();
|
||||
- DispatchEvent(event);
|
||||
+
|
||||
+ // If `trigger.removed` is true, then either this is the cancellation event
|
||||
+ // for the trigger (in which case it's OK to dispatch), or it was cancelled on
|
||||
+ // some other thread while we were blocked above. In the latter case, this
|
||||
+ // event is no longer valid and cannot be dispatched.
|
||||
+ // See https://crbug.com/1508753.
|
||||
+ if (!trigger.removed || event.result == MOJO_RESULT_CANCELLED) {
|
||||
+ DispatchEvent(event);
|
||||
+ }
|
||||
|
||||
// NOTE: This vector is only shrunk by the clear() below, but it may
|
||||
// accumulate more events during each iteration. Hence we iterate by index.
|
||||
diff --git a/mojo/core/trap_unittest.cc b/mojo/core/trap_unittest.cc
|
||||
index 0fd449d9598810fd34372d69d1d1599a0c88b955..4058da72eef8b5a11432b9a17d6ff3ecfd1306e8 100644
|
||||
--- a/mojo/core/trap_unittest.cc
|
||||
+++ b/mojo/core/trap_unittest.cc
|
||||
@@ -1747,6 +1747,111 @@ TEST_F(TrapTest, TriggerDuringDestruction) {
|
||||
MojoClose(b);
|
||||
}
|
||||
|
||||
+TEST_F(TrapTest, RaceDispatchAndBlockedCancel) {
|
||||
+ // Regression test for https://crbug.com/1508753. This bug was caused by
|
||||
+ // reordering of a MOJO_RESULT_CANCELLED event to before some other event for
|
||||
+ // the same trap context, violating an API constraint that must be upheld for
|
||||
+ // memory safety in application code. The scenario which could elicit the bug
|
||||
+ // was as follows:
|
||||
+ //
|
||||
+ // 1. A single trap is watching two pipes, P and Q.
|
||||
+ // 2. Thread A closes pipe P, triggering a CANCELLED event.
|
||||
+ // 3. Thread A re-arms the trap from within the CANCELLED event handler.
|
||||
+ // 4. Thread B changes Q's state to elicit a event for Q (not CANCELLED).
|
||||
+ // 5. Thread B dispatch is blocked because thread A is still dispatching.
|
||||
+ // 6. Before thread B gets a chance to be scheduled, thread A closes Q.
|
||||
+ // 7. Thread A dispatches a CANCELLED event for Q.
|
||||
+ // 8. Thread B is scheduled and proceeds to dispatch its Q event. [BAD]
|
||||
+
|
||||
+ struct State;
|
||||
+
|
||||
+ struct Pipe {
|
||||
+ explicit Pipe(State* state) : state(state) { CreateMessagePipe(&a, &b); }
|
||||
+
|
||||
+ uintptr_t context() const { return reinterpret_cast<uintptr_t>(this); }
|
||||
+
|
||||
+ MojoHandle a;
|
||||
+ MojoHandle b;
|
||||
+ bool trigger_cancelled = false;
|
||||
+
|
||||
+ // Back-reference to common state so it's reachable from the event handler.
|
||||
+ const raw_ptr<State> state;
|
||||
+ };
|
||||
+
|
||||
+ struct State {
|
||||
+ Pipe pipe0{this};
|
||||
+ Pipe pipe1{this};
|
||||
+ MojoHandle trap;
|
||||
+ base::WaitableEvent event;
|
||||
+ };
|
||||
+ State state;
|
||||
+
|
||||
+ // NOTE: + to turn the lambda into a function pointer.
|
||||
+ const MojoTrapEventHandler event_handler = +[](const MojoTrapEvent* event) {
|
||||
+ auto& pipe = *reinterpret_cast<Pipe*>(event->trigger_context);
|
||||
+ auto& state = *pipe.state;
|
||||
+
|
||||
+ // If the bug is present, this expectation can fail flakily. No event should
|
||||
+ // fire for a pipe after its watch has been cancelled.
|
||||
+ EXPECT_FALSE(pipe.trigger_cancelled);
|
||||
+
|
||||
+ if (event->result == MOJO_RESULT_CANCELLED) {
|
||||
+ pipe.trigger_cancelled = true;
|
||||
+
|
||||
+ if (&pipe == &state.pipe0) {
|
||||
+ // When pipe0's watch is cancelled (on the main thread by closure down
|
||||
+ // below) we re-arm the trap immediately. This must succeed because
|
||||
+ // `pipe1.a` is now the only handle being watched, and it's still in an
|
||||
+ // uninteresting state.
|
||||
+ EXPECT_EQ(MOJO_RESULT_OK,
|
||||
+ MojoArmTrap(state.trap, nullptr, nullptr, nullptr));
|
||||
+
|
||||
+ // Unblock the other thread so it can elicit a trap event on pipe1 now
|
||||
+ // that the trap is re-armed. It will still block just before
|
||||
+ // dispatching as long as we're still in this event handler on the main
|
||||
+ // thread.
|
||||
+ state.event.Signal();
|
||||
+
|
||||
+ // A nice long delay to make it very likely for the waiting
|
||||
+ // ThreadedRunner to progress right up to its event dispatch.
|
||||
+ base::PlatformThread::Sleep(base::Milliseconds(10));
|
||||
+
|
||||
+ // Trigger cancellation for pipe1 by closing its `a`. This will queue a
|
||||
+ // CANCELLED event to fire on the same thread immediately after we
|
||||
+ // return from this handler.
|
||||
+ MojoClose(state.pipe1.a);
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ EXPECT_EQ(MOJO_RESULT_OK,
|
||||
+ MojoCreateTrap(event_handler, nullptr, &state.trap));
|
||||
+ EXPECT_EQ(
|
||||
+ MOJO_RESULT_OK,
|
||||
+ MojoAddTrigger(state.trap, state.pipe0.a, MOJO_HANDLE_SIGNAL_READABLE,
|
||||
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
|
||||
+ state.pipe0.context(), nullptr));
|
||||
+ EXPECT_EQ(
|
||||
+ MOJO_RESULT_OK,
|
||||
+ MojoAddTrigger(state.trap, state.pipe1.a, MOJO_HANDLE_SIGNAL_READABLE,
|
||||
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
|
||||
+ state.pipe1.context(), nullptr));
|
||||
+ EXPECT_EQ(MOJO_RESULT_OK, MojoArmTrap(state.trap, nullptr, nullptr, nullptr));
|
||||
+
|
||||
+ ThreadedRunner close_pipe1_b(base::BindLambdaForTesting([&] {
|
||||
+ state.event.Wait();
|
||||
+ MojoClose(state.pipe1.b);
|
||||
+ }));
|
||||
+ close_pipe1_b.Start();
|
||||
+
|
||||
+ // Trigger cancellation of the watch on `pipe0.a`. See event_handler above.
|
||||
+ MojoClose(state.pipe0.a);
|
||||
+
|
||||
+ close_pipe1_b.Join();
|
||||
+ MojoClose(state.pipe0.b);
|
||||
+ MojoClose(state.trap);
|
||||
+}
|
||||
+
|
||||
base::RepeatingClosure g_do_random_thing_callback;
|
||||
|
||||
void ReadAllMessages(const MojoTrapEvent* event) {
|
||||
@@ -44,10 +44,10 @@ index 895f5126806b557c853f163fe69459ea929f11a4..b4ead2f5f2f813c23cd5eddae3d38052
|
||||
|
||||
void RenderWidgetHostImpl::ShowContextMenuAtPoint(
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index daeece42f6fe4e57ca3f88ff7b5d9d0a1c142b9f..744f3757ab2e7bcf517ddae6f5023ac52822a06a 100644
|
||||
index 910ea0d1e11e1dc3deb660b322b67bf223735822..dc413782fc0e7f33011e80a2357d6eba75a6903a 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -5110,6 +5110,11 @@ TextInputManager* WebContentsImpl::GetTextInputManager() {
|
||||
@@ -5115,6 +5115,11 @@ TextInputManager* WebContentsImpl::GetTextInputManager() {
|
||||
return text_input_manager_.get();
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
55
patches/chromium/safely_crash_on_dangling_profile.patch
Normal file
55
patches/chromium/safely_crash_on_dangling_profile.patch
Normal file
@@ -0,0 +1,55 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bo Liu <boliu@chromium.org>
|
||||
Date: Mon, 4 Dec 2023 15:01:22 +0000
|
||||
Subject: Safely crash on dangling profile
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Bug: 1407197
|
||||
Change-Id: Idcafd8f0ba2f980d06338e573489a3456e3823c1
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5080603
|
||||
Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org>
|
||||
Commit-Queue: Bo Liu <boliu@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1232704}
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index e49ccf4ffc115a78abceeddd7f452aeeb5c6a917..09a30d7329b3da7e1f7aa1ea13f4bef876555319 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -256,6 +256,11 @@ BASE_FEATURE(kBackNavigationPredictionMetrics,
|
||||
"BackNavigationPredictionMetrics",
|
||||
base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
|
||||
+// Kill switch for crash immediately on dangling BrowserContext.
|
||||
+BASE_FEATURE(kCrashOnDanglingBrowserContext,
|
||||
+ "CrashOnDanglingBrowserContext",
|
||||
+ base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
+
|
||||
using LifecycleState = RenderFrameHost::LifecycleState;
|
||||
using LifecycleStateImpl = RenderFrameHostImpl::LifecycleStateImpl;
|
||||
|
||||
@@ -1017,11 +1022,18 @@ class WebContentsOfBrowserContext : public base::SupportsUserData::Data {
|
||||
env, web_contents_with_dangling_ptr_to_browser_context);
|
||||
#endif // BUILDFLAG(IS_ANDROID)
|
||||
|
||||
- NOTREACHED()
|
||||
- << "BrowserContext is getting destroyed without first closing all "
|
||||
- << "WebContents (for more info see https://crbug.com/1376879#c44); "
|
||||
- << "creator = " << creator;
|
||||
- base::debug::DumpWithoutCrashing();
|
||||
+ if (base::FeatureList::IsEnabled(kCrashOnDanglingBrowserContext)) {
|
||||
+ LOG(FATAL)
|
||||
+ << "BrowserContext is getting destroyed without first closing all "
|
||||
+ << "WebContents (for more info see https://crbug.com/1376879#c44); "
|
||||
+ << "creator = " << creator;
|
||||
+ } else {
|
||||
+ NOTREACHED()
|
||||
+ << "BrowserContext is getting destroyed without first closing all "
|
||||
+ << "WebContents (for more info see https://crbug.com/1376879#c44); "
|
||||
+ << "creator = " << creator;
|
||||
+ base::debug::DumpWithoutCrashing();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joshua Peraza <jperaza@chromium.org>
|
||||
Date: Tue, 5 Mar 2024 18:09:48 +0000
|
||||
Subject: Update Crashpad to 37afd37401253ebcebcf6e07ce15c8cfecb1a1cc
|
||||
|
||||
29ac83caeb94 [Fuchsia] remove use of fuchsia mac sdk
|
||||
37afd3740125 Properly update iterator
|
||||
|
||||
(cherry picked from commit 80b0e498bec1722e8cc310fe52698e7b690956f2)
|
||||
|
||||
Bug: 325296797
|
||||
Change-Id: I7eb39d1bccec802f1b043eebd20ec0e658fe0e04
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5311633
|
||||
Reviewed-by: Nico Weber <thakis@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1264232}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5335538
|
||||
Reviewed-by: Mark Mentovai <mark@chromium.org>
|
||||
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6261@{#1024}
|
||||
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
|
||||
|
||||
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
|
||||
index e6eb8320371f0f367c131d1712cc0f4d1f410b77..3c3c141e10522d782cd13b5aaa32a640897323e7 100644
|
||||
--- a/third_party/crashpad/README.chromium
|
||||
+++ b/third_party/crashpad/README.chromium
|
||||
@@ -2,7 +2,7 @@ Name: Crashpad
|
||||
Short Name: crashpad
|
||||
URL: https://crashpad.chromium.org/
|
||||
Version: N/A
|
||||
-Revision: 4a93d7f4c407fee2168ea23195d0e30fbfc1f90c
|
||||
+Revision: 37afd37401253ebcebcf6e07ce15c8cfecb1a1cc
|
||||
License: Apache 2.0
|
||||
License File: crashpad/LICENSE
|
||||
Security Critical: yes
|
||||
diff --git a/third_party/crashpad/crashpad/DEPS b/third_party/crashpad/crashpad/DEPS
|
||||
index 909ef7dce53d53486a21cd87e00dc63d3eb79b43..cea46fda079b0bd2aca4bfaeb53158d672cb2b31 100644
|
||||
--- a/third_party/crashpad/crashpad/DEPS
|
||||
+++ b/third_party/crashpad/crashpad/DEPS
|
||||
@@ -121,16 +121,6 @@ deps = {
|
||||
'0d6902558d92fe3d49ba9a8f638ddea829be595b',
|
||||
'condition': 'checkout_fuchsia',
|
||||
},
|
||||
- 'crashpad/third_party/fuchsia/sdk/mac-amd64': {
|
||||
- 'packages': [
|
||||
- {
|
||||
- 'package': 'fuchsia/sdk/core/mac-amd64',
|
||||
- 'version': 'latest'
|
||||
- },
|
||||
- ],
|
||||
- 'condition': 'checkout_fuchsia and host_os == "mac"',
|
||||
- 'dep_type': 'cipd'
|
||||
- },
|
||||
'crashpad/third_party/fuchsia/sdk/linux-amd64': {
|
||||
'packages': [
|
||||
{
|
||||
diff --git a/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc b/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc
|
||||
index 0ad2ee97540174be07110f08e519b530aae045f5..c76722683ddf1ae1a562b3705d909a337a23621b 100644
|
||||
--- a/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc
|
||||
+++ b/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc
|
||||
@@ -99,9 +99,11 @@ ModuleSnapshotSanitized::AnnotationsSimpleMap() const {
|
||||
std::map<std::string, std::string> annotations =
|
||||
snapshot_->AnnotationsSimpleMap();
|
||||
if (allowed_annotations_) {
|
||||
- for (auto kv = annotations.begin(); kv != annotations.end(); ++kv) {
|
||||
- if (!KeyIsAllowed(kv->first, *allowed_annotations_)) {
|
||||
- annotations.erase(kv);
|
||||
+ for (auto kv = annotations.begin(); kv != annotations.end();) {
|
||||
+ if (KeyIsAllowed(kv->first, *allowed_annotations_)) {
|
||||
+ ++kv;
|
||||
+ } else {
|
||||
+ kv = annotations.erase(kv);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ is needed for OSR.
|
||||
Originally landed in https://github.com/electron/libchromiumcontent/pull/226.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index d36306fc177824701ddde81dbd399e77230b1c48..75f4e92f5cf99e044c4584d5dad7251fe3e9a547 100644
|
||||
index 702fa31c9e95d83cbd856f6592050835cd27ccd2..e77956577ca4749e96bfc0908d3094bb21094631 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -3448,6 +3448,13 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
|
||||
|
||||
@@ -37,7 +37,7 @@ index 390866ca02889c9c7dc58561f32d2e195fc700a8..f1510ce378fe9aef9d58a943c0ab3173
|
||||
if (had_fullscreen_token && !GetView()->HasFocus())
|
||||
GetView()->Focus();
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 75f4e92f5cf99e044c4584d5dad7251fe3e9a547..9d5e099d981f3cd9dde4a07c071a63e6459bd311 100644
|
||||
index e77956577ca4749e96bfc0908d3094bb21094631..5f7f36a4b77fda73dc77cde23a8671c89a1f2b78 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -3702,21 +3702,25 @@ KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent(
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
{
|
||||
"src/electron/patches/chromium": "src",
|
||||
|
||||
"src/electron/patches/boringssl": "src/third_party/boringssl/src",
|
||||
|
||||
"src/electron/patches/devtools_frontend": "src/third_party/devtools-frontend/src",
|
||||
|
||||
"src/electron/patches/ffmpeg": "src/third_party/ffmpeg",
|
||||
|
||||
"src/electron/patches/v8": "src/v8",
|
||||
|
||||
"src/electron/patches/node": "src/third_party/electron_node",
|
||||
|
||||
"src/electron/patches/nan": "src/third_party/nan",
|
||||
|
||||
"src/electron/patches/perfetto": "src/third_party/perfetto",
|
||||
|
||||
"src/electron/patches/squirrel.mac": "src/third_party/squirrel.mac",
|
||||
|
||||
"src/electron/patches/Mantle": "src/third_party/squirrel.mac/vendor/Mantle",
|
||||
|
||||
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
|
||||
|
||||
"src/electron/patches/webrtc": "src/third_party/webrtc"
|
||||
}
|
||||
[
|
||||
{ "patch_dir": "src/electron/patches/chromium", "repo": "src" },
|
||||
{ "patch_dir": "src/electron/patches/boringssl", "repo": "src/third_party/boringssl/src" },
|
||||
{ "patch_dir": "src/electron/patches/devtools_frontend", "repo": "src/third_party/devtools-frontend/src" },
|
||||
{ "patch_dir": "src/electron/patches/ffmpeg", "repo": "src/third_party/ffmpeg" },
|
||||
{ "patch_dir": "src/electron/patches/v8", "repo": "src/v8" },
|
||||
{ "patch_dir": "src/electron/patches/node", "repo": "src/third_party/electron_node" },
|
||||
{ "patch_dir": "src/electron/patches/nan", "repo": "src/third_party/nan" },
|
||||
{ "patch_dir": "src/electron/patches/perfetto", "repo": "src/third_party/perfetto" },
|
||||
{ "patch_dir": "src/electron/patches/squirrel.mac", "repo": "src/third_party/squirrel.mac" },
|
||||
{ "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/angle", "repo": "src/third_party/angle" },
|
||||
{ "patch_dir": "src/electron/patches/libvpx", "repo": "src/third_party/libvpx/source/libvpx" },
|
||||
{ "patch_dir": "src/electron/patches/dxc", "repo": "src/third_party/dawn/third_party/dxc" }
|
||||
]
|
||||
|
||||
1
patches/dxc/.patches
Normal file
1
patches/dxc/.patches
Normal file
@@ -0,0 +1 @@
|
||||
fix_hlmatrixlowerpass_leaving_call_to_dangling_functionval.patch
|
||||
@@ -0,0 +1,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Antonio Maiorano <amaiorano@google.com>
|
||||
Date: Wed, 20 Mar 2024 17:15:40 -0400
|
||||
Subject: Fix HLMatrixLowerPass leaving call to dangling FunctionVal
|
||||
|
||||
When lowering an hl.cast, when the operand was an undef matrix, the pass would insert a call to a mat2vec stub, but since the undef value is not
|
||||
an alloca, it never gets handled, and the call to the temporary stub
|
||||
remains. Since the stub FunctionVal gets deleted, when the instruction
|
||||
is accessed in a future pass, it reads a dangling pointer.
|
||||
|
||||
The fix is to handle undef similarly to how constant 0 is handled, and
|
||||
to return an undef vector from lowerHLCast.
|
||||
|
||||
Bug: chromium:328958020
|
||||
Change-Id: Id31e3aa326d9cb9f03ea97139f14dc5292cd6f7b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5383595
|
||||
Reviewed-by: Ben Clayton <bclayton@chromium.org>
|
||||
Reviewed-by: David Neto <dneto@google.com>
|
||||
Reviewed-by: Kenneth Russell <kbr@chromium.org>
|
||||
|
||||
diff --git a/lib/HLSL/HLMatrixLowerPass.cpp b/lib/HLSL/HLMatrixLowerPass.cpp
|
||||
index ca8a8a33fdb475542b3705f3f7a8b8af2554a21f..d5959eb9335465f67d8e7ef7d7ab4eb720274226 100644
|
||||
--- a/lib/HLSL/HLMatrixLowerPass.cpp
|
||||
+++ b/lib/HLSL/HLMatrixLowerPass.cpp
|
||||
@@ -421,6 +421,11 @@ Value *HLMatrixLowerPass::getLoweredByValOperand(Value *Val,
|
||||
if (isa<ConstantAggregateZero>(Val))
|
||||
return ConstantAggregateZero::get(LoweredTy);
|
||||
|
||||
+ // Lower undef mat as undef vec
|
||||
+ if (isa<UndefValue>(Val)) {
|
||||
+ return UndefValue::get(LoweredTy);
|
||||
+ }
|
||||
+
|
||||
// Return a mat-to-vec translation stub
|
||||
FunctionType *TranslationStubTy =
|
||||
FunctionType::get(LoweredTy, {Ty}, /* isVarArg */ false);
|
||||
2
patches/libvpx/.patches
Normal file
2
patches/libvpx/.patches
Normal file
@@ -0,0 +1,2 @@
|
||||
fix_to_buffer_alloc_for_vp9_bitstream_worker_data.patch
|
||||
vp9_fix_to_integer_overflow_test.patch
|
||||
@@ -0,0 +1,68 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Marco Paniconi <marpan@google.com>
|
||||
Date: Wed, 13 Mar 2024 10:58:17 -0700
|
||||
Subject: Fix to buffer alloc for vp9_bitstream_worker_data
|
||||
|
||||
The code was using the bitstream_worker_data when it
|
||||
wasn't allocated for big enough size. This is because
|
||||
the existing condition was to only re-alloc the
|
||||
bitstream_worker_data when current dest_size was larger
|
||||
than the current frame_size. But under resolution change
|
||||
where frame_size is increased, beyond the current dest_size,
|
||||
we need to allow re-alloc to the new size.
|
||||
|
||||
The existing condition to re-alloc when dest_size is
|
||||
larger than frame_size (which is not required) is kept
|
||||
for now.
|
||||
|
||||
Also increase the dest_size to account for image format.
|
||||
|
||||
Added tests, for both ROW_MT=0 and 1, that reproduce
|
||||
the failures in the bugs below.
|
||||
|
||||
Note: this issue only affects the REALTIME encoding path.
|
||||
|
||||
Bug: b/329088759, b/329674887, b/329179808
|
||||
|
||||
Change-Id: Icd65dbc5317120304d803f648d4bd9405710db6f
|
||||
(cherry picked from commit c29e63728316486082dd6083c2062434b441b77d)
|
||||
|
||||
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
|
||||
index ca56d14aa1e31e4791f8772316e449b771aae4fc..88a031e5fc1cf7b6cf0a441664dbbc62006c1790 100644
|
||||
--- a/vp9/encoder/vp9_bitstream.c
|
||||
+++ b/vp9/encoder/vp9_bitstream.c
|
||||
@@ -962,6 +962,14 @@ void vp9_bitstream_encode_tiles_buffer_dealloc(VP9_COMP *const cpi) {
|
||||
}
|
||||
}
|
||||
|
||||
+static int encode_tiles_buffer_alloc_size(VP9_COMP *const cpi) {
|
||||
+ VP9_COMMON *const cm = &cpi->common;
|
||||
+ const int image_bps =
|
||||
+ (8 + 2 * (8 >> (cm->subsampling_x + cm->subsampling_y))) *
|
||||
+ (1 + (cm->bit_depth > 8));
|
||||
+ return cpi->oxcf.width * cpi->oxcf.height * image_bps / 8;
|
||||
+}
|
||||
+
|
||||
static void encode_tiles_buffer_alloc(VP9_COMP *const cpi) {
|
||||
VP9_COMMON *const cm = &cpi->common;
|
||||
int i;
|
||||
@@ -972,7 +980,7 @@ static void encode_tiles_buffer_alloc(VP9_COMP *const cpi) {
|
||||
memset(cpi->vp9_bitstream_worker_data, 0, worker_data_size);
|
||||
for (i = 1; i < cpi->num_workers; ++i) {
|
||||
cpi->vp9_bitstream_worker_data[i].dest_size =
|
||||
- cpi->oxcf.width * cpi->oxcf.height;
|
||||
+ encode_tiles_buffer_alloc_size(cpi);
|
||||
CHECK_MEM_ERROR(&cm->error, cpi->vp9_bitstream_worker_data[i].dest,
|
||||
vpx_malloc(cpi->vp9_bitstream_worker_data[i].dest_size));
|
||||
}
|
||||
@@ -987,8 +995,8 @@ static size_t encode_tiles_mt(VP9_COMP *cpi, uint8_t *data_ptr) {
|
||||
int tile_col = 0;
|
||||
|
||||
if (!cpi->vp9_bitstream_worker_data ||
|
||||
- cpi->vp9_bitstream_worker_data[1].dest_size >
|
||||
- (cpi->oxcf.width * cpi->oxcf.height)) {
|
||||
+ cpi->vp9_bitstream_worker_data[1].dest_size !=
|
||||
+ encode_tiles_buffer_alloc_size(cpi)) {
|
||||
vp9_bitstream_encode_tiles_buffer_dealloc(cpi);
|
||||
encode_tiles_buffer_alloc(cpi);
|
||||
}
|
||||
28
patches/libvpx/vp9_fix_to_integer_overflow_test.patch
Normal file
28
patches/libvpx/vp9_fix_to_integer_overflow_test.patch
Normal file
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Marco Paniconi <marpan@google.com>
|
||||
Date: Sat, 16 Mar 2024 10:39:28 -0700
|
||||
Subject: vp9: fix to integer overflow test
|
||||
|
||||
failure for the 16k test: issue introduced
|
||||
in: c29e637283
|
||||
|
||||
Bug: b/329088759, b/329674887, b/329179808
|
||||
|
||||
Change-Id: I88e8a36b7f13223997c3006c84aec9cfa48c0bcf
|
||||
(cherry picked from commit 19832b1702d5b0adf616a0e080abd5207c8445b5)
|
||||
|
||||
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
|
||||
index 88a031e5fc1cf7b6cf0a441664dbbc62006c1790..d3c029da4bacafdb19aa6bfb9865ccbf2db33393 100644
|
||||
--- a/vp9/encoder/vp9_bitstream.c
|
||||
+++ b/vp9/encoder/vp9_bitstream.c
|
||||
@@ -967,7 +967,9 @@ static int encode_tiles_buffer_alloc_size(VP9_COMP *const cpi) {
|
||||
const int image_bps =
|
||||
(8 + 2 * (8 >> (cm->subsampling_x + cm->subsampling_y))) *
|
||||
(1 + (cm->bit_depth > 8));
|
||||
- return cpi->oxcf.width * cpi->oxcf.height * image_bps / 8;
|
||||
+ const int64_t size =
|
||||
+ (int64_t)cpi->oxcf.width * cpi->oxcf.height * image_bps / 8;
|
||||
+ return (int)size;
|
||||
}
|
||||
|
||||
static void encode_tiles_buffer_alloc(VP9_COMP *const cpi) {
|
||||
@@ -1,5 +1,3 @@
|
||||
refactor_alter_child_process_fork_to_use_execute_script_with.patch
|
||||
feat_initialize_asar_support.patch
|
||||
expose_get_builtin_module_function.patch
|
||||
build_add_gn_build_files.patch
|
||||
fix_add_default_values_for_variables_in_common_gypi.patch
|
||||
@@ -55,3 +53,6 @@ win_process_avoid_assert_after_spawning_store_app_4152.patch
|
||||
test_fix_edge_snapshot_stack_traces.patch
|
||||
chore_remove_use_of_deprecated_kmaxlength.patch
|
||||
fix_avx_detection.patch
|
||||
fix_undici_incorrectly_copies_headers_onto_fetches.patch
|
||||
module_rework_of_memory_management_in_vm_apis_with_the.patch
|
||||
src_preload_function_for_environment.patch
|
||||
|
||||
@@ -26,10 +26,10 @@ index 001343b74ce236f89dca030c0fc9dd0299df0b39..6f277daf4ce846f093f634c473daec07
|
||||
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 fcbd9ee1af002bc176937e6bb5af55791b2f64b2..cbfb6e3620a7e77658c86a4730c50661b8a937f7 100644
|
||||
index b4a24bbffb6c43638d13063e85b6cfba5c0cc9c7..21dbf3d87c813b057602637a27ed226bb91698a5 100644
|
||||
--- a/lib/internal/process/pre_execution.js
|
||||
+++ b/lib/internal/process/pre_execution.js
|
||||
@@ -164,11 +164,13 @@ function patchProcessObject(expandArgv1) {
|
||||
@@ -157,11 +157,13 @@ function patchProcessObject(expandArgv1) {
|
||||
if (expandArgv1 && process.argv[1] &&
|
||||
!StringPrototypeStartsWith(process.argv[1], '-')) {
|
||||
// Expand process.argv[1] into a full path.
|
||||
|
||||
@@ -11,10 +11,10 @@ its own blended handler between Node and Blink.
|
||||
Not upstreamable.
|
||||
|
||||
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
|
||||
index cbfb6e3620a7e77658c86a4730c50661b8a937f7..ccd48027e3dfebd563fcbe83239174c79c693dd7 100644
|
||||
index 21dbf3d87c813b057602637a27ed226bb91698a5..fd5357997a4e05567146dc997e47af408e1fc8f4 100644
|
||||
--- a/lib/internal/process/pre_execution.js
|
||||
+++ b/lib/internal/process/pre_execution.js
|
||||
@@ -567,7 +567,7 @@ function initializeESMLoader() {
|
||||
@@ -560,7 +560,7 @@ function initializeESMLoader() {
|
||||
// Create this WeakMap in js-land because V8 has no C++ API for WeakMap.
|
||||
internalBinding('module_wrap').callbackMap = new SafeWeakMap();
|
||||
|
||||
@@ -23,7 +23,7 @@ index cbfb6e3620a7e77658c86a4730c50661b8a937f7..ccd48027e3dfebd563fcbe83239174c7
|
||||
|
||||
const {
|
||||
setImportModuleDynamicallyCallback,
|
||||
@@ -576,8 +576,8 @@ function initializeESMLoader() {
|
||||
@@ -569,8 +569,8 @@ function initializeESMLoader() {
|
||||
const esm = require('internal/process/esm_loader');
|
||||
// Setup per-isolate callbacks that locate data or callbacks that we keep
|
||||
// track of for different ESM modules.
|
||||
|
||||
@@ -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 ec39a00ddb791e6e1ebe31aa45d290e7dcc4ebfc..1cd5d8969471b276211c45a9d8d76e9b10b1bb66 100644
|
||||
index 5bdc474c80169cb0ceeb082e6afcf9e8fa322ab3..f9234f2ac875cb6cb0c8de2894b8a1d4d8db0c46 100644
|
||||
--- a/lib/child_process.js
|
||||
+++ b/lib/child_process.js
|
||||
@@ -61,6 +61,7 @@ let debug = require('internal/util/debuglog').debuglog(
|
||||
@@ -19,7 +19,7 @@ index ec39a00ddb791e6e1ebe31aa45d290e7dcc4ebfc..1cd5d8969471b276211c45a9d8d76e9b
|
||||
|
||||
const {
|
||||
AbortError,
|
||||
@@ -162,7 +163,6 @@ function fork(modulePath, args = [], options) {
|
||||
@@ -154,7 +155,6 @@ function fork(modulePath, args = [], options) {
|
||||
ArrayPrototypeSplice(execArgv, index - 1, 2);
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ index ec39a00ddb791e6e1ebe31aa45d290e7dcc4ebfc..1cd5d8969471b276211c45a9d8d76e9b
|
||||
args = [...execArgv, modulePath, ...args];
|
||||
|
||||
if (typeof options.stdio === 'string') {
|
||||
@@ -625,6 +625,21 @@ function normalizeSpawnArguments(file, args, options) {
|
||||
@@ -617,6 +617,21 @@ function normalizeSpawnArguments(file, args, options) {
|
||||
'options.windowsVerbatimArguments');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Thu, 13 Sep 2018 08:56:07 -0700
|
||||
Subject: feat: initialize asar support
|
||||
|
||||
This patch initializes asar support in Node.js.
|
||||
|
||||
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
|
||||
index b4a24bbffb6c43638d13063e85b6cfba5c0cc9c7..fcbd9ee1af002bc176937e6bb5af55791b2f64b2 100644
|
||||
--- a/lib/internal/process/pre_execution.js
|
||||
+++ b/lib/internal/process/pre_execution.js
|
||||
@@ -52,6 +52,8 @@ function prepareWorkerThreadExecution() {
|
||||
});
|
||||
}
|
||||
|
||||
+
|
||||
+let processLinkedBinding = process._linkedBinding;
|
||||
function prepareExecution(options) {
|
||||
const { expandArgv1, initializeModules, isMainThread } = options;
|
||||
|
||||
@@ -130,12 +132,17 @@ function setupUserModules() {
|
||||
loadPreloadModules();
|
||||
// Need to be done after --require setup.
|
||||
initializeFrozenIntrinsics();
|
||||
+ setupAsarSupport();
|
||||
}
|
||||
|
||||
function refreshRuntimeOptions() {
|
||||
refreshOptions();
|
||||
}
|
||||
|
||||
+function setupAsarSupport() {
|
||||
+ processLinkedBinding('electron_common_asar').initAsarSupport(require);
|
||||
+}
|
||||
+
|
||||
function patchProcessObject(expandArgv1) {
|
||||
const binding = internalBinding('process_methods');
|
||||
binding.patchProcessObject(process);
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Mon, 30 Jul 2018 10:30:35 -0700
|
||||
Subject: refactor: alter child_process.fork to use execute script with
|
||||
Electron
|
||||
|
||||
When forking a child script, we setup a special environment to make the Electron binary run like the upstream node. On Mac, we use the helper app as node binary.
|
||||
|
||||
diff --git a/lib/child_process.js b/lib/child_process.js
|
||||
index 5bdc474c80169cb0ceeb082e6afcf9e8fa322ab3..ec39a00ddb791e6e1ebe31aa45d290e7dcc4ebfc 100644
|
||||
--- a/lib/child_process.js
|
||||
+++ b/lib/child_process.js
|
||||
@@ -139,6 +139,14 @@ function fork(modulePath, args = [], options) {
|
||||
validateObject(options, 'options');
|
||||
}
|
||||
options = { __proto__: null, ...options, shell: false };
|
||||
+ // When forking a child script, we setup a special environment to make
|
||||
+ // the electron binary run like upstream Node.js
|
||||
+ options.env = Object.create(options.env || process.env)
|
||||
+ options.env.ELECTRON_RUN_AS_NODE = 1;
|
||||
+
|
||||
+ if (!options.execPath && process.type && process.platform == 'darwin') {
|
||||
+ options.execPath = process.helperExecPath;
|
||||
+ }
|
||||
options.execPath = options.execPath || process.execPath;
|
||||
validateArgumentNullCheck(options.execPath, 'options.execPath');
|
||||
|
||||
283
patches/node/src_preload_function_for_environment.patch
Normal file
283
patches/node/src_preload_function_for_environment.patch
Normal file
@@ -0,0 +1,283 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Mon, 4 Mar 2024 11:41:18 +0900
|
||||
Subject: src: preload function for Environment
|
||||
|
||||
Backport https://github.com/nodejs/node/pull/51539
|
||||
|
||||
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
|
||||
index 2d892267a08772f4c37ee381c55f46b3a99f2232..e3daca3ba8cddac8db5fc73d78d869fedb4204af 100644
|
||||
--- a/lib/internal/process/pre_execution.js
|
||||
+++ b/lib/internal/process/pre_execution.js
|
||||
@@ -126,6 +126,9 @@ function setupUserModules() {
|
||||
initializeESMLoader();
|
||||
const CJSLoader = require('internal/modules/cjs/loader');
|
||||
assert(!CJSLoader.hasLoadedAnyUserCJSModule);
|
||||
+ if (getEmbedderOptions().hasEmbedderPreload) {
|
||||
+ runEmbedderPreload();
|
||||
+ }
|
||||
loadPreloadModules();
|
||||
// Need to be done after --require setup.
|
||||
initializeFrozenIntrinsics();
|
||||
@@ -588,6 +591,10 @@ function initializeFrozenIntrinsics() {
|
||||
}
|
||||
}
|
||||
|
||||
+function runEmbedderPreload() {
|
||||
+ internalBinding('mksnapshot').runEmbedderPreload(process, require);
|
||||
+}
|
||||
+
|
||||
function loadPreloadModules() {
|
||||
// For user code, we preload modules if `-r` is passed
|
||||
const preloadModules = getOptionValue('--require');
|
||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||
index c4caef25af670658965fc740ce03c2d2c4ed3e66..465ff36b79c36d29777c7b1abe3a35d3be5de93e 100644
|
||||
--- a/src/api/environment.cc
|
||||
+++ b/src/api/environment.cc
|
||||
@@ -484,18 +484,22 @@ NODE_EXTERN std::unique_ptr<InspectorParentHandle> GetInspectorParentHandle(
|
||||
#endif
|
||||
}
|
||||
|
||||
-MaybeLocal<Value> LoadEnvironment(
|
||||
- Environment* env,
|
||||
- StartExecutionCallback cb) {
|
||||
+MaybeLocal<Value> LoadEnvironment(Environment* env,
|
||||
+ StartExecutionCallback cb,
|
||||
+ EmbedderPreloadCallback preload) {
|
||||
env->InitializeLibuv();
|
||||
env->InitializeDiagnostics();
|
||||
+ if (preload) {
|
||||
+ env->set_embedder_preload(std::move(preload));
|
||||
+ }
|
||||
|
||||
return StartExecution(env, cb);
|
||||
}
|
||||
|
||||
MaybeLocal<Value> LoadEnvironment(
|
||||
Environment* env,
|
||||
- const char* main_script_source_utf8) {
|
||||
+ const char* main_script_source_utf8,
|
||||
+ EmbedderPreloadCallback preload) {
|
||||
CHECK_NOT_NULL(main_script_source_utf8);
|
||||
return LoadEnvironment(
|
||||
env, [&](const StartExecutionCallbackInfo& info) -> MaybeLocal<Value> {
|
||||
@@ -508,7 +512,8 @@ MaybeLocal<Value> LoadEnvironment(
|
||||
std::vector<Local<Value>> args = {realm->process_object(),
|
||||
realm->builtin_module_require()};
|
||||
return realm->ExecuteBootstrapper(name.c_str(), &args);
|
||||
- });
|
||||
+ },
|
||||
+ std::move(preload));
|
||||
}
|
||||
|
||||
Environment* GetCurrentEnvironment(Local<Context> context) {
|
||||
diff --git a/src/env-inl.h b/src/env-inl.h
|
||||
index c68ea0fb1d45fadfa64f092a96ee04ecd9fe4c2d..2db4d431b3ce573e77e282b74c06a57a38d09417 100644
|
||||
--- a/src/env-inl.h
|
||||
+++ b/src/env-inl.h
|
||||
@@ -378,6 +378,14 @@ inline std::vector<double>* Environment::destroy_async_id_list() {
|
||||
return &destroy_async_id_list_;
|
||||
}
|
||||
|
||||
+inline const EmbedderPreloadCallback& Environment::embedder_preload() const {
|
||||
+ return embedder_preload_;
|
||||
+}
|
||||
+
|
||||
+inline void Environment::set_embedder_preload(EmbedderPreloadCallback fn) {
|
||||
+ embedder_preload_ = std::move(fn);
|
||||
+}
|
||||
+
|
||||
inline double Environment::new_async_id() {
|
||||
async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
|
||||
return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
|
||||
diff --git a/src/env.h b/src/env.h
|
||||
index 9b5fcdaed5fdda44cd8103a0821a7b5358523f4e..6a5a7eeec866f6e501feeb03fe7da5ada011afa0 100644
|
||||
--- a/src/env.h
|
||||
+++ b/src/env.h
|
||||
@@ -925,6 +925,9 @@ class Environment : public MemoryRetainer {
|
||||
|
||||
#endif // HAVE_INSPECTOR
|
||||
|
||||
+ inline const EmbedderPreloadCallback& embedder_preload() const;
|
||||
+ inline void set_embedder_preload(EmbedderPreloadCallback fn);
|
||||
+
|
||||
inline void set_process_exit_handler(
|
||||
std::function<void(Environment*, int)>&& handler);
|
||||
|
||||
@@ -1094,6 +1097,7 @@ class Environment : public MemoryRetainer {
|
||||
DefaultProcessExitHandler };
|
||||
|
||||
std::unique_ptr<Realm> principal_realm_ = nullptr;
|
||||
+ EmbedderPreloadCallback embedder_preload_;
|
||||
|
||||
// Used by allocate_managed_buffer() and release_managed_buffer() to keep
|
||||
// track of the BackingStore for a given pointer.
|
||||
diff --git a/src/node.h b/src/node.h
|
||||
index 26368061a909e6abc62a4cf261a5dbbd79404f1a..0dec1e311d7c00c2b830a0b2a6bde4336aebe68b 100644
|
||||
--- a/src/node.h
|
||||
+++ b/src/node.h
|
||||
@@ -630,13 +630,33 @@ struct StartExecutionCallbackInfo {
|
||||
|
||||
using StartExecutionCallback =
|
||||
std::function<v8::MaybeLocal<v8::Value>(const StartExecutionCallbackInfo&)>;
|
||||
+using EmbedderPreloadCallback =
|
||||
+ std::function<void(Environment* env,
|
||||
+ v8::Local<v8::Value> process,
|
||||
+ v8::Local<v8::Value> require)>;
|
||||
|
||||
+// Run initialization for the environment.
|
||||
+//
|
||||
+// The |preload| function, usually used by embedders to inject scripts,
|
||||
+// will be run by Node.js before Node.js executes the entry point.
|
||||
+// The function is guaranteed to run before the user land module loader running
|
||||
+// any user code, so it is safe to assume that at this point, no user code has
|
||||
+// been run yet.
|
||||
+// The function will be executed with preload(process, require), and the passed
|
||||
+// require function has access to internal Node.js modules. There is no
|
||||
+// stability guarantee about the internals exposed to the internal require
|
||||
+// function. Expect breakages when updating Node.js versions if the embedder
|
||||
+// imports internal modules with the internal require function.
|
||||
+// Worker threads created in the environment will also respect The |preload|
|
||||
+// function, so make sure the function is thread-safe.
|
||||
NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment(
|
||||
Environment* env,
|
||||
- StartExecutionCallback cb);
|
||||
+ StartExecutionCallback cb,
|
||||
+ EmbedderPreloadCallback preload = nullptr);
|
||||
NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment(
|
||||
Environment* env,
|
||||
- const char* main_script_source_utf8);
|
||||
+ const char* main_script_source_utf8,
|
||||
+ EmbedderPreloadCallback preload = nullptr);
|
||||
NODE_EXTERN void FreeEnvironment(Environment* env);
|
||||
|
||||
// Set a callback that is called when process.exit() is called from JS,
|
||||
diff --git a/src/node_options.cc b/src/node_options.cc
|
||||
index 365748f046f9d0f232d4f0ebc7b0c7f56bbd74e2..a076de0c5e577114a6166844ab3b4f02db8065ad 100644
|
||||
--- a/src/node_options.cc
|
||||
+++ b/src/node_options.cc
|
||||
@@ -1230,6 +1230,12 @@ void GetEmbedderOptions(const FunctionCallbackInfo<Value>& args) {
|
||||
Boolean::New(isolate, env->no_global_search_paths()))
|
||||
.IsNothing()) return;
|
||||
|
||||
+ if (ret->Set(context,
|
||||
+ FIXED_ONE_BYTE_STRING(env->isolate(), "hasEmbedderPreload"),
|
||||
+ Boolean::New(isolate, env->embedder_preload() != nullptr))
|
||||
+ .IsNothing())
|
||||
+ return;
|
||||
+
|
||||
args.GetReturnValue().Set(ret);
|
||||
}
|
||||
|
||||
diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc
|
||||
index f70e6ddf4303f303d7ace859b257738fd6707853..3f89973349f03128ab77f7cf3902506ec79d1272 100644
|
||||
--- a/src/node_snapshotable.cc
|
||||
+++ b/src/node_snapshotable.cc
|
||||
@@ -1462,6 +1462,17 @@ void SerializeSnapshotableObjects(Realm* realm,
|
||||
|
||||
namespace mksnapshot {
|
||||
|
||||
+void RunEmbedderPreload(const FunctionCallbackInfo<Value>& args) {
|
||||
+ Environment* env = Environment::GetCurrent(args);
|
||||
+ CHECK(env->embedder_preload());
|
||||
+ CHECK_EQ(args.Length(), 2);
|
||||
+ Local<Value> process_obj = args[0];
|
||||
+ Local<Value> require_fn = args[1];
|
||||
+ CHECK(process_obj->IsObject());
|
||||
+ CHECK(require_fn->IsFunction());
|
||||
+ env->embedder_preload()(env, process_obj, require_fn);
|
||||
+}
|
||||
+
|
||||
void CompileSerializeMain(const FunctionCallbackInfo<Value>& args) {
|
||||
CHECK(args[0]->IsString());
|
||||
Local<String> filename = args[0].As<String>();
|
||||
@@ -1515,6 +1526,7 @@ void Initialize(Local<Object> target,
|
||||
Local<Value> unused,
|
||||
Local<Context> context,
|
||||
void* priv) {
|
||||
+ SetMethod(context, target, "runEmbedderPreload", RunEmbedderPreload);
|
||||
SetMethod(context, target, "compileSerializeMain", CompileSerializeMain);
|
||||
SetMethod(context, target, "setSerializeCallback", SetSerializeCallback);
|
||||
SetMethod(context, target, "setDeserializeCallback", SetDeserializeCallback);
|
||||
@@ -1525,6 +1537,7 @@ void Initialize(Local<Object> target,
|
||||
}
|
||||
|
||||
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
||||
+ registry->Register(RunEmbedderPreload);
|
||||
registry->Register(CompileSerializeMain);
|
||||
registry->Register(SetSerializeCallback);
|
||||
registry->Register(SetDeserializeCallback);
|
||||
diff --git a/src/node_worker.cc b/src/node_worker.cc
|
||||
index 6a49144ec4f2059fe75983609b0768e4c2b1817d..13b0445370c70cf3765a4af44336c16ac2e1035d 100644
|
||||
--- a/src/node_worker.cc
|
||||
+++ b/src/node_worker.cc
|
||||
@@ -60,6 +60,7 @@ Worker::Worker(Environment* env,
|
||||
thread_id_(AllocateEnvironmentThreadId()),
|
||||
name_(name),
|
||||
env_vars_(env_vars),
|
||||
+ embedder_preload_(env->embedder_preload()),
|
||||
snapshot_data_(snapshot_data) {
|
||||
Debug(this, "Creating new worker instance with thread id %llu",
|
||||
thread_id_.id);
|
||||
@@ -354,8 +355,12 @@ void Worker::Run() {
|
||||
}
|
||||
|
||||
Debug(this, "Created message port for worker %llu", thread_id_.id);
|
||||
- if (LoadEnvironment(env_.get(), StartExecutionCallback{}).IsEmpty())
|
||||
+ if (LoadEnvironment(env_.get(),
|
||||
+ StartExecutionCallback{},
|
||||
+ std::move(embedder_preload_))
|
||||
+ .IsEmpty()) {
|
||||
return;
|
||||
+ }
|
||||
|
||||
Debug(this, "Loaded environment for worker %llu", thread_id_.id);
|
||||
}
|
||||
diff --git a/src/node_worker.h b/src/node_worker.h
|
||||
index a77c416735a79feb3f54e40d72a98c8903a20ccd..deab68576f6330f8bcfb4703fd05dbb9c515e473 100644
|
||||
--- a/src/node_worker.h
|
||||
+++ b/src/node_worker.h
|
||||
@@ -113,6 +113,7 @@ class Worker : public AsyncWrap {
|
||||
|
||||
std::unique_ptr<MessagePortData> child_port_data_;
|
||||
std::shared_ptr<KVStore> env_vars_;
|
||||
+ EmbedderPreloadCallback embedder_preload_;
|
||||
|
||||
// A raw flag that is used by creator and worker threads to
|
||||
// sync up on pre-mature termination of worker - while in the
|
||||
diff --git a/test/cctest/test_environment.cc b/test/cctest/test_environment.cc
|
||||
index 09dcb1dccc1b28048c6300e2c23c2c40722272af..54460cd9ecf3c8bbf9927598fcbaf05f5937cf9a 100644
|
||||
--- a/test/cctest/test_environment.cc
|
||||
+++ b/test/cctest/test_environment.cc
|
||||
@@ -740,3 +740,31 @@ TEST_F(EnvironmentTest, RequestInterruptAtExit) {
|
||||
|
||||
context->Exit();
|
||||
}
|
||||
+
|
||||
+TEST_F(EnvironmentTest, EmbedderPreload) {
|
||||
+ v8::HandleScope handle_scope(isolate_);
|
||||
+ v8::Local<v8::Context> context = node::NewContext(isolate_);
|
||||
+ v8::Context::Scope context_scope(context);
|
||||
+
|
||||
+ node::EmbedderPreloadCallback preload = [](node::Environment* env,
|
||||
+ v8::Local<v8::Value> process,
|
||||
+ v8::Local<v8::Value> require) {
|
||||
+ CHECK(process->IsObject());
|
||||
+ CHECK(require->IsFunction());
|
||||
+ process.As<v8::Object>()
|
||||
+ ->Set(env->context(),
|
||||
+ v8::String::NewFromUtf8Literal(env->isolate(), "prop"),
|
||||
+ v8::String::NewFromUtf8Literal(env->isolate(), "preload"))
|
||||
+ .Check();
|
||||
+ };
|
||||
+
|
||||
+ std::unique_ptr<node::Environment, decltype(&node::FreeEnvironment)> env(
|
||||
+ node::CreateEnvironment(isolate_data_, context, {}, {}),
|
||||
+ node::FreeEnvironment);
|
||||
+
|
||||
+ v8::Local<v8::Value> main_ret =
|
||||
+ node::LoadEnvironment(env.get(), "return process.prop;", preload)
|
||||
+ .ToLocalChecked();
|
||||
+ node::Utf8Value main_ret_str(isolate_, main_ret);
|
||||
+ EXPECT_EQ(std::string(*main_ret_str), "preload");
|
||||
+}
|
||||
@@ -2,3 +2,7 @@ build_gn.patch
|
||||
do_not_export_private_v8_symbols_on_windows.patch
|
||||
fix_build_deprecated_attribute_for_older_msvc_versions.patch
|
||||
chore_allow_customizing_microtask_policy_per_context.patch
|
||||
merged_wasm_add_bounds_check_in_tier-up_of_wasm-to-js_wrapper.patch
|
||||
merged_parser_fix_home_object_proxy_to_work_off-thread.patch
|
||||
merged_wasm_check_for_type-definition_count_limit.patch
|
||||
merged_runtime_recreate_enum_cache_on_map_update_if_any_previous.patch
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shu-yu Guo <syg@chromium.org>
|
||||
Date: Thu, 7 Mar 2024 14:55:28 -0800
|
||||
Subject: Merged: [parser] Fix home object proxy to work off-thread
|
||||
|
||||
Because the home object has special scope lookup rules due to class
|
||||
heritage position, VariableProxies of the home object are currently
|
||||
directly created on the correct scope during parsing. However, during
|
||||
off-thread parsing the main thread is parked, and the correct scope
|
||||
may try to dereference a main-thread Handle.
|
||||
|
||||
This CL moves the logic into ResolveVariable instead, which happens
|
||||
during postprocessing, with the main thread unparked.
|
||||
|
||||
Fixed: chromium:327740539
|
||||
|
||||
(cherry picked from commit 8f477f936c9b9e6b4c9f35a8ccc5e65bd4cb7f4e)
|
||||
|
||||
Change-Id: I16805ad35f5d70d1acadaf1f5440dfc159dbfa6c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5363634
|
||||
Reviewed-by: Deepti Gandluri <gdeepti@chromium.org>
|
||||
Commit-Queue: Shu-yu Guo <syg@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/12.2@{#44}
|
||||
Cr-Branched-From: 6eb5a9616aa6f8c705217aeb7c7ab8c037a2f676-refs/heads/12.2.281@{#1}
|
||||
Cr-Branched-From: 44cf56d850167c6988522f8981730462abc04bcc-refs/heads/main@{#91934}
|
||||
|
||||
diff --git a/src/ast/ast.h b/src/ast/ast.h
|
||||
index cf9d52eeed67a3d7685916987b540950385f98ce..7bb30723607ec9a3cef9d45b032c3edfa55bdc9c 100644
|
||||
--- a/src/ast/ast.h
|
||||
+++ b/src/ast/ast.h
|
||||
@@ -1534,6 +1534,12 @@ class VariableProxy final : public Expression {
|
||||
bit_field_ = IsRemovedFromUnresolvedField::update(bit_field_, true);
|
||||
}
|
||||
|
||||
+ bool is_home_object() const { return IsHomeObjectField::decode(bit_field_); }
|
||||
+
|
||||
+ void set_is_home_object() {
|
||||
+ bit_field_ = IsHomeObjectField::update(bit_field_, true);
|
||||
+ }
|
||||
+
|
||||
// Provides filtered access to the unresolved variable proxy threaded list.
|
||||
struct UnresolvedNext {
|
||||
static VariableProxy** filter(VariableProxy** t) {
|
||||
@@ -1565,6 +1571,7 @@ class VariableProxy final : public Expression {
|
||||
bit_field_ |= IsAssignedField::encode(false) |
|
||||
IsResolvedField::encode(false) |
|
||||
IsRemovedFromUnresolvedField::encode(false) |
|
||||
+ IsHomeObjectField::encode(false) |
|
||||
HoleCheckModeField::encode(HoleCheckMode::kElided);
|
||||
}
|
||||
|
||||
@@ -1574,7 +1581,8 @@ class VariableProxy final : public Expression {
|
||||
using IsResolvedField = IsAssignedField::Next<bool, 1>;
|
||||
using IsRemovedFromUnresolvedField = IsResolvedField::Next<bool, 1>;
|
||||
using IsNewTargetField = IsRemovedFromUnresolvedField::Next<bool, 1>;
|
||||
- using HoleCheckModeField = IsNewTargetField::Next<HoleCheckMode, 1>;
|
||||
+ using IsHomeObjectField = IsNewTargetField::Next<bool, 1>;
|
||||
+ using HoleCheckModeField = IsHomeObjectField::Next<HoleCheckMode, 1>;
|
||||
|
||||
union {
|
||||
const AstRawString* raw_name_; // if !is_resolved_
|
||||
diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc
|
||||
index 672440a2b4b9ad6262c49be50d03377b413452a6..6dfcd45cf208e58a2fc0cd18ba3b115bae35a0d5 100644
|
||||
--- a/src/ast/scopes.cc
|
||||
+++ b/src/ast/scopes.cc
|
||||
@@ -491,7 +491,6 @@ Scope* Scope::DeserializeScopeChain(IsolateT* isolate, Zone* zone,
|
||||
if (cache_scope_found) {
|
||||
outer_scope->set_deserialized_scope_uses_external_cache();
|
||||
} else {
|
||||
- DCHECK(!cache_scope_found);
|
||||
cache_scope_found =
|
||||
outer_scope->is_declaration_scope() && !outer_scope->is_eval_scope();
|
||||
}
|
||||
@@ -970,9 +969,14 @@ Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
|
||||
DCHECK(!cache->deserialized_scope_uses_external_cache());
|
||||
// The case where where the cache can be another scope is when the cache scope
|
||||
// is the last scope that doesn't use an external cache.
|
||||
+ //
|
||||
+ // The one exception to this is when looking up the home object, which may
|
||||
+ // skip multiple scopes that don't use an external cache (e.g., several arrow
|
||||
+ // functions).
|
||||
DCHECK_IMPLIES(
|
||||
cache != this,
|
||||
- cache->outer_scope()->deserialized_scope_uses_external_cache());
|
||||
+ cache->outer_scope()->deserialized_scope_uses_external_cache() ||
|
||||
+ cache->GetHomeObjectScope() == this);
|
||||
DCHECK_NULL(cache->variables_.Lookup(name));
|
||||
DisallowGarbageCollection no_gc;
|
||||
|
||||
@@ -2282,7 +2286,33 @@ Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope,
|
||||
|
||||
void Scope::ResolveVariable(VariableProxy* proxy) {
|
||||
DCHECK(!proxy->is_resolved());
|
||||
- Variable* var = Lookup<kParsedScope>(proxy, this, nullptr);
|
||||
+ Variable* var;
|
||||
+ if (V8_UNLIKELY(proxy->is_home_object())) {
|
||||
+ // VariableProxies of the home object cannot be resolved like a normal
|
||||
+ // variable. Consider the case of a super.property usage in heritage
|
||||
+ // position:
|
||||
+ //
|
||||
+ // class C extends super.foo { m() { super.bar(); } }
|
||||
+ //
|
||||
+ // The super.foo property access is logically nested under C's class scope,
|
||||
+ // which also has a home object due to its own method m's usage of
|
||||
+ // super.bar(). However, super.foo must resolve super in C's outer scope.
|
||||
+ //
|
||||
+ // Because of the above, start resolving home objects directly at the home
|
||||
+ // object scope instead of the current scope.
|
||||
+ Scope* scope = GetDeclarationScope()->GetHomeObjectScope();
|
||||
+ DCHECK_NOT_NULL(scope);
|
||||
+ if (scope->scope_info_.is_null()) {
|
||||
+ var = Lookup<kParsedScope>(proxy, scope, nullptr);
|
||||
+ } else {
|
||||
+ Scope* entry_cache = scope->deserialized_scope_uses_external_cache()
|
||||
+ ? GetNonEvalDeclarationScope()
|
||||
+ : scope;
|
||||
+ var = Lookup<kDeserializedScope>(proxy, scope, nullptr, entry_cache);
|
||||
+ }
|
||||
+ } else {
|
||||
+ var = Lookup<kParsedScope>(proxy, this, nullptr);
|
||||
+ }
|
||||
DCHECK_NOT_NULL(var);
|
||||
ResolveTo(proxy, var);
|
||||
}
|
||||
@@ -2752,48 +2782,6 @@ int Scope::ContextLocalCount() const {
|
||||
(is_function_var_in_context ? 1 : 0);
|
||||
}
|
||||
|
||||
-VariableProxy* Scope::NewHomeObjectVariableProxy(AstNodeFactory* factory,
|
||||
- const AstRawString* name,
|
||||
- int start_pos) {
|
||||
- // VariableProxies of the home object cannot be resolved like a normal
|
||||
- // variable. Consider the case of a super.property usage in heritage position:
|
||||
- //
|
||||
- // class C extends super.foo { m() { super.bar(); } }
|
||||
- //
|
||||
- // The super.foo property access is logically nested under C's class scope,
|
||||
- // which also has a home object due to its own method m's usage of
|
||||
- // super.bar(). However, super.foo must resolve super in C's outer scope.
|
||||
- //
|
||||
- // Because of the above, home object VariableProxies are always made directly
|
||||
- // on the Scope that needs the home object instead of the innermost scope.
|
||||
- DCHECK(needs_home_object());
|
||||
- if (!scope_info_.is_null()) {
|
||||
- // This is a lazy compile, so the home object's context slot is already
|
||||
- // known.
|
||||
- Variable* home_object = variables_.Lookup(name);
|
||||
- if (home_object == nullptr) {
|
||||
- VariableLookupResult lookup_result;
|
||||
- int index = scope_info_->ContextSlotIndex(name->string(), &lookup_result);
|
||||
- DCHECK_GE(index, 0);
|
||||
- bool was_added;
|
||||
- home_object = variables_.Declare(zone(), this, name, lookup_result.mode,
|
||||
- NORMAL_VARIABLE, lookup_result.init_flag,
|
||||
- lookup_result.maybe_assigned_flag,
|
||||
- IsStaticFlag::kNotStatic, &was_added);
|
||||
- DCHECK(was_added);
|
||||
- home_object->AllocateTo(VariableLocation::CONTEXT, index);
|
||||
- }
|
||||
- return factory->NewVariableProxy(home_object, start_pos);
|
||||
- }
|
||||
- // This is not a lazy compile. Add the unresolved home object VariableProxy to
|
||||
- // the unresolved list of the home object scope, which is not necessarily the
|
||||
- // innermost scope.
|
||||
- VariableProxy* proxy =
|
||||
- factory->NewVariableProxy(name, NORMAL_VARIABLE, start_pos);
|
||||
- AddUnresolved(proxy);
|
||||
- return proxy;
|
||||
-}
|
||||
-
|
||||
bool IsComplementaryAccessorPair(VariableMode a, VariableMode b) {
|
||||
switch (a) {
|
||||
case VariableMode::kPrivateGetterOnly:
|
||||
diff --git a/src/ast/scopes.h b/src/ast/scopes.h
|
||||
index b4c2e8b2136813985231a722c6dbcd26e2c17336..751aaee3d11ecc0da71e2171dd42ed4b85d00219 100644
|
||||
--- a/src/ast/scopes.h
|
||||
+++ b/src/ast/scopes.h
|
||||
@@ -603,10 +603,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
|
||||
needs_home_object_ = true;
|
||||
}
|
||||
|
||||
- VariableProxy* NewHomeObjectVariableProxy(AstNodeFactory* factory,
|
||||
- const AstRawString* name,
|
||||
- int start_pos);
|
||||
-
|
||||
bool RemoveInnerScope(Scope* inner_scope) {
|
||||
DCHECK_NOT_NULL(inner_scope);
|
||||
if (inner_scope == inner_scope_) {
|
||||
@@ -865,7 +861,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
|
||||
FunctionKind function_kind() const { return function_kind_; }
|
||||
|
||||
// Inform the scope that the corresponding code uses "super".
|
||||
- Scope* RecordSuperPropertyUsage() {
|
||||
+ void RecordSuperPropertyUsage() {
|
||||
DCHECK(IsConciseMethod(function_kind()) ||
|
||||
IsAccessorFunction(function_kind()) ||
|
||||
IsClassConstructor(function_kind()));
|
||||
@@ -873,7 +869,6 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
|
||||
Scope* home_object_scope = GetHomeObjectScope();
|
||||
DCHECK_NOT_NULL(home_object_scope);
|
||||
home_object_scope->set_needs_home_object();
|
||||
- return home_object_scope;
|
||||
}
|
||||
|
||||
bool uses_super_property() const { return uses_super_property_; }
|
||||
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
|
||||
index af7add9aa8231233dffd5f04ca491b3f614c3f97..232a6bdae48d5d6300b53bfd05b42841d2eae664 100644
|
||||
--- a/src/parsing/parser-base.h
|
||||
+++ b/src/parsing/parser-base.h
|
||||
@@ -3823,9 +3823,9 @@ ParserBase<Impl>::ParseSuperExpression() {
|
||||
impl()->ReportMessage(MessageTemplate::kOptionalChainingNoSuper);
|
||||
return impl()->FailureExpression();
|
||||
}
|
||||
- Scope* home_object_scope = scope->RecordSuperPropertyUsage();
|
||||
+ scope->RecordSuperPropertyUsage();
|
||||
UseThis();
|
||||
- return impl()->NewSuperPropertyReference(home_object_scope, pos);
|
||||
+ return impl()->NewSuperPropertyReference(pos);
|
||||
}
|
||||
// super() is only allowed in derived constructor. new super() is never
|
||||
// allowed; it's reported as an error by
|
||||
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
|
||||
index d42cd361d230de2b7da93a05785b2b721ff372cd..4c1ce5360f2b7f8a9c8a19fcee25e65b3a433db5 100644
|
||||
--- a/src/parsing/parser.cc
|
||||
+++ b/src/parsing/parser.cc
|
||||
@@ -300,18 +300,17 @@ Expression* Parser::NewThrowError(Runtime::FunctionId id,
|
||||
return factory()->NewThrow(call_constructor, pos);
|
||||
}
|
||||
|
||||
-Expression* Parser::NewSuperPropertyReference(Scope* home_object_scope,
|
||||
- int pos) {
|
||||
+Expression* Parser::NewSuperPropertyReference(int pos) {
|
||||
const AstRawString* home_object_name;
|
||||
if (IsStatic(scope()->GetReceiverScope()->function_kind())) {
|
||||
home_object_name = ast_value_factory_->dot_static_home_object_string();
|
||||
} else {
|
||||
home_object_name = ast_value_factory_->dot_home_object_string();
|
||||
}
|
||||
- return factory()->NewSuperPropertyReference(
|
||||
- home_object_scope->NewHomeObjectVariableProxy(factory(), home_object_name,
|
||||
- pos),
|
||||
- pos);
|
||||
+
|
||||
+ VariableProxy* proxy = NewUnresolved(home_object_name, pos);
|
||||
+ proxy->set_is_home_object();
|
||||
+ return factory()->NewSuperPropertyReference(proxy, pos);
|
||||
}
|
||||
|
||||
Expression* Parser::NewSuperCallReference(int pos) {
|
||||
diff --git a/src/parsing/parser.h b/src/parsing/parser.h
|
||||
index 8aede5d6a2cd38b2ad02fa2d7542ea8163c29aa9..0e92f0350b5989781bda0eeb9746cfa18cd5e179 100644
|
||||
--- a/src/parsing/parser.h
|
||||
+++ b/src/parsing/parser.h
|
||||
@@ -798,7 +798,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
|
||||
return factory()->NewThisExpression(pos);
|
||||
}
|
||||
|
||||
- Expression* NewSuperPropertyReference(Scope* home_object_scope, int pos);
|
||||
+ Expression* NewSuperPropertyReference(int pos);
|
||||
Expression* NewSuperCallReference(int pos);
|
||||
Expression* NewTargetExpression(int pos);
|
||||
Expression* ImportMetaExpression(int pos);
|
||||
diff --git a/src/parsing/preparser.h b/src/parsing/preparser.h
|
||||
index 6c4996bd06be782bd0f767a2bfb6d413cfc1ae82..2ca6b9ac407b0862d82be466eec624280b241b09 100644
|
||||
--- a/src/parsing/preparser.h
|
||||
+++ b/src/parsing/preparser.h
|
||||
@@ -1536,8 +1536,7 @@ class PreParser : public ParserBase<PreParser> {
|
||||
return PreParserExpression::This();
|
||||
}
|
||||
|
||||
- V8_INLINE PreParserExpression
|
||||
- NewSuperPropertyReference(Scope* home_object_scope, int pos) {
|
||||
+ V8_INLINE PreParserExpression NewSuperPropertyReference(int pos) {
|
||||
return PreParserExpression::Default();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Darius Mercadier <dmercadier@chromium.org>
|
||||
Date: Fri, 22 Mar 2024 17:55:04 +0100
|
||||
Subject: Merged: [runtime] Recreate enum cache on map update if any previous
|
||||
map had one
|
||||
|
||||
If any previous map in the transition tree had an enum cache, then we
|
||||
recreate one when updating the map.
|
||||
|
||||
Bug: 330760873
|
||||
(cherry picked from commit 807cf7d0b7d96212c98ed2119e07f9b2c6a23f61)
|
||||
|
||||
Change-Id: Ia9ea4cf17fef60166a0c037318eb539866aac37a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5401859
|
||||
Reviewed-by: Igor Sheludko <ishell@chromium.org>
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Auto-Submit: Darius Mercadier <dmercadier@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/12.2@{#52}
|
||||
Cr-Branched-From: 6eb5a9616aa6f8c705217aeb7c7ab8c037a2f676-refs/heads/12.2.281@{#1}
|
||||
Cr-Branched-From: 44cf56d850167c6988522f8981730462abc04bcc-refs/heads/main@{#91934}
|
||||
|
||||
diff --git a/src/objects/map-updater.cc b/src/objects/map-updater.cc
|
||||
index 7d04b0641778365d6818cc362ed7c2f0e33071fd..b7b83ad235aee5d0703b9346d552c72b0812694f 100644
|
||||
--- a/src/objects/map-updater.cc
|
||||
+++ b/src/objects/map-updater.cc
|
||||
@@ -1036,14 +1036,21 @@ MapUpdater::State MapUpdater::ConstructNewMap() {
|
||||
Handle<Map> new_map =
|
||||
Map::AddMissingTransitions(isolate_, split_map, new_descriptors);
|
||||
|
||||
+ bool had_any_enum_cache =
|
||||
+ split_map->instance_descriptors(isolate_)
|
||||
+ ->enum_cache()
|
||||
+ ->keys()
|
||||
+ ->length() > 0 ||
|
||||
+ old_descriptors_->enum_cache()->keys()->length() > 0;
|
||||
+
|
||||
// Deprecated part of the transition tree is no longer reachable, so replace
|
||||
// current instance descriptors in the "survived" part of the tree with
|
||||
// the new descriptors to maintain descriptors sharing invariant.
|
||||
split_map->ReplaceDescriptors(isolate_, *new_descriptors);
|
||||
|
||||
- // If the old descriptors had an enum cache, make sure the new ones do too.
|
||||
- if (old_descriptors_->enum_cache()->keys()->length() > 0 &&
|
||||
- new_map->NumberOfEnumerableProperties() > 0) {
|
||||
+ // If the old descriptors had an enum cache (or if {split_map}'s descriptors
|
||||
+ // had one), make sure the new ones do too.
|
||||
+ if (had_any_enum_cache && new_map->NumberOfEnumerableProperties() > 0) {
|
||||
FastKeyAccumulator::InitializeFastPropertyEnumCache(
|
||||
isolate_, new_map, new_map->NumberOfEnumerableProperties());
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Haas <ahaas@chromium.org>
|
||||
Date: Tue, 20 Feb 2024 16:27:22 +0100
|
||||
Subject: Merged: [wasm] Add bounds check in tier-up of wasm-to-js wrapper
|
||||
|
||||
The entry index in the WasmApiFunctionRef was used to look for the given
|
||||
WasmApiFunctionRef in the indirect function tables, but it was not
|
||||
considered that the indirect function tables can have different lengths.
|
||||
|
||||
R=clemensb@chromium.org
|
||||
|
||||
Bug: 325893559
|
||||
|
||||
(cherry picked from commit 7330f46163e8a2c10a3d40ecbf554656f0ac55e8)
|
||||
|
||||
Change-Id: I52355890e21490c75566216985680c64e0b0db75
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5323850
|
||||
Commit-Queue: Andreas Haas <ahaas@chromium.org>
|
||||
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/12.2@{#38}
|
||||
Cr-Branched-From: 6eb5a9616aa6f8c705217aeb7c7ab8c037a2f676-refs/heads/12.2.281@{#1}
|
||||
Cr-Branched-From: 44cf56d850167c6988522f8981730462abc04bcc-refs/heads/main@{#91934}
|
||||
|
||||
diff --git a/src/runtime/runtime-wasm.cc b/src/runtime/runtime-wasm.cc
|
||||
index 5f711bc606633bd916356f0eca5799ce63760dbd..1077e6bb3ec359ef540987d030e244f1789aa14d 100644
|
||||
--- a/src/runtime/runtime-wasm.cc
|
||||
+++ b/src/runtime/runtime-wasm.cc
|
||||
@@ -602,7 +602,8 @@ RUNTIME_FUNCTION(Runtime_TierUpWasmToJSWrapper) {
|
||||
for (int table_index = 0; table_index < table_count; ++table_index) {
|
||||
Handle<WasmIndirectFunctionTable> table =
|
||||
instance->GetIndirectFunctionTable(isolate, table_index);
|
||||
- if (table->refs()->get(entry_index) == *ref) {
|
||||
+ if (entry_index < table->refs()->length() &&
|
||||
+ table->refs()->get(entry_index) == *ref) {
|
||||
table->targets()
|
||||
->set<ExternalPointerTag::kWasmIndirectFunctionTargetTag>(
|
||||
entry_index, isolate, wasm_code->instruction_start());
|
||||
@@ -0,0 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Manos Koukoutos <manoskouk@chromium.org>
|
||||
Date: Thu, 21 Mar 2024 11:38:08 +0100
|
||||
Subject: Merged: [wasm] Check for type-definition count limit
|
||||
|
||||
(cherry picked from commit b852ad701db21d6db5b34e66f4ec1cdccd2ec4d4)
|
||||
|
||||
Bug: chromium:330575498
|
||||
Change-Id: I395f0ed6d823b7d1e139da6551486e3627d65724
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5378419
|
||||
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
|
||||
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
|
||||
Auto-Submit: Manos Koukoutos <manoskouk@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#92941}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5380190
|
||||
Reviewed-by: Francis McCabe <fgm@chromium.org>
|
||||
Commit-Queue: Adam Klein <adamk@chromium.org>
|
||||
Reviewed-by: Adam Klein <adamk@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/12.2@{#50}
|
||||
Cr-Branched-From: 6eb5a9616aa6f8c705217aeb7c7ab8c037a2f676-refs/heads/12.2.281@{#1}
|
||||
Cr-Branched-From: 44cf56d850167c6988522f8981730462abc04bcc-refs/heads/main@{#91934}
|
||||
|
||||
diff --git a/src/wasm/module-decoder-impl.h b/src/wasm/module-decoder-impl.h
|
||||
index 5629ea1f1316b974e7858006f16b52669bdd2fd5..2738fc6c2a6a325dd2c4bbc5d6f9a58f10a9c94d 100644
|
||||
--- a/src/wasm/module-decoder-impl.h
|
||||
+++ b/src/wasm/module-decoder-impl.h
|
||||
@@ -689,6 +689,11 @@ class ModuleDecoderImpl : public Decoder {
|
||||
}
|
||||
} else {
|
||||
if (tracer_) tracer_->TypeOffset(pc_offset());
|
||||
+ if (initial_size + 1 > kV8MaxWasmTypes) {
|
||||
+ errorf(pc(), "Type definition count exceeds maximum %zu",
|
||||
+ kV8MaxWasmTypes);
|
||||
+ return;
|
||||
+ }
|
||||
// Similarly to above, we need to resize types for a group of size 1.
|
||||
module_->types.resize(initial_size + 1);
|
||||
module_->isorecursive_canonical_type_ids.resize(initial_size + 1);
|
||||
@@ -1,3 +1,4 @@
|
||||
fix_fallback_to_x11_capturer_on_wayland.patch
|
||||
fix_mark_pipewire_capturer_as_failed_after_session_is_closed.patch
|
||||
fix_check_pipewire_init_before_creating_generic_capturer.patch
|
||||
tighten_som_dchecks_to_checks_in_vp9_packetization.patch
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Erik=20Spr=C3=A5ng?= <sprang@webrtc.org>
|
||||
Date: Fri, 19 Jan 2024 16:59:01 +0100
|
||||
Subject: Tighten som DCHECKs to CHECKs in VP9 packetization.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
(cherry picked from commit 6a992129fb0dede4a8fbdaf5de43abaf43c20299)
|
||||
|
||||
No-Try: True
|
||||
Bug: chromium:1518991, chromium:1518994
|
||||
Change-Id: I47f68ba6aaf4874fd952332bf213e3a1e0389268
|
||||
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335241
|
||||
Auto-Submit: Erik Språng <sprang@webrtc.org>
|
||||
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
|
||||
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#41580}
|
||||
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338640
|
||||
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
|
||||
Commit-Queue: Erik Språng <sprang@webrtc.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6167@{#6}
|
||||
Cr-Branched-From: ece5cb83715dea85617114b6d4e981fdee2623ba-refs/heads/main@{#41315}
|
||||
|
||||
diff --git a/modules/rtp_rtcp/source/rtp_format_vp9.cc b/modules/rtp_rtcp/source/rtp_format_vp9.cc
|
||||
index 15e059e85c8968c8ed72efa6b17ac998b5597f45..9ad4aa97c34aabe761739045662adc6374e3dc69 100644
|
||||
--- a/modules/rtp_rtcp/source/rtp_format_vp9.cc
|
||||
+++ b/modules/rtp_rtcp/source/rtp_format_vp9.cc
|
||||
@@ -94,8 +94,8 @@ size_t RefIndicesLength(const RTPVideoHeaderVP9& hdr) {
|
||||
if (!hdr.inter_pic_predicted || !hdr.flexible_mode)
|
||||
return 0;
|
||||
|
||||
- RTC_DCHECK_GT(hdr.num_ref_pics, 0U);
|
||||
- RTC_DCHECK_LE(hdr.num_ref_pics, kMaxVp9RefPics);
|
||||
+ RTC_CHECK_GT(hdr.num_ref_pics, 0U);
|
||||
+ RTC_CHECK_LE(hdr.num_ref_pics, kMaxVp9RefPics);
|
||||
return hdr.num_ref_pics;
|
||||
}
|
||||
|
||||
@@ -123,9 +123,9 @@ size_t SsDataLength(const RTPVideoHeaderVP9& hdr) {
|
||||
if (!hdr.ss_data_available)
|
||||
return 0;
|
||||
|
||||
- RTC_DCHECK_GT(hdr.num_spatial_layers, 0U);
|
||||
- RTC_DCHECK_LE(hdr.num_spatial_layers, kMaxVp9NumberOfSpatialLayers);
|
||||
- RTC_DCHECK_LE(hdr.gof.num_frames_in_gof, kMaxVp9FramesInGof);
|
||||
+ RTC_CHECK_GT(hdr.num_spatial_layers, 0U);
|
||||
+ RTC_CHECK_LE(hdr.num_spatial_layers, kMaxVp9NumberOfSpatialLayers);
|
||||
+ RTC_CHECK_LE(hdr.gof.num_frames_in_gof, kMaxVp9FramesInGof);
|
||||
size_t length = 1; // V
|
||||
if (hdr.spatial_layer_resolution_present) {
|
||||
length += 4 * hdr.num_spatial_layers; // Y
|
||||
@@ -136,7 +136,7 @@ size_t SsDataLength(const RTPVideoHeaderVP9& hdr) {
|
||||
// N_G
|
||||
length += hdr.gof.num_frames_in_gof; // T, U, R
|
||||
for (size_t i = 0; i < hdr.gof.num_frames_in_gof; ++i) {
|
||||
- RTC_DCHECK_LE(hdr.gof.num_ref_pics[i], kMaxVp9RefPics);
|
||||
+ RTC_CHECK_LE(hdr.gof.num_ref_pics[i], kMaxVp9RefPics);
|
||||
length += hdr.gof.num_ref_pics[i]; // R times
|
||||
}
|
||||
return length;
|
||||
@@ -248,9 +248,9 @@ bool WriteRefIndices(const RTPVideoHeaderVP9& vp9,
|
||||
// +-+-+-+-+-+-+-+-+ -| -|
|
||||
//
|
||||
bool WriteSsData(const RTPVideoHeaderVP9& vp9, rtc::BitBufferWriter* writer) {
|
||||
- RTC_DCHECK_GT(vp9.num_spatial_layers, 0U);
|
||||
- RTC_DCHECK_LE(vp9.num_spatial_layers, kMaxVp9NumberOfSpatialLayers);
|
||||
- RTC_DCHECK_LE(vp9.gof.num_frames_in_gof, kMaxVp9FramesInGof);
|
||||
+ RTC_CHECK_GT(vp9.num_spatial_layers, 0U);
|
||||
+ RTC_CHECK_LE(vp9.num_spatial_layers, kMaxVp9NumberOfSpatialLayers);
|
||||
+ RTC_CHECK_LE(vp9.gof.num_frames_in_gof, kMaxVp9FramesInGof);
|
||||
bool g_bit = vp9.gof.num_frames_in_gof > 0;
|
||||
|
||||
RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.num_spatial_layers - 1, 3));
|
||||
@@ -288,6 +288,8 @@ bool WriteSsData(const RTPVideoHeaderVP9& vp9, rtc::BitBufferWriter* writer) {
|
||||
// current API to invoke SVC is not flexible enough.
|
||||
RTPVideoHeaderVP9 RemoveInactiveSpatialLayers(
|
||||
const RTPVideoHeaderVP9& original_header) {
|
||||
+ RTC_CHECK_LE(original_header.num_spatial_layers,
|
||||
+ kMaxVp9NumberOfSpatialLayers);
|
||||
RTPVideoHeaderVP9 hdr(original_header);
|
||||
if (original_header.first_active_layer == 0)
|
||||
return hdr;
|
||||
@@ -314,7 +316,7 @@ RtpPacketizerVp9::RtpPacketizerVp9(rtc::ArrayView<const uint8_t> payload,
|
||||
header_size_(PayloadDescriptorLengthMinusSsData(hdr_)),
|
||||
first_packet_extra_header_size_(SsDataLength(hdr_)),
|
||||
remaining_payload_(payload) {
|
||||
- RTC_DCHECK_EQ(hdr_.first_active_layer, 0);
|
||||
+ RTC_CHECK_EQ(hdr_.first_active_layer, 0);
|
||||
|
||||
limits.max_payload_len -= header_size_;
|
||||
limits.first_packet_reduction_len += first_packet_extra_header_size_;
|
||||
@@ -357,8 +359,8 @@ bool RtpPacketizerVp9::NextPacket(RtpPacketToSend* packet) {
|
||||
|
||||
// Ensure end_of_picture is always set on top spatial layer when it is not
|
||||
// dropped.
|
||||
- RTC_DCHECK(hdr_.spatial_idx < hdr_.num_spatial_layers - 1 ||
|
||||
- hdr_.end_of_picture);
|
||||
+ RTC_CHECK(hdr_.spatial_idx < hdr_.num_spatial_layers - 1 ||
|
||||
+ hdr_.end_of_picture);
|
||||
|
||||
packet->SetMarker(layer_end && hdr_.end_of_picture);
|
||||
return true;
|
||||
@@ -3,19 +3,30 @@
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import warnings
|
||||
|
||||
from lib import git
|
||||
from lib.patches import patch_from_dir
|
||||
|
||||
THREEWAY = "ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES" in os.environ
|
||||
|
||||
def apply_patches(dirs):
|
||||
threeway = os.environ.get("ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES")
|
||||
for patch_dir, repo in dirs.items():
|
||||
if os.path.exists(repo):
|
||||
git.import_patches(repo=repo, patch_data=patch_from_dir(patch_dir),
|
||||
threeway=threeway is not None,
|
||||
committer_name="Electron Scripts", committer_email="scripts@electron")
|
||||
def apply_patches(target):
|
||||
repo = target.get('repo')
|
||||
if not os.path.exists(repo):
|
||||
warnings.warn('repo not found: %s' % repo)
|
||||
return
|
||||
patch_dir = target.get('patch_dir')
|
||||
git.import_patches(
|
||||
committer_email="scripts@electron",
|
||||
committer_name="Electron Scripts",
|
||||
patch_data=patch_from_dir(patch_dir),
|
||||
repo=repo,
|
||||
threeway=THREEWAY,
|
||||
)
|
||||
|
||||
def apply_config(config):
|
||||
for target in config:
|
||||
apply_patches(target)
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description='Apply Electron patches')
|
||||
@@ -26,9 +37,8 @@ def parse_args():
|
||||
|
||||
|
||||
def main():
|
||||
configs = parse_args().config
|
||||
for config_json in configs:
|
||||
apply_patches(json.load(config_json))
|
||||
for config_json in parse_args().config:
|
||||
apply_config(json.load(config_json))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -3,14 +3,27 @@
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import warnings
|
||||
|
||||
from lib import git
|
||||
|
||||
|
||||
def export_patches(dirs, dry_run):
|
||||
for patch_dir, repo in dirs.items():
|
||||
if os.path.exists(repo):
|
||||
git.export_patches(repo=repo, out_dir=patch_dir, dry_run=dry_run)
|
||||
def export_patches(target, dry_run):
|
||||
repo = target.get('repo')
|
||||
if not os.path.exists(repo):
|
||||
warnings.warn('repo not found: %s' % repo)
|
||||
return
|
||||
git.export_patches(
|
||||
dry_run=dry_run,
|
||||
grep=target.get('grep'),
|
||||
out_dir=target.get('patch_dir'),
|
||||
repo=repo
|
||||
)
|
||||
|
||||
|
||||
def export_config(config, dry_run):
|
||||
for target in config:
|
||||
export_patches(target, dry_run)
|
||||
|
||||
|
||||
def parse_args():
|
||||
@@ -28,7 +41,7 @@ def main():
|
||||
configs = parse_args().config
|
||||
dry_run = parse_args().dry_run
|
||||
for config_json in configs:
|
||||
export_patches(json.load(config_json), dry_run)
|
||||
export_config(json.load(config_json), dry_run)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -38,8 +38,8 @@ const main = async () => {
|
||||
config: 'webpack.config.worker.js'
|
||||
},
|
||||
{
|
||||
name: 'asar_bundle_deps',
|
||||
config: 'webpack.config.asar.js'
|
||||
name: 'node_bundle_deps',
|
||||
config: 'webpack.config.node.js'
|
||||
},
|
||||
{
|
||||
name: 'utility_bundle_deps',
|
||||
|
||||
@@ -10,13 +10,15 @@ def main(argv):
|
||||
parser.add_argument("-o", "--output",
|
||||
help="directory into which exported patches will be written",
|
||||
required=True)
|
||||
parser.add_argument("--grep",
|
||||
help="only export patches matching a keyword")
|
||||
parser.add_argument("patch_range",
|
||||
nargs='?',
|
||||
help="range of patches to export. Defaults to all commits since the "
|
||||
"most recent tag or remote branch.")
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
git.export_patches('.', args.output, patch_range=args.patch_range)
|
||||
git.export_patches('.', args.output, patch_range=args.patch_range, grep=args.grep)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -15,6 +15,12 @@ import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.append(SCRIPT_DIR)
|
||||
|
||||
from patches import PATCH_FILENAME_PREFIX, is_patch_location_line
|
||||
|
||||
UPSTREAM_HEAD='refs/patches/upstream-head'
|
||||
|
||||
def is_repo_root(path):
|
||||
path_exists = os.path.exists(path)
|
||||
@@ -77,14 +83,10 @@ def am(repo, patch_data, threeway=False, directory=None, exclude=None,
|
||||
proc.returncode))
|
||||
|
||||
|
||||
def import_patches(repo, **kwargs):
|
||||
def import_patches(repo, ref=UPSTREAM_HEAD, **kwargs):
|
||||
"""same as am(), but we save the upstream HEAD so we can refer to it when we
|
||||
later export patches"""
|
||||
update_ref(
|
||||
repo=repo,
|
||||
ref='refs/patches/upstream-head',
|
||||
newvalue='HEAD'
|
||||
)
|
||||
update_ref(repo=repo, ref=ref, newvalue='HEAD')
|
||||
am(repo=repo, **kwargs)
|
||||
|
||||
|
||||
@@ -94,32 +96,18 @@ def update_ref(repo, ref, newvalue):
|
||||
return subprocess.check_call(args)
|
||||
|
||||
|
||||
def get_upstream_head(repo):
|
||||
args = [
|
||||
'git',
|
||||
'-C',
|
||||
repo,
|
||||
'rev-parse',
|
||||
'--verify',
|
||||
'refs/patches/upstream-head',
|
||||
]
|
||||
def get_commit_for_ref(repo, ref):
|
||||
args = ['git', '-C', repo, 'rev-parse', '--verify', ref]
|
||||
return subprocess.check_output(args).decode('utf-8').strip()
|
||||
|
||||
def get_commit_count(repo, commit_range):
|
||||
args = [
|
||||
'git',
|
||||
'-C',
|
||||
repo,
|
||||
'rev-list',
|
||||
'--count',
|
||||
commit_range
|
||||
]
|
||||
args = ['git', '-C', repo, 'rev-list', '--count', commit_range]
|
||||
return int(subprocess.check_output(args).decode('utf-8').strip())
|
||||
|
||||
def guess_base_commit(repo):
|
||||
def guess_base_commit(repo, ref):
|
||||
"""Guess which commit the patches might be based on"""
|
||||
try:
|
||||
upstream_head = get_upstream_head(repo)
|
||||
upstream_head = get_commit_for_ref(repo, ref)
|
||||
num_commits = get_commit_count(repo, upstream_head + '..')
|
||||
return [upstream_head, num_commits]
|
||||
except subprocess.CalledProcessError:
|
||||
@@ -183,6 +171,16 @@ def split_patches(patch_data):
|
||||
patches[-1].append(line)
|
||||
return patches
|
||||
|
||||
def filter_patches(patches, key):
|
||||
"""Return patches that include the specified key"""
|
||||
if key is None:
|
||||
return patches
|
||||
matches = []
|
||||
for patch in patches:
|
||||
if any(key in line for line in patch):
|
||||
matches.append(patch)
|
||||
continue
|
||||
return matches
|
||||
|
||||
def munge_subject_to_filename(subject):
|
||||
"""Derive a suitable filename from a commit's subject"""
|
||||
@@ -195,8 +193,8 @@ def get_file_name(patch):
|
||||
"""Return the name of the file to which the patch should be written"""
|
||||
file_name = None
|
||||
for line in patch:
|
||||
if line.startswith('Patch-Filename: '):
|
||||
file_name = line[len('Patch-Filename: '):]
|
||||
if line.startswith(PATCH_FILENAME_PREFIX):
|
||||
file_name = line[len(PATCH_FILENAME_PREFIX):]
|
||||
break
|
||||
# If no patch-filename header, munge the subject.
|
||||
if not file_name:
|
||||
@@ -209,19 +207,18 @@ def get_file_name(patch):
|
||||
|
||||
def join_patch(patch):
|
||||
"""Joins and formats patch contents"""
|
||||
return ''.join(remove_patch_filename(patch)).rstrip('\n') + '\n'
|
||||
return ''.join(remove_patch_location(patch)).rstrip('\n') + '\n'
|
||||
|
||||
|
||||
def remove_patch_filename(patch):
|
||||
"""Strip out the Patch-Filename trailer from a patch's message body"""
|
||||
def remove_patch_location(patch):
|
||||
"""Strip out the patch location lines from a patch's message body"""
|
||||
force_keep_next_line = False
|
||||
n = len(patch)
|
||||
for i, l in enumerate(patch):
|
||||
is_patchfilename = l.startswith('Patch-Filename: ')
|
||||
next_is_patchfilename = i < len(patch) - 1 and patch[i + 1].startswith(
|
||||
'Patch-Filename: '
|
||||
)
|
||||
skip_line = is_patch_location_line(l)
|
||||
skip_next = i < n - 1 and is_patch_location_line(patch[i + 1])
|
||||
if not force_keep_next_line and (
|
||||
is_patchfilename or (next_is_patchfilename and len(l.rstrip()) == 0)
|
||||
skip_line or (skip_next and len(l.rstrip()) == 0)
|
||||
):
|
||||
pass # drop this line
|
||||
else:
|
||||
@@ -237,18 +234,24 @@ def to_utf8(patch):
|
||||
return unicode(patch, "utf-8")
|
||||
|
||||
|
||||
def export_patches(repo, out_dir, patch_range=None, dry_run=False):
|
||||
def export_patches(repo, out_dir,
|
||||
patch_range=None, ref=UPSTREAM_HEAD,
|
||||
dry_run=False, grep=None):
|
||||
if not os.path.exists(repo):
|
||||
sys.stderr.write(
|
||||
"Skipping patches in {} because it does not exist.\n".format(repo)
|
||||
)
|
||||
return
|
||||
if patch_range is None:
|
||||
patch_range, num_patches = guess_base_commit(repo)
|
||||
patch_range, num_patches = guess_base_commit(repo, ref)
|
||||
sys.stderr.write("Exporting {} patches in {} since {}\n".format(
|
||||
num_patches, repo, patch_range[0:7]))
|
||||
patch_data = format_patch(repo, patch_range)
|
||||
patches = split_patches(patch_data)
|
||||
if grep:
|
||||
olen = len(patches)
|
||||
patches = filter_patches(patches, grep)
|
||||
sys.stderr.write("Exporting {} of {} patches\n".format(len(patches), olen))
|
||||
|
||||
try:
|
||||
os.mkdir(out_dir)
|
||||
|
||||
@@ -3,19 +3,27 @@
|
||||
import codecs
|
||||
import os
|
||||
|
||||
PATCH_DIR_PREFIX = "Patch-Dir: "
|
||||
PATCH_FILENAME_PREFIX = "Patch-Filename: "
|
||||
PATCH_LINE_PREFIXES = (PATCH_DIR_PREFIX, PATCH_FILENAME_PREFIX)
|
||||
|
||||
|
||||
def is_patch_location_line(line):
|
||||
return line.startswith(PATCH_LINE_PREFIXES)
|
||||
|
||||
def read_patch(patch_dir, patch_filename):
|
||||
"""Read a patch from |patch_dir/filename| and amend the commit message with
|
||||
metadata about the patch file it came from."""
|
||||
ret = []
|
||||
added_filename_line = False
|
||||
added_patch_location = False
|
||||
patch_path = os.path.join(patch_dir, patch_filename)
|
||||
with codecs.open(patch_path, encoding='utf-8') as f:
|
||||
for l in f.readlines():
|
||||
line_has_correct_start = l.startswith('diff -') or l.startswith('---')
|
||||
if not added_filename_line and line_has_correct_start:
|
||||
ret.append('Patch-Filename: {}\n'.format(patch_filename))
|
||||
added_filename_line = True
|
||||
if not added_patch_location and line_has_correct_start:
|
||||
ret.append('{}{}\n'.format(PATCH_DIR_PREFIX, patch_dir))
|
||||
ret.append('{}{}\n'.format(PATCH_FILENAME_PREFIX, patch_filename))
|
||||
added_patch_location = True
|
||||
ret.append(l)
|
||||
return ''.join(ret)
|
||||
|
||||
|
||||
@@ -258,10 +258,9 @@ const LINTERS = [
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const config = JSON.parse(fs.readFileSync(patchesConfig, 'utf8'));
|
||||
for (const key of Object.keys(config)) {
|
||||
for (const target of JSON.parse(fs.readFileSync(patchesConfig, 'utf8'))) {
|
||||
// The directory the config points to should exist
|
||||
const targetPatchesDir = path.resolve(__dirname, '../../..', key);
|
||||
const targetPatchesDir = path.resolve(__dirname, '../../..', target.patch_dir);
|
||||
if (!fs.existsSync(targetPatchesDir)) {
|
||||
console.error(
|
||||
`target patch directory: "${targetPatchesDir}" does not exist`
|
||||
|
||||
@@ -14,7 +14,9 @@ from lib.patches import patch_from_dir
|
||||
|
||||
|
||||
def patched_file_paths(patches_config):
|
||||
for patch_dir, repo in patches_config.items():
|
||||
for target in patches_config:
|
||||
patch_dir = target.get('patch_dir')
|
||||
repo = target.get('repo')
|
||||
for line in patch_from_dir(patch_dir).split("\n"):
|
||||
if line.startswith("+++"):
|
||||
yield posixpath.join(repo, line[6:])
|
||||
|
||||
@@ -70,7 +70,14 @@ async function checkAppVeyorImage (options) {
|
||||
const { cloudSettings } = settings;
|
||||
return cloudSettings.images.find(image => image.name === `${options.imageVersion}`) || null;
|
||||
} catch (err) {
|
||||
console.log('Could not call AppVeyor: ', err);
|
||||
if (err.response?.body) {
|
||||
console.error('Could not call AppVeyor: ', {
|
||||
statusCode: err.response.statusCode,
|
||||
body: JSON.parse(err.response.body)
|
||||
});
|
||||
} else {
|
||||
console.error('Error calling AppVeyor:', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -183,7 +183,14 @@ async function circleCIRequest (url, method, requestBody) {
|
||||
}
|
||||
|
||||
return makeRequest(requestOpts, true).catch(err => {
|
||||
console.log('Error calling CircleCI:', err);
|
||||
if (err.response?.body) {
|
||||
console.error('Could not call CircleCI: ', {
|
||||
statusCode: err.response.statusCode,
|
||||
body: JSON.parse(err.response.body)
|
||||
});
|
||||
} else {
|
||||
console.error('Error calling CircleCI:', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -234,7 +241,14 @@ async function callAppVeyor (targetBranch, job, options) {
|
||||
const buildUrl = `https://ci.appveyor.com/project/electron-bot/${appVeyorJobs[job]}/build/${version}`;
|
||||
console.log(`AppVeyor release build request for ${job} successful. Check build status at ${buildUrl}`);
|
||||
} catch (err) {
|
||||
console.log('Could not call AppVeyor: ', err);
|
||||
if (err.response?.body) {
|
||||
console.error('Could not call AppVeyor: ', {
|
||||
statusCode: err.response.statusCode,
|
||||
body: JSON.parse(err.response.body)
|
||||
});
|
||||
} else {
|
||||
console.error('Error calling AppVeyor:', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,14 @@ module.exports = async function getUrlHash (targetUrl, algorithm = 'sha256', att
|
||||
return resp.body.trim();
|
||||
} catch (err) {
|
||||
if (attempts > 1) {
|
||||
console.error('Failed to get URL hash for', targetUrl, 'we will retry', err);
|
||||
if (err.response?.body) {
|
||||
console.error(`Failed to get URL hash for ${targetUrl} - we will retry`, {
|
||||
statusCode: err.response.statusCode,
|
||||
body: JSON.parse(err.response.body)
|
||||
});
|
||||
} else {
|
||||
console.error(`Failed to get URL hash for ${targetUrl} - we will retry`, err);
|
||||
}
|
||||
return getUrlHash(targetUrl, algorithm, attempts - 1);
|
||||
}
|
||||
throw err;
|
||||
|
||||
@@ -27,7 +27,9 @@ const getHeaders = (filePath: string, fileName: string) => {
|
||||
if (!extension) {
|
||||
throw new Error(`Failed to get headers for extensionless file: ${fileName}`);
|
||||
}
|
||||
console.log(`About to get size of ${filePath}`);
|
||||
const size = fs.statSync(filePath).size;
|
||||
console.log(`Got size of ${filePath}: ${size}`);
|
||||
const options: Record<string, string> = {
|
||||
json: 'text/json',
|
||||
zip: 'application/zip',
|
||||
@@ -46,10 +48,13 @@ const uploadUrl = `https://uploads.github.com/repos/electron/${targetRepo}/relea
|
||||
let retry = 0;
|
||||
|
||||
function uploadToGitHub () {
|
||||
console.log(`in uploadToGitHub for ${filePath}, ${fileName}`);
|
||||
const fileData = fs.createReadStream(filePath);
|
||||
console.log(`in uploadToGitHub, created readstream for ${filePath}`);
|
||||
octokit.repos.uploadReleaseAsset({
|
||||
url: uploadUrl,
|
||||
headers: getHeaders(filePath, fileName),
|
||||
data: fs.createReadStream(filePath) as any,
|
||||
data: fileData as any,
|
||||
name: fileName,
|
||||
owner: 'electron',
|
||||
repo: targetRepo,
|
||||
|
||||
@@ -363,10 +363,13 @@ def upload_io_to_github(release, filename, filepath, version):
|
||||
(filename))
|
||||
script_path = os.path.join(
|
||||
ELECTRON_DIR, 'script', 'release', 'uploaders', 'upload-to-github.ts')
|
||||
upload_gh_output = execute([TS_NODE, script_path, filepath, filename,
|
||||
str(release['id']), version])
|
||||
upload_process = subprocess.Popen([TS_NODE, script_path, filepath, filename,
|
||||
str(release['id']), version], stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
if is_verbose_mode():
|
||||
print(upload_gh_output)
|
||||
for c in iter(lambda: upload_process.stdout.read(1), b""):
|
||||
sys.stdout.buffer.write(c)
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def upload_sha256_checksum(version, file_path, key_prefix=None):
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "shell/app/electron_content_client.h"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -105,12 +106,12 @@ bool IsWidevineAvailable(
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_WIDEVINE)
|
||||
|
||||
void AppendDelimitedSwitchToVector(const base::StringPiece cmd_switch,
|
||||
void AppendDelimitedSwitchToVector(const std::string_view cmd_switch,
|
||||
std::vector<std::string>* append_me) {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto switch_value = command_line->GetSwitchValueASCII(cmd_switch);
|
||||
if (!switch_value.empty()) {
|
||||
constexpr base::StringPiece delimiter(",", 1);
|
||||
constexpr std::string_view delimiter{",", 1};
|
||||
auto tokens =
|
||||
base::SplitString(switch_value, delimiter, base::TRIM_WHITESPACE,
|
||||
base::SPLIT_WANT_NONEMPTY);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include "base/apple/bundle_locations.h"
|
||||
@@ -80,9 +81,9 @@ namespace {
|
||||
|
||||
const char kRelauncherProcess[] = "relauncher";
|
||||
|
||||
constexpr base::StringPiece kElectronDisableSandbox("ELECTRON_DISABLE_SANDBOX");
|
||||
constexpr base::StringPiece kElectronEnableStackDumping(
|
||||
"ELECTRON_ENABLE_STACK_DUMPING");
|
||||
constexpr std::string_view kElectronDisableSandbox{"ELECTRON_DISABLE_SANDBOX"};
|
||||
constexpr std::string_view kElectronEnableStackDumping{
|
||||
"ELECTRON_ENABLE_STACK_DUMPING"};
|
||||
|
||||
// Returns true if this subprocess type needs the ResourceBundle initialized
|
||||
// and resources loaded.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user