mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70a66589ae | ||
|
|
6d5b65ec35 | ||
|
|
ec2adf0b2e | ||
|
|
2d9eaffb98 | ||
|
|
3d3bd64ab2 | ||
|
|
8b9170b664 | ||
|
|
6b2c470f46 | ||
|
|
f53fad8abb | ||
|
|
7b2c526a43 | ||
|
|
1da86c0fbf | ||
|
|
166bcd3208 | ||
|
|
133cd29201 | ||
|
|
3511eb1a8e | ||
|
|
426cd1d68c | ||
|
|
2c152014c4 | ||
|
|
d1a6d98a93 | ||
|
|
ea680012de | ||
|
|
d635f34565 | ||
|
|
18bf1d2f59 | ||
|
|
4a0d4975f3 | ||
|
|
56ac51cfa2 | ||
|
|
d297808531 | ||
|
|
077c4addd5 | ||
|
|
c3c5734fa8 | ||
|
|
62c97ffecf | ||
|
|
24b841cbcd | ||
|
|
b1377d42d9 | ||
|
|
ca92ebff25 | ||
|
|
f6af8959c3 | ||
|
|
94d5a7429d | ||
|
|
d5065e5ec5 | ||
|
|
2d559ca855 | ||
|
|
f9ac250f6d | ||
|
|
b87b14d739 | ||
|
|
5c3ab4e1ee | ||
|
|
08ce63f8a5 | ||
|
|
72332f4574 | ||
|
|
0c195c0e20 | ||
|
|
8b1d8d7e6a | ||
|
|
8c0365a276 | ||
|
|
c9c159db15 | ||
|
|
b3ca1a1f96 | ||
|
|
1a99aa73a9 | ||
|
|
503c81785d | ||
|
|
6a504f260e | ||
|
|
aca67b1761 | ||
|
|
b7a9bdc425 | ||
|
|
ad0b24cfe2 | ||
|
|
6db0b9c70d | ||
|
|
79be0be8cb | ||
|
|
c12f2eec55 | ||
|
|
3ed0d0a502 | ||
|
|
8471e47507 | ||
|
|
a7cdf2c7ad | ||
|
|
fde45bcab8 | ||
|
|
40e2d6e2f0 | ||
|
|
267cbc841e | ||
|
|
0cb2077ab3 | ||
|
|
8605079453 | ||
|
|
b788b3d65c | ||
|
|
f842ead6bc | ||
|
|
dace26c191 | ||
|
|
81984bc728 |
@@ -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
|
||||
@@ -1656,17 +1658,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
|
||||
@@ -2296,6 +2296,7 @@ jobs:
|
||||
<<: *env-global
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
parallelism: 3
|
||||
steps:
|
||||
- electron-tests:
|
||||
artifact-key: linux-arm
|
||||
@@ -2307,6 +2308,7 @@ jobs:
|
||||
<<: *env-global
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
parallelism: 3
|
||||
steps:
|
||||
- electron-tests:
|
||||
artifact-key: linux-arm64
|
||||
@@ -2324,8 +2326,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
|
||||
@@ -2349,7 +2354,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
@@ -164,15 +164,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" ]
|
||||
|
||||
@@ -218,6 +209,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" ]
|
||||
|
||||
@@ -229,9 +229,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",
|
||||
@@ -239,9 +239,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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 = ""
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -61,8 +61,9 @@ The `protocol` module has the following methods:
|
||||
module gets emitted and can be called only once.
|
||||
|
||||
Registers the `scheme` as standard, secure, bypasses content security policy for
|
||||
resources, allows registering ServiceWorker, supports fetch API, and streaming
|
||||
video/audio. Specify a privilege with the value of `true` to enable the capability.
|
||||
resources, allows registering ServiceWorker, supports fetch API, streaming
|
||||
video/audio, and V8 code cache. Specify a privilege with the value of `true` to
|
||||
enable the capability.
|
||||
|
||||
An example of registering a privileged scheme, that bypasses Content Security
|
||||
Policy:
|
||||
|
||||
@@ -1356,6 +1356,10 @@ registered.
|
||||
Sets the directory to store the generated JS [code cache](https://v8.dev/blog/code-caching-for-devs) for this session. The directory is not required to be created by the user before this call, the runtime will create if it does not exist otherwise will use the existing directory. If directory cannot be created, then code cache will not be used and all operations related to code cache will fail silently inside the runtime. By default, the directory will be `Code Cache` under the
|
||||
respective user data folder.
|
||||
|
||||
Note that by default code cache is only enabled for http(s) URLs, to enable code
|
||||
cache for custom protocols, `codeCache: true` and `standard: true` must be
|
||||
specified when registering the protocol.
|
||||
|
||||
#### `ses.clearCodeCaches(options)`
|
||||
|
||||
* `options` Object
|
||||
|
||||
@@ -9,3 +9,5 @@
|
||||
* `supportFetchAPI` boolean (optional) - Default false.
|
||||
* `corsEnabled` boolean (optional) - Default false.
|
||||
* `stream` boolean (optional) - Default false.
|
||||
* `codeCache` boolean (optional) - Enable V8 code cache for the scheme, only
|
||||
works when `standard` is also set to true. Default false.
|
||||
|
||||
@@ -45,6 +45,18 @@ systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })
|
||||
nativeTheme.on('updated', () => { /* ... */ })
|
||||
```
|
||||
|
||||
### Removed: Some `window.setVibrancy` options on macOS
|
||||
|
||||
The following vibrancy options have been removed:
|
||||
|
||||
* 'light'
|
||||
* 'medium-light'
|
||||
* 'dark'
|
||||
* 'ultra-dark'
|
||||
* 'appearance-based'
|
||||
|
||||
These were previously deprecated and have been removed by Apple in 10.15.
|
||||
|
||||
### Removed: `webContents.getPrinters`
|
||||
|
||||
The `webContents.getPrinters` method has been removed. Use
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -14,10 +14,10 @@ process:
|
||||
|
||||
Electron will listen for V8 inspector protocol messages on the specified `port`,
|
||||
an external debugger will need to connect on this port. The default `port` is
|
||||
`5858`.
|
||||
`9229`.
|
||||
|
||||
```shell
|
||||
electron --inspect=5858 your/app
|
||||
electron --inspect=9229 your/app
|
||||
```
|
||||
|
||||
### `--inspect-brk=[port]`
|
||||
|
||||
@@ -214,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",
|
||||
@@ -250,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",
|
||||
@@ -273,7 +272,6 @@ auto_filenames = {
|
||||
"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-provider.ts",
|
||||
"lib/renderer/api/clipboard.ts",
|
||||
@@ -312,7 +310,6 @@ auto_filenames = {
|
||||
"lib/common/deprecate.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",
|
||||
@@ -331,10 +328,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",
|
||||
@@ -343,12 +339,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",
|
||||
|
||||
@@ -167,6 +167,8 @@ filenames = {
|
||||
"shell/common/language_util_mac.mm",
|
||||
"shell/common/mac/main_application_bundle.h",
|
||||
"shell/common/mac/main_application_bundle.mm",
|
||||
"shell/common/mac/codesign_util.cc",
|
||||
"shell/common/mac/codesign_util.h",
|
||||
"shell/common/node_bindings_mac.cc",
|
||||
"shell/common/node_bindings_mac.h",
|
||||
"shell/common/platform_util_mac.mm",
|
||||
@@ -249,7 +251,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",
|
||||
@@ -275,8 +276,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",
|
||||
@@ -515,8 +514,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",
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
import { wrapFsWithAsar } from './fs-wrapper';
|
||||
|
||||
wrapFsWithAsar(require('fs'));
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -10,9 +10,6 @@ const Module = require('module');
|
||||
// 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,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);
|
||||
}
|
||||
@@ -73,3 +73,43 @@ if (process.platform === 'win32') {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const Module = require('module');
|
||||
|
||||
// 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: string, parent: NodeModule, isMain: boolean, options?: { paths: Array<string>}) {
|
||||
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');
|
||||
|
||||
// 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);
|
||||
};
|
||||
}
|
||||
|
||||
// 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: string, parent: NodeModule, isMain: boolean, options?: { paths: Array<string>}) {
|
||||
if (electronModuleNames.has(request)) {
|
||||
return 'electron';
|
||||
} else {
|
||||
return originalResolveFilename(request, parent, isMain, options);
|
||||
}
|
||||
};
|
||||
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');
|
||||
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;
|
||||
}
|
||||
};
|
||||
@@ -6,6 +6,16 @@ import type * as ipcRendererUtilsModule from '@electron/internal/renderer/ipc-re
|
||||
|
||||
const Module = require('module');
|
||||
|
||||
// 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.
|
||||
//
|
||||
@@ -32,9 +42,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,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,5 @@
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
import { ParentPort } from '@electron/internal/utility/parent-port';
|
||||
const Module = require('module');
|
||||
const v8Util = process._linkedBinding('electron_common_v8_util');
|
||||
@@ -7,12 +9,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');
|
||||
// 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.8.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",
|
||||
|
||||
2
patches/DirectXShaderCompiler/.patches
Normal file
2
patches/DirectXShaderCompiler/.patches
Normal file
@@ -0,0 +1,2 @@
|
||||
fix_hlmatrixlowerpass_leaving_call_to_dangling_functionval.patch
|
||||
cherry-pick-a65e511a14b4.patch
|
||||
66
patches/DirectXShaderCompiler/cherry-pick-a65e511a14b4.patch
Normal file
66
patches/DirectXShaderCompiler/cherry-pick-a65e511a14b4.patch
Normal file
@@ -0,0 +1,66 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Antonio Maiorano <amaiorano@google.com>
|
||||
Date: Wed, 3 Apr 2024 15:58:51 -0400
|
||||
Subject: Fix ASAN use-after-free on unreferenced self-assignment of struct
|
||||
instance (#6466)
|
||||
|
||||
When deleting an unused memcpy, ScalarReplAggregatesHLSL was attempting
|
||||
to delete both the target and the source of the memcpy without first
|
||||
checking if they were both same, resulting in a double-delete.
|
||||
|
||||
Bug: chromium:331123811
|
||||
Change-Id: Idaef95a06b10a7fb6f0ca2e662972a44ec662fbc
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/microsoft/DirectXShaderCompiler/+/5419225
|
||||
Reviewed-by: David Neto <dneto@google.com>
|
||||
Reviewed-by: dan sinclair <dsinclair@chromium.org>
|
||||
Reviewed-by: Ben Clayton <bclayton@chromium.org>
|
||||
|
||||
diff --git a/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp b/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
|
||||
index b3589884aa3b690e1aad5ca7a19218a222591d39..8e2eff7f69ec378393c7a9afc4040cd9e921c42d 100644
|
||||
--- a/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
|
||||
+++ b/lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
|
||||
@@ -989,9 +989,11 @@ void DeleteMemcpy(MemCpyInst *MI) {
|
||||
if (op0->user_empty())
|
||||
op0->eraseFromParent();
|
||||
}
|
||||
- if (Instruction *op1 = dyn_cast<Instruction>(Op1)) {
|
||||
- if (op1->user_empty())
|
||||
- op1->eraseFromParent();
|
||||
+ if (Op0 != Op1) {
|
||||
+ if (Instruction *op1 = dyn_cast<Instruction>(Op1)) {
|
||||
+ if (op1->user_empty())
|
||||
+ op1->eraseFromParent();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/tools/clang/test/DXC/unreferenced_struct_selft_assignment_crash.hlsl b/tools/clang/test/DXC/unreferenced_struct_selft_assignment_crash.hlsl
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..81adf71867c9868992372e12dc1ba81aebb48344
|
||||
--- /dev/null
|
||||
+++ b/tools/clang/test/DXC/unreferenced_struct_selft_assignment_crash.hlsl
|
||||
@@ -0,0 +1,24 @@
|
||||
+// RUN: %dxc -T cs_6_0 %s | FileCheck %s
|
||||
+
|
||||
+// Validate that self-assignment of a static struct instance that is not
|
||||
+// referenced does not crash the compiler. This was resulting in an ASAN
|
||||
+// use-after-free in ScalarReplAggregatesHLSL because DeleteMemcpy would
|
||||
+// attempt to delete both source and target, even if both were the same.
|
||||
+// CHECK: define void @main() {
|
||||
+// CHECK-NEXT: ret void
|
||||
+// CHECK-NEXT: }
|
||||
+
|
||||
+struct MyStruct {
|
||||
+ int m0;
|
||||
+};
|
||||
+
|
||||
+static MyStruct s;
|
||||
+
|
||||
+void foo() {
|
||||
+ s = s;
|
||||
+}
|
||||
+
|
||||
+[numthreads(1, 1, 1)]
|
||||
+void main() {
|
||||
+ foo();
|
||||
+}
|
||||
@@ -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 e35ff832ecff9f2e46eecbd74f4b8b2f7cc7f700..c3a7254ef2b2f894a36ba8499b4aa9ace0afb8fa 100644
|
||||
--- a/lib/HLSL/HLMatrixLowerPass.cpp
|
||||
+++ b/lib/HLSL/HLMatrixLowerPass.cpp
|
||||
@@ -381,6 +381,11 @@ Value* HLMatrixLowerPass::getLoweredByValOperand(Value *Val, IRBuilder<> &Builde
|
||||
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);
|
||||
Function *TranslationStub = m_matToVecStubs->get(TranslationStubTy);
|
||||
8
patches/angle/.patches
Normal file
8
patches/angle/.patches
Normal file
@@ -0,0 +1,8 @@
|
||||
m120_translator_optimize_field-name-collision_check.patch
|
||||
m120_translator_fail_compilation_if_too_many_struct_fields.patch
|
||||
m120_translator_limit_private_variable_size_to_64kb.patch
|
||||
m120_vulkan_don_t_crash_when_glcopyteximage2d_redefines_itself.patch
|
||||
m123_vulkan_fix_access_to_inactive_attributes.patch
|
||||
cherry-pick-f6672dbbe223.patch
|
||||
m119_move_invalid_uniform_protection_to_the_frontend.patch
|
||||
m120_fix_off-by-one_bounds_check_on_uniform_location.patch
|
||||
267
patches/angle/cherry-pick-f6672dbbe223.patch
Normal file
267
patches/angle/cherry-pick-f6672dbbe223.patch
Normal file
@@ -0,0 +1,267 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Mon, 25 Mar 2024 14:46:56 -0400
|
||||
Subject: M123: Translator: Disallow samplers in structs in interface blocks
|
||||
|
||||
As disallowed by the spec:
|
||||
|
||||
> Types and declarators are the same as for other uniform variable
|
||||
> declarations outside blocks, with these exceptions:
|
||||
>
|
||||
> * opaque types are not allowed
|
||||
|
||||
Bug: chromium:328859176
|
||||
Change-Id: Ib94977860102329e520e635c3757827c93ca2163
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5391986
|
||||
Auto-Submit: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Reviewed-by: Geoff Lang <geofflang@chromium.org>
|
||||
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
(cherry picked from commit a0fa06f6d79ced897c0fe2795551268199d29806)
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5435737
|
||||
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
|
||||
|
||||
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
|
||||
index e174725beb764407185e471a9916ffd164493cd8..cb9eb3a4a566348f11aa5962037164147bc65684 100644
|
||||
--- a/src/compiler/translator/ParseContext.cpp
|
||||
+++ b/src/compiler/translator/ParseContext.cpp
|
||||
@@ -34,27 +34,39 @@ namespace
|
||||
|
||||
const int kWebGLMaxStructNesting = 4;
|
||||
|
||||
-bool ContainsSampler(const TStructure *structType);
|
||||
+struct IsSamplerFunc
|
||||
+{
|
||||
+ bool operator()(TBasicType type) { return IsSampler(type); }
|
||||
+};
|
||||
+struct IsOpaqueFunc
|
||||
+{
|
||||
+ bool operator()(TBasicType type) { return IsOpaqueType(type); }
|
||||
+};
|
||||
+
|
||||
+template <typename OpaqueFunc>
|
||||
+bool ContainsOpaque(const TStructure *structType);
|
||||
|
||||
-bool ContainsSampler(const TType &type)
|
||||
+template <typename OpaqueFunc>
|
||||
+bool ContainsOpaque(const TType &type)
|
||||
{
|
||||
- if (IsSampler(type.getBasicType()))
|
||||
+ if (OpaqueFunc{}(type.getBasicType()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (type.getBasicType() == EbtStruct)
|
||||
{
|
||||
- return ContainsSampler(type.getStruct());
|
||||
+ return ContainsOpaque<OpaqueFunc>(type.getStruct());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
-bool ContainsSampler(const TStructure *structType)
|
||||
+template <typename OpaqueFunc>
|
||||
+bool ContainsOpaque(const TStructure *structType)
|
||||
{
|
||||
for (const auto &field : structType->fields())
|
||||
{
|
||||
- if (ContainsSampler(*field->type()))
|
||||
+ if (ContainsOpaque<OpaqueFunc>(*field->type()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -1057,7 +1069,7 @@ bool TParseContext::checkIsNotOpaqueType(const TSourceLoc &line,
|
||||
{
|
||||
if (pType.type == EbtStruct)
|
||||
{
|
||||
- if (ContainsSampler(pType.userDef))
|
||||
+ if (ContainsOpaque<IsSamplerFunc>(pType.userDef))
|
||||
{
|
||||
std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
|
||||
reasonStream << reason << " (structure contains a sampler)";
|
||||
@@ -4923,12 +4935,9 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
|
||||
{
|
||||
TField *field = (*fieldList)[memberIndex];
|
||||
TType *fieldType = field->type();
|
||||
- if (IsOpaqueType(fieldType->getBasicType()))
|
||||
+ if (ContainsOpaque<IsOpaqueFunc>(*fieldType))
|
||||
{
|
||||
- std::string reason("unsupported type - ");
|
||||
- reason += fieldType->getBasicString();
|
||||
- reason += " types are not allowed in interface blocks";
|
||||
- error(field->line(), reason.c_str(), fieldType->getBasicString());
|
||||
+ error(field->line(), "Opaque types are not allowed in interface blocks", blockName);
|
||||
}
|
||||
|
||||
const TQualifier qualifier = fieldType->getQualifier();
|
||||
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
|
||||
index f4b7ce6222ff4a29cb20b75bc102e2c8ae478189..8ac5b758b128ded933d727f7dccb0ce8f8eb338b 100644
|
||||
--- a/src/tests/gl_tests/GLSLTest.cpp
|
||||
+++ b/src/tests/gl_tests/GLSLTest.cpp
|
||||
@@ -6716,7 +6716,34 @@ void main()
|
||||
gl_FragColor = vec4(f(us), 0, 0, 1);
|
||||
})";
|
||||
|
||||
- CompileShader(GL_FRAGMENT_SHADER, kFS);
|
||||
+ GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
|
||||
+ EXPECT_NE(fs, 0u);
|
||||
+ ASSERT_GL_NO_ERROR();
|
||||
+}
|
||||
+
|
||||
+// Test that structs with samplers are not allowed in interface blocks. This is forbidden per
|
||||
+// GLES3:
|
||||
+//
|
||||
+// > Types and declarators are the same as for other uniform variable declarations outside blocks,
|
||||
+// > with these exceptions:
|
||||
+// > * opaque types are not allowed
|
||||
+TEST_P(GLSLTest_ES3, StructWithSamplersDisallowedInInterfaceBlock)
|
||||
+{
|
||||
+ const char kFS[] = R"(#version 300 es
|
||||
+precision mediump float;
|
||||
+struct S { sampler2D samp; bool b; };
|
||||
+
|
||||
+layout(std140) uniform Buffer { S s; } buffer;
|
||||
+
|
||||
+out vec4 color;
|
||||
+
|
||||
+void main()
|
||||
+{
|
||||
+ color = texture(buffer.s.samp, vec2(0));
|
||||
+})";
|
||||
+
|
||||
+ GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
|
||||
+ EXPECT_EQ(fs, 0u);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
@@ -18195,6 +18222,116 @@ void main() {
|
||||
EXPECT_EQ(0u, shader);
|
||||
}
|
||||
|
||||
+// Same as TooManyFieldsInStruct, but with samplers in the struct.
|
||||
+TEST_P(GLSLTest_ES3, TooManySamplerFieldsInStruct)
|
||||
+{
|
||||
+ std::ostringstream fs;
|
||||
+ fs << R"(#version 300 es
|
||||
+precision highp float;
|
||||
+struct TooManyFields
|
||||
+{
|
||||
+)";
|
||||
+ for (uint32_t i = 0; i < (1 << 16); ++i)
|
||||
+ {
|
||||
+ fs << " sampler2D field" << i << ";\n";
|
||||
+ }
|
||||
+ fs << R"(};
|
||||
+uniform TooManyFields s;
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ color = texture(s.field0, vec2(0));
|
||||
+})";
|
||||
+
|
||||
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fs.str().c_str());
|
||||
+ EXPECT_EQ(0u, shader);
|
||||
+}
|
||||
+
|
||||
+// More complex variation of ManySamplerFieldsInStruct. This one compiles fine.
|
||||
+TEST_P(GLSLTest_ES3, ManySamplerFieldsInStructComplex)
|
||||
+{
|
||||
+ // D3D and OpenGL may be more restrictive about this many samplers.
|
||||
+ ANGLE_SKIP_TEST_IF(IsD3D() || IsOpenGL());
|
||||
+
|
||||
+ std::ostringstream fs;
|
||||
+ fs << R"(#version 300 es
|
||||
+precision highp float;
|
||||
+
|
||||
+struct X {
|
||||
+ mediump sampler2D a[0xf00];
|
||||
+ mediump sampler2D b[0xf00];
|
||||
+ mediump sampler2D c[0xf000];
|
||||
+ mediump sampler2D d[0xf00];
|
||||
+};
|
||||
+
|
||||
+struct Y {
|
||||
+ X s1;
|
||||
+ mediump sampler2D a[0xf00];
|
||||
+ mediump sampler2D b[0xf000];
|
||||
+ mediump sampler2D c[0x14000];
|
||||
+};
|
||||
+
|
||||
+struct S {
|
||||
+ Y s1;
|
||||
+};
|
||||
+
|
||||
+struct structBuffer { S s; };
|
||||
+
|
||||
+uniform structBuffer b;
|
||||
+
|
||||
+out vec4 color;
|
||||
+void main()
|
||||
+{
|
||||
+ color = texture(b.s.s1.s1.c[0], vec2(0));
|
||||
+})";
|
||||
+
|
||||
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fs.str().c_str());
|
||||
+ EXPECT_NE(0u, shader);
|
||||
+}
|
||||
+
|
||||
+// Make sure a large array of samplers works.
|
||||
+TEST_P(GLSLTest, ManySamplers)
|
||||
+{
|
||||
+ // D3D and OpenGL may be more restrictive about this many samplers.
|
||||
+ ANGLE_SKIP_TEST_IF(IsD3D() || IsOpenGL());
|
||||
+
|
||||
+ std::ostringstream fs;
|
||||
+ fs << R"(precision highp float;
|
||||
+
|
||||
+uniform mediump sampler2D c[0x12000];
|
||||
+
|
||||
+void main()
|
||||
+{
|
||||
+ gl_FragColor = texture2D(c[0], vec2(0));
|
||||
+})";
|
||||
+
|
||||
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fs.str().c_str());
|
||||
+ EXPECT_NE(0u, shader);
|
||||
+}
|
||||
+
|
||||
+// Make sure a large array of samplers works when declared in a struct.
|
||||
+TEST_P(GLSLTest, ManySamplersInStruct)
|
||||
+{
|
||||
+ // D3D and OpenGL may be more restrictive about this many samplers.
|
||||
+ ANGLE_SKIP_TEST_IF(IsD3D() || IsOpenGL());
|
||||
+
|
||||
+ std::ostringstream fs;
|
||||
+ fs << R"(precision highp float;
|
||||
+
|
||||
+struct X {
|
||||
+ mediump sampler2D c[0x12000];
|
||||
+};
|
||||
+
|
||||
+uniform X x;
|
||||
+
|
||||
+void main()
|
||||
+{
|
||||
+ gl_FragColor = texture2D(x.c[0], vec2(0));
|
||||
+})";
|
||||
+
|
||||
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fs.str().c_str());
|
||||
+ EXPECT_NE(0u, shader);
|
||||
+}
|
||||
+
|
||||
// Test that passing large arrays to functions are compiled correctly. Regression test for the
|
||||
// SPIR-V generator that made a copy of the array to pass to the function, by decomposing and
|
||||
// reconstructing it (in the absence of OpCopyLogical), but the reconstruction instruction has a
|
||||
diff --git a/src/tests/gl_tests/PixelLocalStorageTest.cpp b/src/tests/gl_tests/PixelLocalStorageTest.cpp
|
||||
index c49ba5741ad565ad9637fb2188a472ccbebc6284..126936271eb25eec601349a560fabc6f0f7d4b75 100644
|
||||
--- a/src/tests/gl_tests/PixelLocalStorageTest.cpp
|
||||
+++ b/src/tests/gl_tests/PixelLocalStorageTest.cpp
|
||||
@@ -5573,8 +5573,7 @@ TEST_P(PixelLocalStorageCompilerTest, Declarations)
|
||||
EXPECT_FALSE(log.compileFragmentShader(kPLSInStruct));
|
||||
EXPECT_TRUE(log.has("ERROR: 0:5: 'pixelLocalANGLE' : disallowed type in struct"));
|
||||
EXPECT_TRUE(
|
||||
- log.has("ERROR: 0:10: 'pixelLocalANGLE' : unsupported type - pixelLocalANGLE types are not "
|
||||
- "allowed in interface blocks"));
|
||||
+ log.has("ERROR: 0:10: 'PLSBlock' : Opaque types are not allowed in interface blocks"));
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Lang <geofflang@chromium.org>
|
||||
Date: Tue, 17 Oct 2023 11:39:10 -0400
|
||||
Subject: M119: Move invalid uniform protection to the frontend.
|
||||
|
||||
The frontend potentialy indexes into mUniformLocations with invalid
|
||||
uniform locations while validation is disabled too. Move the validation
|
||||
from the Metal backend to the frontend.
|
||||
|
||||
Bug: chromium:1484878
|
||||
Change-Id: I92bc43aa28cfa26d601bb28f318860375f618608
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4947652
|
||||
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
(cherry picked from commit e076d6cfd0e1d6948623bb344c5a38753b0c2b2e)
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4969232
|
||||
Reviewed-by: Kenneth Russell <kbr@chromium.org>
|
||||
|
||||
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
|
||||
index 5caab257c909d81ea40c8bdad6bca8ce5e9c72c7..5dc66027831b0d1ac1915faf0d32223d6a71cd1c 100644
|
||||
--- a/src/libANGLE/Program.cpp
|
||||
+++ b/src/libANGLE/Program.cpp
|
||||
@@ -2192,7 +2192,7 @@ GLuint Program::getUniformIndex(const std::string &name) const
|
||||
|
||||
bool Program::shouldIgnoreUniform(UniformLocation location) const
|
||||
{
|
||||
- if (location.value == -1)
|
||||
+ if (location.value < 0 || static_cast<size_t>(location.value) >= mUniformLocations.size())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
diff --git a/src/libANGLE/renderer/metal/ProgramMtl.mm b/src/libANGLE/renderer/metal/ProgramMtl.mm
|
||||
index 5b86c4a8e0fa00012460d2e14101494c1dc4fa82..c7b98020e47c2f881815685e122ecaa57dbc1ad9 100644
|
||||
--- a/src/libANGLE/renderer/metal/ProgramMtl.mm
|
||||
+++ b/src/libANGLE/renderer/metal/ProgramMtl.mm
|
||||
@@ -766,22 +766,10 @@ void operator()() override
|
||||
ProgramExecutableMtl *executableMtl = getExecutable();
|
||||
|
||||
const std::vector<gl::VariableLocation> &uniformLocations = mState.getUniformLocations();
|
||||
- if (location < 0 || static_cast<size_t>(location) >= uniformLocations.size())
|
||||
- {
|
||||
- ERR() << "Invalid uniform location " << location << ", expected [0, "
|
||||
- << uniformLocations.size() << ")";
|
||||
- return;
|
||||
- }
|
||||
- const gl::VariableLocation &locationInfo = uniformLocations[location];
|
||||
+ const gl::VariableLocation &locationInfo = uniformLocations[location];
|
||||
|
||||
const std::vector<gl::LinkedUniform> &linkedUniforms = mState.getUniforms();
|
||||
- if (locationInfo.index >= linkedUniforms.size())
|
||||
- {
|
||||
- ERR() << "Invalid uniform location index " << locationInfo.index << ", expected [0, "
|
||||
- << linkedUniforms.size() << ")";
|
||||
- return;
|
||||
- }
|
||||
- const gl::LinkedUniform &linkedUniform = linkedUniforms[locationInfo.index];
|
||||
+ const gl::LinkedUniform &linkedUniform = linkedUniforms[locationInfo.index];
|
||||
|
||||
if (linkedUniform.isSampler())
|
||||
{
|
||||
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Lang <geofflang@chromium.org>
|
||||
Date: Wed, 22 Nov 2023 12:01:31 -0500
|
||||
Subject: M120: Fix off-by-one bounds check on uniform location.
|
||||
|
||||
Log an error when the user provides an invalid uniform location.
|
||||
|
||||
Bug: chromium:1504162
|
||||
Bug: chromium:1484878
|
||||
Change-Id: Ieb7eb964d508954ac8dfa8e4d9bd941778185223
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5054238
|
||||
Commit-Queue: Geoff Lang <geofflang@chromium.org>
|
||||
Reviewed-by: James Godfrey-Kittle <jamesgk@google.com>
|
||||
(cherry picked from commit fba482b7107ccf3e178f6bf56b6b0285407ace3a)
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5080772
|
||||
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
|
||||
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
|
||||
index 5dc66027831b0d1ac1915faf0d32223d6a71cd1c..d9e9582679b1e16e122c7e7b0a699e23cf45ae46 100644
|
||||
--- a/src/libANGLE/Program.cpp
|
||||
+++ b/src/libANGLE/Program.cpp
|
||||
@@ -2192,13 +2192,15 @@ GLuint Program::getUniformIndex(const std::string &name) const
|
||||
|
||||
bool Program::shouldIgnoreUniform(UniformLocation location) const
|
||||
{
|
||||
- if (location.value < 0 || static_cast<size_t>(location.value) >= mUniformLocations.size())
|
||||
+ if (location.value < 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
- if (mState.mExecutable->mUniformLocations[static_cast<size_t>(location.value)].ignored)
|
||||
+ if (static_cast<size_t>(location.value) >= mState.mExecutable->mUniformLocations.size())
|
||||
{
|
||||
+ ERR() << "Invalid uniform location " << location.value << ", expected [0, "
|
||||
+ << mState.mExecutable->mUniformLocations.size() << ")";
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Thu, 30 Nov 2023 14:12:42 -0500
|
||||
Subject: M120: Translator: Fail compilation if too many struct fields
|
||||
|
||||
If there are too many struct fields, SPIR-V cannot be produced (as it
|
||||
has a hard limit of 16383 fields). The Nvidia GL driver has also been
|
||||
observed to fail when there are too many fields.
|
||||
|
||||
Bug: chromium:1505009
|
||||
Change-Id: I29fd61d180175e89e7db9ca8ba49ab07585b5f9a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5143827
|
||||
Reviewed-by: Cody Northrop <cnorthrop@google.com>
|
||||
|
||||
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
|
||||
index 7c90ea4f1d23a8af0cab1d44124eea021a27a16d..e174725beb764407185e471a9916ffd164493cd8 100644
|
||||
--- a/src/compiler/translator/ParseContext.cpp
|
||||
+++ b/src/compiler/translator/ParseContext.cpp
|
||||
@@ -4726,6 +4726,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
|
||||
const TVector<unsigned int> *arraySizes,
|
||||
const TSourceLoc &arraySizesLine)
|
||||
{
|
||||
+ checkDoesNotHaveTooManyFields(blockName, fieldList, nameLine);
|
||||
+
|
||||
// Ensure there are no duplicate field names
|
||||
checkDoesNotHaveDuplicateFieldNames(fieldList, nameLine);
|
||||
|
||||
@@ -6289,6 +6291,21 @@ void TParseContext::checkDoesNotHaveDuplicateFieldNames(const TFieldList *fields
|
||||
}
|
||||
}
|
||||
|
||||
+void TParseContext::checkDoesNotHaveTooManyFields(const ImmutableString &name,
|
||||
+ const TFieldList *fields,
|
||||
+ const TSourceLoc &location)
|
||||
+{
|
||||
+ // Check that there are not too many fields. SPIR-V has a limit of 16383 fields, and it would
|
||||
+ // be reasonable to apply that limit to all outputs. For example, it was observed that 32768
|
||||
+ // fields cause the Nvidia GL driver to fail compilation, so such a limit is not too specific to
|
||||
+ // SPIR-V.
|
||||
+ constexpr size_t kMaxFieldCount = 16383;
|
||||
+ if (fields->size() > kMaxFieldCount)
|
||||
+ {
|
||||
+ error(location, "Too many fields in the struct (limit is 16383)", name);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
TFieldList *TParseContext::addStructFieldList(TFieldList *fields, const TSourceLoc &location)
|
||||
{
|
||||
return fields;
|
||||
@@ -6392,6 +6409,8 @@ TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
|
||||
}
|
||||
}
|
||||
|
||||
+ checkDoesNotHaveTooManyFields(structName, fieldList, structLine);
|
||||
+
|
||||
// Ensure there are no duplicate field names
|
||||
checkDoesNotHaveDuplicateFieldNames(fieldList, structLine);
|
||||
|
||||
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
|
||||
index b63dbbadd146d1a004513823de72c89240a31929..c83b73271b557ed122668d7e655deae5aa23bc48 100644
|
||||
--- a/src/compiler/translator/ParseContext.h
|
||||
+++ b/src/compiler/translator/ParseContext.h
|
||||
@@ -355,6 +355,9 @@ class TParseContext : angle::NonCopyable
|
||||
const TVector<unsigned int> *arraySizes);
|
||||
|
||||
void checkDoesNotHaveDuplicateFieldNames(const TFieldList *fields, const TSourceLoc &location);
|
||||
+ void checkDoesNotHaveTooManyFields(const ImmutableString &name,
|
||||
+ const TFieldList *fields,
|
||||
+ const TSourceLoc &location);
|
||||
TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
|
||||
TFieldList *combineStructFieldLists(TFieldList *processedFields,
|
||||
const TFieldList *newlyAddedFields,
|
||||
diff --git a/src/tests/compiler_tests/ExpressionLimit_test.cpp b/src/tests/compiler_tests/ExpressionLimit_test.cpp
|
||||
index d399e1792d97edb76d5e0247e4166e094cecb7e5..e17eace1b4b9a4185d6833fb7895f5fd49ae7679 100644
|
||||
--- a/src/tests/compiler_tests/ExpressionLimit_test.cpp
|
||||
+++ b/src/tests/compiler_tests/ExpressionLimit_test.cpp
|
||||
@@ -16,12 +16,6 @@ class ExpressionLimitTest : public testing::Test
|
||||
static const int kMaxExpressionComplexity = 16;
|
||||
static const int kMaxCallStackDepth = 16;
|
||||
static const int kMaxFunctionParameters = 16;
|
||||
- static const char *kExpressionTooComplex;
|
||||
- static const char *kCallStackTooDeep;
|
||||
- static const char *kHasRecursion;
|
||||
- static const char *kTooManyParameters;
|
||||
- static const char *kTooComplexSwitch;
|
||||
- static const char *kGlobalVariableInit;
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
@@ -125,9 +119,7 @@ class ExpressionLimitTest : public testing::Test
|
||||
|
||||
GenerateDeepFunctionStack(length, &ss);
|
||||
|
||||
- ss << "void main() {\n"
|
||||
- << " gl_FragColor = function" << length << "();\n"
|
||||
- << "}";
|
||||
+ ss << "void main() {\n" << " gl_FragColor = function" << length << "();\n" << "}";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
@@ -138,9 +130,7 @@ class ExpressionLimitTest : public testing::Test
|
||||
|
||||
GenerateDeepFunctionStack(length, &ss);
|
||||
|
||||
- ss << "void main() {\n"
|
||||
- << " gl_FragColor = vec4(0,0,0,0);\n"
|
||||
- << "}";
|
||||
+ ss << "void main() {\n" << " gl_FragColor = vec4(0,0,0,0);\n" << "}";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
@@ -149,9 +139,7 @@ class ExpressionLimitTest : public testing::Test
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
- ss << "precision mediump float;\n"
|
||||
- << "\n"
|
||||
- << "float foo(";
|
||||
+ ss << "precision mediump float;\n" << "\n" << "float foo(";
|
||||
for (int i = 0; i < parameters; ++i)
|
||||
{
|
||||
ss << "float f" << i;
|
||||
@@ -244,15 +232,13 @@ class ExpressionLimitTest : public testing::Test
|
||||
ShBuiltInResources resources;
|
||||
};
|
||||
|
||||
-const char *ExpressionLimitTest::kExpressionTooComplex = "Expression too complex";
|
||||
-const char *ExpressionLimitTest::kCallStackTooDeep = "Call stack too deep";
|
||||
-const char *ExpressionLimitTest::kHasRecursion =
|
||||
- "Recursive function call in the following call chain";
|
||||
-const char *ExpressionLimitTest::kTooManyParameters = "Function has too many parameters";
|
||||
-const char *ExpressionLimitTest::kTooComplexSwitch =
|
||||
- "too complex expressions inside a switch statement";
|
||||
-const char *ExpressionLimitTest::kGlobalVariableInit =
|
||||
- "global variable initializers must be constant expressions";
|
||||
+constexpr char kExpressionTooComplex[] = "Expression too complex";
|
||||
+constexpr char kCallStackTooDeep[] = "Call stack too deep";
|
||||
+constexpr char kHasRecursion[] = "Recursive function call in the following call chain";
|
||||
+constexpr char kTooManyParameters[] = "Function has too many parameters";
|
||||
+constexpr char kTooComplexSwitch[] = "too complex expressions inside a switch statement";
|
||||
+constexpr char kGlobalVariableInit[] = "global variable initializers must be constant expressions";
|
||||
+constexpr char kTooManyFields[] = "Too many fields in the struct";
|
||||
|
||||
TEST_F(ExpressionLimitTest, ExpressionComplexity)
|
||||
{
|
||||
@@ -632,3 +618,31 @@ TEST_F(ExpressionLimitTest, NestingInsideGlobalInitializer)
|
||||
compileOptions, nullptr));
|
||||
sh::Destruct(compiler);
|
||||
}
|
||||
+
|
||||
+TEST_F(ExpressionLimitTest, TooManyStructFields)
|
||||
+{
|
||||
+ ShShaderSpec spec = SH_WEBGL2_SPEC;
|
||||
+ ShShaderOutput output = SH_ESSL_OUTPUT;
|
||||
+ ShHandle compiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, spec, output, &resources);
|
||||
+ ShCompileOptions compileOptions = {};
|
||||
+
|
||||
+ std::ostringstream fs;
|
||||
+ fs << R"(#version 300 es
|
||||
+precision highp float;
|
||||
+struct TooManyFields
|
||||
+{
|
||||
+)";
|
||||
+ for (uint32_t i = 0; i < (1 << 16); ++i)
|
||||
+ {
|
||||
+ fs << " float field" << i << ";\n";
|
||||
+ }
|
||||
+ fs << R"(};
|
||||
+uniform B { TooManyFields s; };
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ color = vec4(s.field0, 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ EXPECT_TRUE(CheckShaderCompilation(compiler, fs.str().c_str(), compileOptions, kTooManyFields));
|
||||
+ sh::Destruct(compiler);
|
||||
+}
|
||||
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
|
||||
index 0fa89f59a38165b8d526a99bae60c7b752dec15d..d7eb48eacfe58fc128fc2d24088ac18ea5196c05 100644
|
||||
--- a/src/tests/gl_tests/GLSLTest.cpp
|
||||
+++ b/src/tests/gl_tests/GLSLTest.cpp
|
||||
@@ -18168,6 +18168,33 @@ void main() {
|
||||
ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), fs.str().c_str());
|
||||
}
|
||||
|
||||
+// Test that structs with too many fields are rejected. In SPIR-V, the instruction that defines the
|
||||
+// struct lists the fields which means the length of the instruction is a function of the field
|
||||
+// count. Since SPIR-V instruction sizes are limited to 16 bits, structs with more fields cannot be
|
||||
+// represented.
|
||||
+TEST_P(GLSLTest_ES3, TooManyFieldsInStruct)
|
||||
+{
|
||||
+ std::ostringstream fs;
|
||||
+ fs << R"(#version 300 es
|
||||
+precision highp float;
|
||||
+struct TooManyFields
|
||||
+{
|
||||
+)";
|
||||
+ for (uint32_t i = 0; i < (1 << 16); ++i)
|
||||
+ {
|
||||
+ fs << " float field" << i << ";\n";
|
||||
+ }
|
||||
+ fs << R"(};
|
||||
+uniform B { TooManyFields s; };
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ color = vec4(s.field0, 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fs.str().c_str());
|
||||
+ EXPECT_EQ(0u, shader);
|
||||
+}
|
||||
+
|
||||
} // anonymous namespace
|
||||
|
||||
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(GLSLTest);
|
||||
@@ -0,0 +1,416 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Thu, 30 Nov 2023 15:42:32 -0500
|
||||
Subject: M120: Translator: Limit private variable size to 64KB
|
||||
|
||||
This is indirectly fixing an issue where passing large arrays in SPIR-V
|
||||
such that an internal cast is needed (such as array inside interface
|
||||
block copied to local varaible) causes an overflow of the instruction
|
||||
length limit (in the absence of OpCopyLogical).
|
||||
|
||||
By limiting the size of private variables to 32KB, this limitation is
|
||||
indirectly enforced. It was observed that all the test shaders added in
|
||||
this CL fail on the Nvidia OpenGL drivers, so such a limit seems to be
|
||||
reasonble.
|
||||
|
||||
Bug: chromium:1505009
|
||||
Change-Id: I75a1e40a538120ffc69ae7edafbdba5830c6b0bb
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5143828
|
||||
Reviewed-by: Cody Northrop <cnorthrop@google.com>
|
||||
|
||||
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
|
||||
index 1f3a4d52f2f45e7ed10b9b5512f2f92a06877256..c70c419631a1c4d382bcc8ba36c35d0ba06c2c5d 100644
|
||||
--- a/src/compiler/translator/Compiler.cpp
|
||||
+++ b/src/compiler/translator/Compiler.cpp
|
||||
@@ -771,11 +771,6 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
|
||||
return false;
|
||||
}
|
||||
|
||||
- if (shouldLimitTypeSizes() && !ValidateTypeSizeLimitations(root, &mSymbolTable, &mDiagnostics))
|
||||
- {
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
if (!ValidateFragColorAndFragData(mShaderType, mShaderVersion, mSymbolTable, &mDiagnostics))
|
||||
{
|
||||
return false;
|
||||
@@ -1056,6 +1051,13 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
|
||||
return false;
|
||||
}
|
||||
|
||||
+ // Run after RemoveUnreferencedVariables, validate that the shader does not have excessively
|
||||
+ // large variables.
|
||||
+ if (shouldLimitTypeSizes() && !ValidateTypeSizeLimitations(root, &mSymbolTable, &mDiagnostics))
|
||||
+ {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
// Built-in function emulation needs to happen after validateLimitations pass.
|
||||
GetGlobalPoolAllocator()->lock();
|
||||
initBuiltInFunctionEmulator(&mBuiltInFunctionEmulator, compileOptions);
|
||||
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
index f0ff9cb11ac39e62672285300c8f41641f12c617..8f02c65b5ec5fd20b8bcee2bc595cfb278f758b4 100644
|
||||
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
@@ -24,10 +24,11 @@ namespace
|
||||
// Arbitrarily enforce that all types declared with a size in bytes of over 2 GB will cause
|
||||
// compilation failure.
|
||||
//
|
||||
-// For local and global variables, the limit is much lower (16MB) as that much memory won't fit in
|
||||
+// For local and global variables, the limit is much lower (64KB) as that much memory won't fit in
|
||||
// the GPU registers anyway.
|
||||
-constexpr size_t kMaxVariableSizeInBytes = static_cast<size_t>(2) * 1024 * 1024 * 1024;
|
||||
-constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast<size_t>(16) * 1024 * 1024;
|
||||
+constexpr size_t kMaxVariableSizeInBytes = static_cast<size_t>(2) * 1024 * 1024 * 1024;
|
||||
+constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast<size_t>(64) * 1024;
|
||||
+constexpr size_t kMaxTotalPrivateVariableSizeInBytes = static_cast<size_t>(16) * 1024 * 1024;
|
||||
|
||||
// Traverses intermediate tree to ensure that the shader does not
|
||||
// exceed certain implementation-defined limits on the sizes of types.
|
||||
@@ -70,43 +71,115 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
|
||||
continue;
|
||||
}
|
||||
|
||||
- const TType &variableType = asSymbol->getType();
|
||||
-
|
||||
- // Create a ShaderVariable from which to compute
|
||||
- // (conservative) sizing information.
|
||||
- ShaderVariable shaderVar;
|
||||
- setCommonVariableProperties(variableType, variable, &shaderVar);
|
||||
-
|
||||
- // Compute the std140 layout of this variable, assuming
|
||||
- // it's a member of a block (which it might not be).
|
||||
- Std140BlockEncoder layoutEncoder;
|
||||
- BlockEncoderVisitor visitor("", "", &layoutEncoder);
|
||||
- // Since the size limit's arbitrary, it doesn't matter
|
||||
- // whether the row-major layout is correctly determined.
|
||||
- bool isRowMajorLayout = false;
|
||||
- TraverseShaderVariable(shaderVar, isRowMajorLayout, &visitor);
|
||||
- if (layoutEncoder.getCurrentOffset() > kMaxVariableSizeInBytes)
|
||||
+ if (!validateVariableSize(variable, asSymbol->getLine()))
|
||||
{
|
||||
- error(asSymbol->getLine(),
|
||||
- "Size of declared variable exceeds implementation-defined limit",
|
||||
- asSymbol->getName());
|
||||
return false;
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override
|
||||
+ {
|
||||
+ const TFunction *function = node->getFunction();
|
||||
+ const size_t paramCount = function->getParamCount();
|
||||
+
|
||||
+ for (size_t paramIndex = 0; paramIndex < paramCount; ++paramIndex)
|
||||
+ {
|
||||
+ validateVariableSize(*function->getParam(paramIndex), node->getLine());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ bool validateVariableSize(const TVariable &variable, const TSourceLoc &location)
|
||||
+ {
|
||||
+ const TType &variableType = variable.getType();
|
||||
+
|
||||
+ // Create a ShaderVariable from which to compute
|
||||
+ // (conservative) sizing information.
|
||||
+ ShaderVariable shaderVar;
|
||||
+ setCommonVariableProperties(variableType, variable, &shaderVar);
|
||||
+
|
||||
+ // Compute the std140 layout of this variable, assuming
|
||||
+ // it's a member of a block (which it might not be).
|
||||
+ Std140BlockEncoder layoutEncoder;
|
||||
+ BlockEncoderVisitor visitor("", "", &layoutEncoder);
|
||||
+ // Since the size limit's arbitrary, it doesn't matter
|
||||
+ // whether the row-major layout is correctly determined.
|
||||
+ bool isRowMajorLayout = false;
|
||||
+ TraverseShaderVariable(shaderVar, isRowMajorLayout, &visitor);
|
||||
+ if (layoutEncoder.getCurrentOffset() > kMaxVariableSizeInBytes)
|
||||
+ {
|
||||
+ error(location, "Size of declared variable exceeds implementation-defined limit",
|
||||
+ variable.name());
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // Skip over struct declarations. As long as they are not used (or if they are used later
|
||||
+ // in a less-restricted context (such as a UBO or SSBO)), they can be larger than
|
||||
+ // kMaxPrivateVariableSizeInBytes.
|
||||
+ if (variable.symbolType() == SymbolType::Empty && variableType.isStructSpecifier())
|
||||
+ {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ switch (variableType.getQualifier())
|
||||
+ {
|
||||
+ // List of all types that need to be limited (for example because they cause overflows
|
||||
+ // in drivers, or create trouble for the SPIR-V gen as the number of an instruction's
|
||||
+ // arguments cannot be more than 64KB (see OutputSPIRVTraverser::cast)).
|
||||
+
|
||||
+ // Local/global variables
|
||||
+ case EvqTemporary:
|
||||
+ case EvqGlobal:
|
||||
+ case EvqConst:
|
||||
+
|
||||
+ // Function arguments
|
||||
+ case EvqParamIn:
|
||||
+ case EvqParamOut:
|
||||
+ case EvqParamInOut:
|
||||
+ case EvqParamConst:
|
||||
+
|
||||
+ // Varyings
|
||||
+ case EvqVaryingIn:
|
||||
+ case EvqVaryingOut:
|
||||
+ case EvqSmoothOut:
|
||||
+ case EvqFlatOut:
|
||||
+ case EvqNoPerspectiveOut:
|
||||
+ case EvqCentroidOut:
|
||||
+ case EvqSampleOut:
|
||||
+ case EvqNoPerspectiveCentroidOut:
|
||||
+ case EvqNoPerspectiveSampleOut:
|
||||
+ case EvqSmoothIn:
|
||||
+ case EvqFlatIn:
|
||||
+ case EvqNoPerspectiveIn:
|
||||
+ case EvqCentroidIn:
|
||||
+ case EvqNoPerspectiveCentroidIn:
|
||||
+ case EvqNoPerspectiveSampleIn:
|
||||
+ case EvqVertexOut:
|
||||
+ case EvqFragmentIn:
|
||||
+ case EvqGeometryIn:
|
||||
+ case EvqGeometryOut:
|
||||
+ case EvqPerVertexIn:
|
||||
+ case EvqPerVertexOut:
|
||||
+ case EvqPatchIn:
|
||||
+ case EvqPatchOut:
|
||||
+ case EvqTessControlIn:
|
||||
+ case EvqTessControlOut:
|
||||
+ case EvqTessEvaluationIn:
|
||||
+ case EvqTessEvaluationOut:
|
||||
|
||||
- const bool isPrivate = variableType.getQualifier() == EvqTemporary ||
|
||||
- variableType.getQualifier() == EvqGlobal ||
|
||||
- variableType.getQualifier() == EvqConst;
|
||||
- if (isPrivate)
|
||||
- {
|
||||
if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes)
|
||||
{
|
||||
- error(asSymbol->getLine(),
|
||||
+ error(location,
|
||||
"Size of declared private variable exceeds implementation-defined limit",
|
||||
- asSymbol->getName());
|
||||
+ variable.name());
|
||||
return false;
|
||||
}
|
||||
mTotalPrivateVariablesSize += layoutEncoder.getCurrentOffset();
|
||||
- }
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -115,7 +188,7 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
|
||||
void validateTotalPrivateVariableSize()
|
||||
{
|
||||
if (mTotalPrivateVariablesSize.ValueOrDefault(std::numeric_limits<size_t>::max()) >
|
||||
- kMaxPrivateVariableSizeInBytes)
|
||||
+ kMaxTotalPrivateVariableSizeInBytes)
|
||||
{
|
||||
mDiagnostics->error(
|
||||
TSourceLoc{},
|
||||
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
|
||||
index 91233461298150dff48e4d044eb8535e1bcfb7b6..f1343f8e8ad65b6fa292c630214c66aaf3ff5a64 100644
|
||||
--- a/src/tests/angle_end2end_tests_expectations.txt
|
||||
+++ b/src/tests/angle_end2end_tests_expectations.txt
|
||||
@@ -110,6 +110,8 @@ b/273271471 WIN INTEL VULKAN : ShaderAlgorithmTest.rgb_to_hsl_vertex_shader/* =
|
||||
7872 WIN INTEL OPENGL : VertexAttributeTest.AliasingMatrixAttribLocations/ES2_OpenGL = SKIP
|
||||
7872 WIN INTEL OPENGL : VertexAttributeTest.ShortUnnormalized/ES2_OpenGL = SKIP
|
||||
7872 WIN INTEL OPENGL : ViewportTest.DoubleWindowCentered/ES2_OpenGL = SKIP
|
||||
+8441 WIN INTEL OPENGL : GLSLTest_ES3.LargeInterfaceBlockArray/* = SKIP
|
||||
+8441 WIN INTEL OPENGL : GLSLTest_ES3.LargeInterfaceBlockNestedArray/* = SKIP
|
||||
|
||||
// Linux
|
||||
6065 LINUX INTEL VULKAN : SimpleStateChangeTestES31.DrawThenUpdateUBOThenDrawThenDrawIndexed/* = SKIP
|
||||
@@ -146,6 +148,10 @@ b/273271471 WIN INTEL VULKAN : ShaderAlgorithmTest.rgb_to_hsl_vertex_shader/* =
|
||||
6977 LINUX NVIDIA OpenGL : MipmapTestES31.GenerateLowerMipsWithDraw/* = SKIP
|
||||
7301 LINUX NVIDIA OpenGL : CopyTexImageTest.RGBAToRGB/ES2_OpenGL_EmulateCopyTexImage2DFromRenderbuffers/* = SKIP
|
||||
7371 LINUX NVIDIA OpenGL : FramebufferTest_ES3.SurfaceDimensionsChangeAndFragCoord/* = SKIP
|
||||
+8441 NVIDIA OPENGL : GLSLTest_ES3.LargeInterfaceBlockArray/* = SKIP
|
||||
+8441 NVIDIA OPENGL : GLSLTest_ES3.LargeInterfaceBlockNestedArray/* = SKIP
|
||||
+8441 NVIDIA GLES : GLSLTest_ES3.LargeInterfaceBlockArray/* = SKIP
|
||||
+8441 NVIDIA GLES : GLSLTest_ES3.LargeInterfaceBlockNestedArray/* = SKIP
|
||||
|
||||
// Nvidia Vulkan
|
||||
7236 NVIDIA VULKAN : GLSLTest_ES31.TessellationControlShaderMatrixCopyBug/* = SKIP
|
||||
@@ -1055,6 +1061,8 @@ b/273271471 WIN INTEL VULKAN : ShaderAlgorithmTest.rgb_to_hsl_vertex_shader/* =
|
||||
7389 MAC OPENGL : Texture2DTest.ManySupersedingTextureUpdates/* = SKIP
|
||||
|
||||
8437 MAC OPENGL : GLSLTest_ES3.LotsOfFieldsInStruct/* = SKIP
|
||||
+8437 MAC OPENGL : GLSLTest_ES3.LargeInterfaceBlockArray/* = SKIP
|
||||
+8437 MAC OPENGL : GLSLTest_ES3.LargeInterfaceBlockNestedArray/* = SKIP
|
||||
|
||||
// GL, GLES run into issues with cleanup
|
||||
7495 WIN OpenGL : EGLMultiContextTest.ReuseUnterminatedDisplay/* = SKIP
|
||||
diff --git a/src/tests/compiler_tests/RecordConstantPrecision_test.cpp b/src/tests/compiler_tests/RecordConstantPrecision_test.cpp
|
||||
index 07923f991423f4ec1ff8cbe81fb822c2b526d149..9446576ac797c0e5db8f9c63d79adff744ea488e 100644
|
||||
--- a/src/tests/compiler_tests/RecordConstantPrecision_test.cpp
|
||||
+++ b/src/tests/compiler_tests/RecordConstantPrecision_test.cpp
|
||||
@@ -141,11 +141,11 @@ TEST_F(RecordConstantPrecisionTest, HigherPrecisionConstantInIndex)
|
||||
uniform mediump float u;
|
||||
void main()
|
||||
{
|
||||
- const highp int a = 33000;
|
||||
- mediump float b[34000];
|
||||
+ const highp int a = 330;
|
||||
+ mediump float b[340];
|
||||
gl_FragColor = vec4(b[a]);
|
||||
})";
|
||||
compile(shaderString);
|
||||
ASSERT_FALSE(foundInCode("const highp int s"));
|
||||
- ASSERT_TRUE(foundInCode("b[33000]"));
|
||||
+ ASSERT_TRUE(foundInCode("b[330]"));
|
||||
}
|
||||
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
|
||||
index d7eb48eacfe58fc128fc2d24088ac18ea5196c05..f4b7ce6222ff4a29cb20b75bc102e2c8ae478189 100644
|
||||
--- a/src/tests/gl_tests/GLSLTest.cpp
|
||||
+++ b/src/tests/gl_tests/GLSLTest.cpp
|
||||
@@ -18195,6 +18195,138 @@ void main() {
|
||||
EXPECT_EQ(0u, shader);
|
||||
}
|
||||
|
||||
+// Test that passing large arrays to functions are compiled correctly. Regression test for the
|
||||
+// SPIR-V generator that made a copy of the array to pass to the function, by decomposing and
|
||||
+// reconstructing it (in the absence of OpCopyLogical), but the reconstruction instruction has a
|
||||
+// length higher than can fit in SPIR-V.
|
||||
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockArrayPassedToFunction)
|
||||
+{
|
||||
+ constexpr char kFS[] = R"(#version 300 es
|
||||
+precision highp float;
|
||||
+uniform Large { float a[65536]; };
|
||||
+float f(float b[65536])
|
||||
+{
|
||||
+ b[0] = 1.0;
|
||||
+ return b[0] + b[1];
|
||||
+}
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ color = vec4(f(a), 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
|
||||
+ EXPECT_EQ(0u, shader);
|
||||
+}
|
||||
+
|
||||
+// Make sure the shader in LargeInterfaceBlockArrayPassedToFunction works if the large local is
|
||||
+// avoided.
|
||||
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockArray)
|
||||
+{
|
||||
+ int maxUniformBlockSize = 0;
|
||||
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize);
|
||||
+ ANGLE_SKIP_TEST_IF(maxUniformBlockSize < 16384 * 4);
|
||||
+
|
||||
+ constexpr char kFS[] = R"(#version 300 es
|
||||
+precision highp float;
|
||||
+uniform Large { float a[16384]; };
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ color = vec4(a[0], 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
|
||||
+}
|
||||
+
|
||||
+// Similar to LargeInterfaceBlockArrayPassedToFunction, but the array is nested in a struct.
|
||||
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockNestedArrayPassedToFunction)
|
||||
+{
|
||||
+ constexpr char kFS[] = R"(#version 300 es
|
||||
+precision highp float;
|
||||
+struct S { float a[65536]; };
|
||||
+uniform Large { S s; };
|
||||
+float f(float b[65536])
|
||||
+{
|
||||
+ b[0] = 1.0;
|
||||
+ return b[0] + b[1];
|
||||
+}
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ color = vec4(f(s.a), 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
|
||||
+ EXPECT_EQ(0u, shader);
|
||||
+}
|
||||
+
|
||||
+// Make sure the shader in LargeInterfaceBlockNestedArrayPassedToFunction works if the large local
|
||||
+// is avoided.
|
||||
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockNestedArray)
|
||||
+{
|
||||
+ int maxUniformBlockSize = 0;
|
||||
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize);
|
||||
+ ANGLE_SKIP_TEST_IF(maxUniformBlockSize < 16384 * 4);
|
||||
+
|
||||
+ constexpr char kFS[] = R"(#version 300 es
|
||||
+precision highp float;
|
||||
+struct S { float a[16384]; };
|
||||
+uniform Large { S s; };
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ color = vec4(s.a[0], 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
|
||||
+}
|
||||
+
|
||||
+// Similar to LargeInterfaceBlockArrayPassedToFunction, but the large array is copied to a local
|
||||
+// variable instead.
|
||||
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockArrayCopiedToLocal)
|
||||
+{
|
||||
+ constexpr char kFS[] = R"(#version 300 es
|
||||
+precision highp float;
|
||||
+uniform Large { float a[65536]; };
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ float b[65536] = a;
|
||||
+ color = vec4(b[0], 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
|
||||
+ EXPECT_EQ(0u, shader);
|
||||
+}
|
||||
+
|
||||
+// Similar to LargeInterfaceBlockArrayCopiedToLocal, but the array is nested in a struct
|
||||
+TEST_P(GLSLTest_ES3, LargeInterfaceBlockNestedArrayCopiedToLocal)
|
||||
+{
|
||||
+ constexpr char kFS[] = R"(#version 300 es
|
||||
+precision highp float;
|
||||
+struct S { float a[65536]; };
|
||||
+uniform Large { S s; };
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ S s2 = s;
|
||||
+ color = vec4(s2.a[0], 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
|
||||
+ EXPECT_EQ(0u, shader);
|
||||
+}
|
||||
+
|
||||
+// Test that too large varyings are rejected.
|
||||
+TEST_P(GLSLTest_ES3, LargeArrayVarying)
|
||||
+{
|
||||
+ constexpr char kFS[] = R"(#version 300 es
|
||||
+precision highp float;
|
||||
+in float a[65536];
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ color = vec4(a[0], 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFS);
|
||||
+ EXPECT_EQ(0u, shader);
|
||||
+}
|
||||
+
|
||||
} // anonymous namespace
|
||||
|
||||
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(GLSLTest);
|
||||
@@ -0,0 +1,180 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Thu, 30 Nov 2023 13:53:00 -0500
|
||||
Subject: M120: Translator: Optimize field-name-collision check
|
||||
|
||||
As each field of the struct was encountered, its name was linearly
|
||||
checked against previously added fields. That's O(n^2).
|
||||
|
||||
The name collision check is now moved to when the struct is completely
|
||||
defined, and is done with an unordered_map.
|
||||
|
||||
Bug: chromium:1505009
|
||||
Change-Id: I3fbc23493e5a03e61b631af615cffaf9995fd566
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5143826
|
||||
Reviewed-by: Cody Northrop <cnorthrop@google.com>
|
||||
|
||||
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
|
||||
index 28ac378cab6cb3812a43b6064733d7354ee694bc..7c90ea4f1d23a8af0cab1d44124eea021a27a16d 100644
|
||||
--- a/src/compiler/translator/ParseContext.cpp
|
||||
+++ b/src/compiler/translator/ParseContext.cpp
|
||||
@@ -4726,6 +4726,9 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
|
||||
const TVector<unsigned int> *arraySizes,
|
||||
const TSourceLoc &arraySizesLine)
|
||||
{
|
||||
+ // Ensure there are no duplicate field names
|
||||
+ checkDoesNotHaveDuplicateFieldNames(fieldList, nameLine);
|
||||
+
|
||||
const bool isGLPerVertex = blockName == "gl_PerVertex";
|
||||
// gl_PerVertex is allowed to be redefined and therefore not reserved
|
||||
if (!isGLPerVertex)
|
||||
@@ -6269,28 +6272,25 @@ TDeclarator *TParseContext::parseStructArrayDeclarator(const ImmutableString &id
|
||||
return new TDeclarator(identifier, arraySizes, loc);
|
||||
}
|
||||
|
||||
-void TParseContext::checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
|
||||
- const TFieldList::const_iterator end,
|
||||
- const ImmutableString &name,
|
||||
- const TSourceLoc &location)
|
||||
+void TParseContext::checkDoesNotHaveDuplicateFieldNames(const TFieldList *fields,
|
||||
+ const TSourceLoc &location)
|
||||
{
|
||||
- for (auto fieldIter = begin; fieldIter != end; ++fieldIter)
|
||||
+ TUnorderedMap<ImmutableString, uint32_t, ImmutableString::FowlerNollVoHash<sizeof(size_t)>>
|
||||
+ fieldNames;
|
||||
+ for (TField *field : *fields)
|
||||
{
|
||||
- if ((*fieldIter)->name() == name)
|
||||
+ // Note: operator[] adds this name to the map if it doesn't already exist, and initializes
|
||||
+ // its value to 0.
|
||||
+ uint32_t count = ++fieldNames[field->name()];
|
||||
+ if (count != 1)
|
||||
{
|
||||
- error(location, "duplicate field name in structure", name);
|
||||
+ error(location, "Duplicate field name in structure", field->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TFieldList *TParseContext::addStructFieldList(TFieldList *fields, const TSourceLoc &location)
|
||||
{
|
||||
- for (TFieldList::const_iterator fieldIter = fields->begin(); fieldIter != fields->end();
|
||||
- ++fieldIter)
|
||||
- {
|
||||
- checkDoesNotHaveDuplicateFieldName(fields->begin(), fieldIter, (*fieldIter)->name(),
|
||||
- location);
|
||||
- }
|
||||
return fields;
|
||||
}
|
||||
|
||||
@@ -6298,12 +6298,8 @@ TFieldList *TParseContext::combineStructFieldLists(TFieldList *processedFields,
|
||||
const TFieldList *newlyAddedFields,
|
||||
const TSourceLoc &location)
|
||||
{
|
||||
- for (TField *field : *newlyAddedFields)
|
||||
- {
|
||||
- checkDoesNotHaveDuplicateFieldName(processedFields->begin(), processedFields->end(),
|
||||
- field->name(), location);
|
||||
- processedFields->push_back(field);
|
||||
- }
|
||||
+ processedFields->insert(processedFields->end(), newlyAddedFields->begin(),
|
||||
+ newlyAddedFields->end());
|
||||
return processedFields;
|
||||
}
|
||||
|
||||
@@ -6396,7 +6392,10 @@ TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
|
||||
}
|
||||
}
|
||||
|
||||
- // ensure we do not specify any storage qualifiers on the struct members
|
||||
+ // Ensure there are no duplicate field names
|
||||
+ checkDoesNotHaveDuplicateFieldNames(fieldList, structLine);
|
||||
+
|
||||
+ // Ensure we do not specify any storage qualifiers on the struct members
|
||||
for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
|
||||
{
|
||||
TField &field = *(*fieldList)[typeListIndex];
|
||||
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
|
||||
index 9e1354ef816705fb512b40b329794e0282129807..b63dbbadd146d1a004513823de72c89240a31929 100644
|
||||
--- a/src/compiler/translator/ParseContext.h
|
||||
+++ b/src/compiler/translator/ParseContext.h
|
||||
@@ -354,10 +354,7 @@ class TParseContext : angle::NonCopyable
|
||||
const TSourceLoc &loc,
|
||||
const TVector<unsigned int> *arraySizes);
|
||||
|
||||
- void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
|
||||
- const TFieldList::const_iterator end,
|
||||
- const ImmutableString &name,
|
||||
- const TSourceLoc &location);
|
||||
+ void checkDoesNotHaveDuplicateFieldNames(const TFieldList *fields, const TSourceLoc &location);
|
||||
TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
|
||||
TFieldList *combineStructFieldLists(TFieldList *processedFields,
|
||||
const TFieldList *newlyAddedFields,
|
||||
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
|
||||
index 04b1a80e4ccabf0043617d90a1a06cff25deab98..91233461298150dff48e4d044eb8535e1bcfb7b6 100644
|
||||
--- a/src/tests/angle_end2end_tests_expectations.txt
|
||||
+++ b/src/tests/angle_end2end_tests_expectations.txt
|
||||
@@ -1054,6 +1054,8 @@ b/273271471 WIN INTEL VULKAN : ShaderAlgorithmTest.rgb_to_hsl_vertex_shader/* =
|
||||
7389 SWIFTSHADER : Texture2DTest.ManySupersedingTextureUpdates/* = SKIP
|
||||
7389 MAC OPENGL : Texture2DTest.ManySupersedingTextureUpdates/* = SKIP
|
||||
|
||||
+8437 MAC OPENGL : GLSLTest_ES3.LotsOfFieldsInStruct/* = SKIP
|
||||
+
|
||||
// GL, GLES run into issues with cleanup
|
||||
7495 WIN OpenGL : EGLMultiContextTest.ReuseUnterminatedDisplay/* = SKIP
|
||||
7495 WIN GLES : EGLMultiContextTest.ReuseUnterminatedDisplay/* = SKIP
|
||||
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
|
||||
index 6443d47740d7f625fde2ebca2ef4a34d512d0883..0fa89f59a38165b8d526a99bae60c7b752dec15d 100644
|
||||
--- a/src/tests/gl_tests/GLSLTest.cpp
|
||||
+++ b/src/tests/gl_tests/GLSLTest.cpp
|
||||
@@ -18124,6 +18124,50 @@ void main()
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
}
|
||||
|
||||
+// Test that Metal compiler doesn't inline non-const globals
|
||||
+TEST_P(WebGLGLSLTest, InvalidGlobalsNotInlined)
|
||||
+{
|
||||
+ constexpr char kFS[] = R"(#version 100
|
||||
+ precision highp float;
|
||||
+ float v1 = 0.5;
|
||||
+ float v2 = v1;
|
||||
+
|
||||
+ float f1() {
|
||||
+ return v2;
|
||||
+ }
|
||||
+
|
||||
+ void main() {
|
||||
+ gl_FragColor = vec4(v1 + f1(),0.0,0.0, 1.0);
|
||||
+ })";
|
||||
+ ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFS);
|
||||
+ ASSERT_GL_NO_ERROR();
|
||||
+}
|
||||
+
|
||||
+// Test that a struct can have lots of fields. Regression test for an inefficient O(n^2) check for
|
||||
+// fields having unique names.
|
||||
+TEST_P(GLSLTest_ES3, LotsOfFieldsInStruct)
|
||||
+{
|
||||
+ std::ostringstream fs;
|
||||
+ fs << R"(#version 300 es
|
||||
+precision highp float;
|
||||
+struct LotsOfFields
|
||||
+{
|
||||
+)";
|
||||
+ // Note: 16383 is the SPIR-V limit for struct member count.
|
||||
+ for (uint32_t i = 0; i < 16383; ++i)
|
||||
+ {
|
||||
+ fs << " float field" << i << ";\n";
|
||||
+ }
|
||||
+ fs << R"(};
|
||||
+uniform B { LotsOfFields s; };
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ color = vec4(s.field0, 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), fs.str().c_str());
|
||||
+}
|
||||
+
|
||||
} // anonymous namespace
|
||||
|
||||
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(GLSLTest);
|
||||
@@ -0,0 +1,135 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Tue, 5 Dec 2023 13:36:53 -0500
|
||||
Subject: M120: Vulkan: Don't crash when glCopyTexImage2D redefines itself
|
||||
|
||||
The Vulkan backend marks a level being redefined as such before doing
|
||||
the copy. If a single-level texture was being redefined, it releases it
|
||||
so it can be immediately reallocated. If the source of the copy is the
|
||||
same texture, this causes a crash.
|
||||
|
||||
This can be properly supported by using a temp image to do the copy, but
|
||||
that is not implemented in this change.
|
||||
|
||||
Bug: chromium:1501798
|
||||
Change-Id: I3a902b1e9eec41afd385d9c75a8c95dc986070a8
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5143829
|
||||
Reviewed-by: Cody Northrop <cnorthrop@google.com>
|
||||
|
||||
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||||
index 54d1184518e1cc6e83157b901a37e4ce1e9b58a5..98f66a1d4b02f78dcb3bdae673d21f4bd087fea7 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||||
@@ -879,8 +879,28 @@ angle::Result TextureVk::copyImage(const gl::Context *context,
|
||||
gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
|
||||
const vk::Format &vkFormat = renderer->getFormat(internalFormatInfo.sizedInternalFormat);
|
||||
|
||||
+ // The texture level being redefined might be the same as the one bound to the framebuffer.
|
||||
+ // This _could_ be supported by using a temp image before redefining the level (and potentially
|
||||
+ // discarding the image). However, this is currently unimplemented.
|
||||
+ FramebufferVk *framebufferVk = vk::GetImpl(source);
|
||||
+ RenderTargetVk *colorReadRT = framebufferVk->getColorReadRenderTarget();
|
||||
+ vk::ImageHelper *srcImage = &colorReadRT->getImageForCopy();
|
||||
+ const bool isCubeMap = index.getType() == gl::TextureType::CubeMap;
|
||||
+ gl::LevelIndex levelIndex(getNativeImageIndex(index).getLevelIndex());
|
||||
+ const uint32_t layerIndex = index.hasLayer() ? index.getLayerIndex() : 0;
|
||||
+ const uint32_t redefinedFace = isCubeMap ? layerIndex : 0;
|
||||
+ const uint32_t sourceFace = isCubeMap ? colorReadRT->getLayerIndex() : 0;
|
||||
+ const bool isSelfCopy = mImage == srcImage && levelIndex == colorReadRT->getLevelIndex() &&
|
||||
+ redefinedFace == sourceFace;
|
||||
+
|
||||
ANGLE_TRY(redefineLevel(context, index, vkFormat, newImageSize));
|
||||
|
||||
+ if (isSelfCopy)
|
||||
+ {
|
||||
+ UNIMPLEMENTED();
|
||||
+ return angle::Result::Continue;
|
||||
+ }
|
||||
+
|
||||
return copySubImageImpl(context, index, gl::Offset(0, 0, 0), sourceArea, internalFormatInfo,
|
||||
source);
|
||||
}
|
||||
@@ -1949,7 +1969,8 @@ angle::Result TextureVk::redefineLevel(const gl::Context *context,
|
||||
mImage->getLevelCount() == 1 && mImage->getFirstAllocatedLevel() == levelIndexGL;
|
||||
|
||||
// If incompatible, and redefining the single-level image, release it so it can be
|
||||
- // recreated immediately. This is an optimization to avoid an extra copy.
|
||||
+ // recreated immediately. This is needed so that the texture can be reallocated with
|
||||
+ // the correct format/size.
|
||||
if (!isCompatibleRedefinition && isUpdateToSingleLevelImage)
|
||||
{
|
||||
releaseImage(contextVk);
|
||||
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
|
||||
index f1343f8e8ad65b6fa292c630214c66aaf3ff5a64..e60ea8f9970d14a551128528d18e7be3bc08efcc 100644
|
||||
--- a/src/tests/angle_end2end_tests_expectations.txt
|
||||
+++ b/src/tests/angle_end2end_tests_expectations.txt
|
||||
@@ -29,6 +29,8 @@
|
||||
6989 GLES : BlitFramebufferTestES31.OOBResolve/* = SKIP
|
||||
7881 VULKAN : MultithreadingTestES3.UnsynchronizedTextureReads/* = SKIP
|
||||
7881 VULKAN : MultithreadingTestES3.UnsynchronizedTextureReads2/* = SKIP
|
||||
+// Incorrectly handled pretty much in all backends
|
||||
+8446 : CopyTexImageTestES3.RedefineSameLevel/* = SKIP
|
||||
|
||||
6743 OPENGL : SimpleStateChangeTestES3.RespecifyBufferAfterBeginTransformFeedback/* = SKIP
|
||||
6743 GLES : SimpleStateChangeTestES3.RespecifyBufferAfterBeginTransformFeedback/* = SKIP
|
||||
diff --git a/src/tests/gl_tests/CopyTexImageTest.cpp b/src/tests/gl_tests/CopyTexImageTest.cpp
|
||||
index 3d0cf40ab244a5463c2e4b3d53470d6f932e357b..d6949280ed301fc918e397dad26b9efec1c32f23 100644
|
||||
--- a/src/tests/gl_tests/CopyTexImageTest.cpp
|
||||
+++ b/src/tests/gl_tests/CopyTexImageTest.cpp
|
||||
@@ -1262,6 +1262,56 @@ TEST_P(CopyTexImageTestES3, 3DSubImageDrawMismatchedTextureTypes)
|
||||
glBindTexture(GL_TEXTURE_3D, 0);
|
||||
}
|
||||
|
||||
+// Make sure a single-level texture can be redefined through glCopyTexImage2D from a framebuffer
|
||||
+// bound to the same texture. Regression test for a bug in the Vulkan backend where the texture was
|
||||
+// released before the copy.
|
||||
+TEST_P(CopyTexImageTestES3, RedefineSameLevel)
|
||||
+{
|
||||
+ constexpr GLsizei kSize = 32;
|
||||
+ constexpr GLsizei kHalfSize = kSize / 2;
|
||||
+
|
||||
+ // Create a single-level texture with four colors in different regions.
|
||||
+ std::vector<GLColor> initData(kSize * kSize);
|
||||
+ for (GLsizei y = 0; y < kSize; ++y)
|
||||
+ {
|
||||
+ const bool isTop = y < kHalfSize;
|
||||
+ for (GLsizei x = 0; x < kSize; ++x)
|
||||
+ {
|
||||
+ const bool isLeft = x < kHalfSize;
|
||||
+
|
||||
+ GLColor color = isLeft && isTop ? GLColor::red
|
||||
+ : isLeft && !isTop ? GLColor::green
|
||||
+ : !isLeft && isTop ? GLColor::blue
|
||||
+ : GLColor::yellow;
|
||||
+ color.A = 123;
|
||||
+ initData[y * kSize + x] = color;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ GLTexture tex;
|
||||
+ glBindTexture(GL_TEXTURE_2D, tex);
|
||||
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
+ initData.data());
|
||||
+
|
||||
+ // Bind the framebuffer to the same texture
|
||||
+ GLFramebuffer framebuffer;
|
||||
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
|
||||
+
|
||||
+ // Redefine the texture
|
||||
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kHalfSize / 2, kHalfSize / 2, kHalfSize, kHalfSize,
|
||||
+ 0);
|
||||
+
|
||||
+ // Verify copy is done correctly.
|
||||
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
|
||||
+
|
||||
+ EXPECT_PIXEL_RECT_EQ(0, 0, kHalfSize / 2, kHalfSize / 2, GLColor::red);
|
||||
+ EXPECT_PIXEL_RECT_EQ(kHalfSize / 2, 0, kHalfSize / 2, kHalfSize / 2, GLColor::blue);
|
||||
+ EXPECT_PIXEL_RECT_EQ(0, kHalfSize / 2, kHalfSize / 2, kHalfSize / 2, GLColor::green);
|
||||
+ EXPECT_PIXEL_RECT_EQ(kHalfSize / 2, kHalfSize / 2, kHalfSize / 2, kHalfSize / 2,
|
||||
+ GLColor::yellow);
|
||||
+}
|
||||
+
|
||||
ANGLE_INSTANTIATE_TEST(CopyTexImageTest,
|
||||
ANGLE_ALL_TEST_PLATFORMS_ES2,
|
||||
ES2_D3D11_PRESENT_PATH_FAST(),
|
||||
@@ -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 9965bb1084ea237a18f72a1549916c0a6140806e..8e1708c82cd97acee56aae131c7d629c05a9d6a9 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
|
||||
@@ -2596,8 +2596,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 b26821200e472bec3d522d7b3e7f7aa0cb0d27a5..c37868cd4067aced75f2edb7397d72457a6fabb3 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)
|
||||
{
|
||||
@@ -4544,6 +4599,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,
|
||||
@@ -135,3 +135,32 @@ revert_same_party_cookie_attribute_removal.patch
|
||||
crash_gpu_process_and_clear_shader_cache_when_skia_reports.patch
|
||||
scale_rects_properly_in_syncgetfirstrectforrange.patch
|
||||
fix_restore_original_resize_performance_on_macos.patch
|
||||
feat_allow_code_cache_in_custom_schemes.patch
|
||||
fix_font_flooding_in_dev_tools.patch
|
||||
cherry-pick-5fde415e06f9.patch
|
||||
cherry-pick-8d607d3921b8.patch
|
||||
cherry-pick-998e947b265f.patch
|
||||
cherry-pick-021598ea43c1.patch
|
||||
cherry-pick-76340163a820.patch
|
||||
cherry-pick-f15cfb9371c4.patch
|
||||
cherry-pick-4ca62c7a8b88.patch
|
||||
cherry-pick-5b2fddadaa12.patch
|
||||
cherry-pick-50a1bddfca85.patch
|
||||
reland_mojom_ts_generator_handle_empty_module_path_identically_to.patch
|
||||
cherry-pick-c1cda70a433a.patch
|
||||
cherry-pick-cc07a95bc309.patch
|
||||
safely_crash_on_dangling_profile.patch
|
||||
cherry-pick-91a02d67a83d.patch
|
||||
cherry-pick-8755f76bec32.patch
|
||||
cherry-pick-1f8bec968902.patch
|
||||
cherry-pick-4a98f9e304be.patch
|
||||
fix_racy_iterator_use_in_node_addconnection.patch
|
||||
fix_a_crash_when_a_bmp_image_contains_an_unnecessary_eof_code.patch
|
||||
m120_ipcz_fix_a_few_weak_asserts.patch
|
||||
prevent_mojotrap_event_re-ordering.patch
|
||||
m122_cherry_pick_cve-2024-25062_libxml_fix.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
|
||||
cherry-pick-1b1f34234346.patch
|
||||
|
||||
69
patches/chromium/cherry-pick-021598ea43c1.patch
Normal file
69
patches/chromium/cherry-pick-021598ea43c1.patch
Normal file
@@ -0,0 +1,69 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Guido Urdaneta <guidou@chromium.org>
|
||||
Date: Mon, 4 Dec 2023 23:00:41 +0000
|
||||
Subject: Drop frames received on the wrong task runner
|
||||
|
||||
It can happen during transfer that a frame is posted from the
|
||||
background media thread to the task runner of the old execution
|
||||
context, which can lead to races and UAF.
|
||||
|
||||
This CL makes underlying sources drop frames received on the
|
||||
wrong task runner to avoid the problem.
|
||||
|
||||
(cherry picked from commit 9d042e0d498356185fe9eb33c53b69fab33d06bf)
|
||||
|
||||
Bug: 1505708
|
||||
Change-Id: I686228d88cb1c48bdf8c0b6bf85edd280a54300a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5077845
|
||||
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
|
||||
Reviewed-by: Tony Herre <toprice@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1231802}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5082444
|
||||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Auto-Submit: Guido Urdaneta <guidou@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1370}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc
|
||||
index b5a2f71bae81bba6e61d8f303d24a9df874ae885..4c7b0b982e3d314749e39178eb0fca706d11bd85 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc
|
||||
@@ -58,7 +58,15 @@ void RTCEncodedAudioUnderlyingSource::Trace(Visitor* visitor) const {
|
||||
|
||||
void RTCEncodedAudioUnderlyingSource::OnFrameFromSource(
|
||||
std::unique_ptr<webrtc::TransformableAudioFrameInterface> webrtc_frame) {
|
||||
- DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
+ // It can happen that a frame is posted to the task runner of the old
|
||||
+ // execution context during a stream transfer to a new context.
|
||||
+ // TODO(https://crbug.com/1506631): Make the state updates related to the
|
||||
+ // transfer atomic and turn this into a DCHECK.
|
||||
+ if (!task_runner_->BelongsToCurrentThread()) {
|
||||
+ DVLOG(1) << "Dropped frame posted to incorrect task runner. This can "
|
||||
+ "happen during transfer.";
|
||||
+ return;
|
||||
+ }
|
||||
// If the source is canceled or there are too many queued frames,
|
||||
// drop the new frame.
|
||||
if (!disconnect_callback_ || !GetExecutionContext()) {
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc
|
||||
index 54ca7d1529b1772200c3691b56e847acc42d086d..8fb1d8460e289cd5e6764271f79dada7f121cb1b 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc
|
||||
@@ -58,7 +58,15 @@ void RTCEncodedVideoUnderlyingSource::Trace(Visitor* visitor) const {
|
||||
|
||||
void RTCEncodedVideoUnderlyingSource::OnFrameFromSource(
|
||||
std::unique_ptr<webrtc::TransformableVideoFrameInterface> webrtc_frame) {
|
||||
- DCHECK(task_runner_->BelongsToCurrentThread());
|
||||
+ // It can happen that a frame is posted to the task runner of the old
|
||||
+ // execution context during a stream transfer to a new context.
|
||||
+ // TODO(https://crbug.com/1506631): Make the state updates related to the
|
||||
+ // transfer atomic and turn this into a DCHECK.
|
||||
+ if (!task_runner_->BelongsToCurrentThread()) {
|
||||
+ DVLOG(1) << "Dropped frame posted to incorrect task runner. This can "
|
||||
+ "happen during transfer.";
|
||||
+ return;
|
||||
+ }
|
||||
// If the source is canceled or there are too many queued frames,
|
||||
// drop the new frame.
|
||||
if (!disconnect_callback_ || !GetExecutionContext()) {
|
||||
42
patches/chromium/cherry-pick-1b1f34234346.patch
Normal file
42
patches/chromium/cherry-pick-1b1f34234346.patch
Normal file
@@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kylechar <kylechar@chromium.org>
|
||||
Date: Tue, 9 Apr 2024 17:14:26 +0000
|
||||
Subject: Validate buffer length
|
||||
|
||||
The BitmapInSharedMemory mojo traits were only validating row length and
|
||||
not total buffer length.
|
||||
|
||||
(cherry picked from commit 1a19ff70bd54847d818566bd7a1e7c384c419746)
|
||||
|
||||
(cherry picked from commit f15315f1cb7897e208947a40d538aac693283d7f)
|
||||
|
||||
Bug: 331237485
|
||||
Change-Id: Ia2318899c44e9e7ac72fc7183954e6ce2c702179
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5396796
|
||||
Commit-Queue: Kyle Charbonneau <kylechar@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/main@{#1278417}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5420432
|
||||
Commit-Queue: danakj <danakj@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/6312@{#786}
|
||||
Cr-Original-Branched-From: 6711dcdae48edaf98cbc6964f90fac85b7d9986e-refs/heads/main@{#1262506}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5433678
|
||||
Reviewed-by: danakj <danakj@chromium.org>
|
||||
Reviewed-by: Kyle Charbonneau <kylechar@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#2003}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/services/viz/public/cpp/compositing/bitmap_in_shared_memory_mojom_traits.cc b/services/viz/public/cpp/compositing/bitmap_in_shared_memory_mojom_traits.cc
|
||||
index a6e5f45d9e72b9ac48e536c3a7756966b3c263cf..519d554055e5182cdcbae44fafdac339a64a923b 100644
|
||||
--- a/services/viz/public/cpp/compositing/bitmap_in_shared_memory_mojom_traits.cc
|
||||
+++ b/services/viz/public/cpp/compositing/bitmap_in_shared_memory_mojom_traits.cc
|
||||
@@ -76,6 +76,10 @@ bool StructTraits<viz::mojom::BitmapInSharedMemoryDataView, SkBitmap>::Read(
|
||||
if (!mapping_ptr->IsValid())
|
||||
return false;
|
||||
|
||||
+ if (mapping_ptr->size() < image_info.computeByteSize(data.row_bytes())) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
if (!sk_bitmap->installPixels(image_info, mapping_ptr->memory(),
|
||||
data.row_bytes(), &DeleteSharedMemoryMapping,
|
||||
mapping_ptr.get())) {
|
||||
125
patches/chromium/cherry-pick-1f8bec968902.patch
Normal file
125
patches/chromium/cherry-pick-1f8bec968902.patch
Normal file
@@ -0,0 +1,125 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tsuyoshi Horo <horo@chromium.org>
|
||||
Date: Wed, 24 Jan 2024 02:04:24 +0000
|
||||
Subject: Fix UAF in SourceStreamToDataPipe
|
||||
|
||||
SourceStreamToDataPipe::ReadMore() is passing a callback with
|
||||
Unretained(this) to net::SourceStream::Read(). But this callback may be
|
||||
called even after the SourceStream is destructed. This is causing UAF
|
||||
issue (crbug.com/1511085).
|
||||
|
||||
To solve this problem, this CL changes ReadMore() method to pass a
|
||||
callback with a weak ptr of this.
|
||||
|
||||
(cherry picked from commit 6e36a69da1b73f9aea9c54bfbe6c5b9cb2c672a5)
|
||||
|
||||
Bug: 1511085
|
||||
Change-Id: Idd4e34ff300ff5db2de1de7b303841c7db3a964a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5179746
|
||||
Reviewed-by: Adam Rice <ricea@chromium.org>
|
||||
Commit-Queue: Tsuyoshi Horo <horo@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1244526}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5231558
|
||||
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1860}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/services/network/public/cpp/source_stream_to_data_pipe.cc b/services/network/public/cpp/source_stream_to_data_pipe.cc
|
||||
index bfd85b1a00b216b52ae816ca29cb66ddabe20b6d..07afd58a40f92485ded07c535092a891c5140c7b 100644
|
||||
--- a/services/network/public/cpp/source_stream_to_data_pipe.cc
|
||||
+++ b/services/network/public/cpp/source_stream_to_data_pipe.cc
|
||||
@@ -55,9 +55,9 @@ void SourceStreamToDataPipe::ReadMore() {
|
||||
|
||||
scoped_refptr<net::IOBuffer> buffer(
|
||||
new network::NetToMojoIOBuffer(pending_write_.get()));
|
||||
- int result = source_->Read(
|
||||
- buffer.get(), base::checked_cast<int>(num_bytes),
|
||||
- base::BindOnce(&SourceStreamToDataPipe::DidRead, base::Unretained(this)));
|
||||
+ int result = source_->Read(buffer.get(), base::checked_cast<int>(num_bytes),
|
||||
+ base::BindOnce(&SourceStreamToDataPipe::DidRead,
|
||||
+ weak_factory_.GetWeakPtr()));
|
||||
|
||||
if (result != net::ERR_IO_PENDING)
|
||||
DidRead(result);
|
||||
diff --git a/services/network/public/cpp/source_stream_to_data_pipe_unittest.cc b/services/network/public/cpp/source_stream_to_data_pipe_unittest.cc
|
||||
index 7061418c5141d936f04b1193c98e66efc5e72ac5..54159df39afa7cf6e2faa51da185dc034b923209 100644
|
||||
--- a/services/network/public/cpp/source_stream_to_data_pipe_unittest.cc
|
||||
+++ b/services/network/public/cpp/source_stream_to_data_pipe_unittest.cc
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
+#include "base/test/bind.h"
|
||||
#include "base/test/task_environment.h"
|
||||
+#include "net/base/net_errors.h"
|
||||
#include "net/filter/mock_source_stream.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
@@ -42,6 +44,33 @@ struct SourceStreamToDataPipeTestParam {
|
||||
const ReadResultType read_result_type;
|
||||
};
|
||||
|
||||
+class DummyPendingSourceStream : public net::SourceStream {
|
||||
+ public:
|
||||
+ DummyPendingSourceStream() : net::SourceStream(SourceStream::TYPE_NONE) {}
|
||||
+ ~DummyPendingSourceStream() override = default;
|
||||
+
|
||||
+ DummyPendingSourceStream(const DummyPendingSourceStream&) = delete;
|
||||
+ DummyPendingSourceStream& operator=(const DummyPendingSourceStream&) = delete;
|
||||
+
|
||||
+ // SourceStream implementation
|
||||
+ int Read(net::IOBuffer* dest_buffer,
|
||||
+ int buffer_size,
|
||||
+ net::CompletionOnceCallback callback) override {
|
||||
+ callback_ = std::move(callback);
|
||||
+ return net::ERR_IO_PENDING;
|
||||
+ }
|
||||
+ std::string Description() const override { return ""; }
|
||||
+ bool MayHaveMoreBytes() const override { return true; }
|
||||
+
|
||||
+ net::CompletionOnceCallback TakeCompletionCallback() {
|
||||
+ CHECK(callback_);
|
||||
+ return std::move(callback_);
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ net::CompletionOnceCallback callback_;
|
||||
+};
|
||||
+
|
||||
} // namespace
|
||||
|
||||
class SourceStreamToDataPipeTest
|
||||
@@ -212,4 +241,33 @@ TEST_P(SourceStreamToDataPipeTest, MayHaveMoreBytes) {
|
||||
EXPECT_EQ(ReadPipe(&output), net::OK);
|
||||
EXPECT_EQ(output, message);
|
||||
}
|
||||
+
|
||||
+TEST(SourceStreamToDataPipeCallbackTest, CompletionCallbackAfterDestructed) {
|
||||
+ base::test::TaskEnvironment task_environment;
|
||||
+
|
||||
+ std::unique_ptr<DummyPendingSourceStream> source =
|
||||
+ std::make_unique<DummyPendingSourceStream>();
|
||||
+ DummyPendingSourceStream* source_ptr = source.get();
|
||||
+ const MojoCreateDataPipeOptions data_pipe_options{
|
||||
+ sizeof(MojoCreateDataPipeOptions), MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1, 1};
|
||||
+ mojo::ScopedDataPipeProducerHandle producer_end;
|
||||
+ mojo::ScopedDataPipeConsumerHandle consumer_end;
|
||||
+ CHECK_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(&data_pipe_options,
|
||||
+ producer_end, consumer_end));
|
||||
+
|
||||
+ std::unique_ptr<SourceStreamToDataPipe> adapter =
|
||||
+ std::make_unique<SourceStreamToDataPipe>(std::move(source),
|
||||
+ std::move(producer_end));
|
||||
+ bool callback_called = false;
|
||||
+ adapter->Start(
|
||||
+ base::BindLambdaForTesting([&](int result) { callback_called = true; }));
|
||||
+ net::CompletionOnceCallback callback = source_ptr->TakeCompletionCallback();
|
||||
+ adapter.reset();
|
||||
+
|
||||
+ // Test that calling `callback` after deleting `adapter` must not cause UAF
|
||||
+ // (crbug.com/1511085).
|
||||
+ std::move(callback).Run(net::ERR_FAILED);
|
||||
+ EXPECT_FALSE(callback_called);
|
||||
+}
|
||||
+
|
||||
} // namespace network
|
||||
67
patches/chromium/cherry-pick-4a98f9e304be.patch
Normal file
67
patches/chromium/cherry-pick-4a98f9e304be.patch
Normal file
@@ -0,0 +1,67 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Peter=20Bostr=C3=B6m?= <pbos@chromium.org>
|
||||
Date: Fri, 26 Jan 2024 19:37:57 +0000
|
||||
Subject: Speculatively fix race in mojo ShutDownOnIOThread
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This acquires `write_lock_` before resetting handles used by WriteNoLock
|
||||
(which is called under the same lock in another thread). We also set
|
||||
`reject_writes_` to prevent future write attempts after shutdown. That
|
||||
seems strictly more correct.
|
||||
|
||||
We also acquire `fds_to_close_lock_` before clearing the FDs.
|
||||
|
||||
I was unable to repro locally as content_browsertests just times out
|
||||
in my local setup without reporting anything interesting. This seems
|
||||
strictly more correct though.
|
||||
|
||||
(cherry picked from commit 9755d9d81e4a8cb5b4f76b23b761457479dbb06b)
|
||||
|
||||
Bug: 1519980
|
||||
Change-Id: I96279936ca908ecb98eddd381df20d61597cba43
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5226127
|
||||
Auto-Submit: Peter Boström <pbos@chromium.org>
|
||||
Reviewed-by: Ken Rockot <rockot@google.com>
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Commit-Queue: Peter Boström <pbos@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1250580}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5239564
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1883}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/mojo/core/channel_posix.cc b/mojo/core/channel_posix.cc
|
||||
index 0a3596382d0e9a40c72bfb4ead6f0338a61253d6..eae6b0768463679b5043514dc5745da52b80ae10 100644
|
||||
--- a/mojo/core/channel_posix.cc
|
||||
+++ b/mojo/core/channel_posix.cc
|
||||
@@ -246,16 +246,21 @@ void ChannelPosix::WaitForWriteOnIOThreadNoLock() {
|
||||
void ChannelPosix::ShutDownOnIOThread() {
|
||||
base::CurrentThread::Get()->RemoveDestructionObserver(this);
|
||||
|
||||
- read_watcher_.reset();
|
||||
- write_watcher_.reset();
|
||||
- if (leak_handle_) {
|
||||
- std::ignore = socket_.release();
|
||||
- } else {
|
||||
- socket_.reset();
|
||||
- }
|
||||
+ {
|
||||
+ base::AutoLock lock(write_lock_);
|
||||
+ reject_writes_ = true;
|
||||
+ read_watcher_.reset();
|
||||
+ write_watcher_.reset();
|
||||
+ if (leak_handle_) {
|
||||
+ std::ignore = socket_.release();
|
||||
+ } else {
|
||||
+ socket_.reset();
|
||||
+ }
|
||||
#if BUILDFLAG(IS_IOS)
|
||||
- fds_to_close_.clear();
|
||||
+ base::AutoLock fd_lock(fds_to_close_lock_);
|
||||
+ fds_to_close_.clear();
|
||||
#endif
|
||||
+ }
|
||||
|
||||
// May destroy the |this| if it was the last reference.
|
||||
self_ = nullptr;
|
||||
43
patches/chromium/cherry-pick-4ca62c7a8b88.patch
Normal file
43
patches/chromium/cherry-pick-4ca62c7a8b88.patch
Normal file
@@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Vasiliy Telezhnikov <vasilyt@chromium.org>
|
||||
Date: Thu, 7 Dec 2023 16:56:57 +0000
|
||||
Subject: Check for slugs count before deserializing Slugs in DrawSlugOp
|
||||
|
||||
Count is part of serialized data and while we never serialize values
|
||||
less then 1, it can be any value when coming over IPC, we should check
|
||||
that it's positive before substacting one.
|
||||
|
||||
(cherry picked from commit 0527e0d5b08a13d63f4f1eeefa1b86ecfd0cb63b)
|
||||
|
||||
Bug: 1506726
|
||||
Change-Id: I244f50a682f2e852b22ba88f1e9cddddb0fdfcb9
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5078779
|
||||
Reviewed-by: Peng Huang <penghuang@chromium.org>
|
||||
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1232013}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5096809
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1428}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/cc/paint/paint_op.cc b/cc/paint/paint_op.cc
|
||||
index bd39210efa9a4da6f3888dd25ef465a1d0a4cc70..4c88eaa1e57ddae2c7fb0ba94d66b843ab8f63f2 100644
|
||||
--- a/cc/paint/paint_op.cc
|
||||
+++ b/cc/paint/paint_op.cc
|
||||
@@ -976,10 +976,12 @@ PaintOp* DrawSlugOp::Deserialize(PaintOpReader& reader, void* output) {
|
||||
reader.Read(&op->flags);
|
||||
unsigned int count = 0;
|
||||
reader.Read(&count);
|
||||
- reader.Read(&op->slug);
|
||||
- op->extra_slugs.resize(count - 1);
|
||||
- for (auto& extra_slug : op->extra_slugs) {
|
||||
- reader.Read(&extra_slug);
|
||||
+ if (count > 0) {
|
||||
+ reader.Read(&op->slug);
|
||||
+ op->extra_slugs.resize(count - 1);
|
||||
+ for (auto& extra_slug : op->extra_slugs) {
|
||||
+ reader.Read(&extra_slug);
|
||||
+ }
|
||||
}
|
||||
return op;
|
||||
}
|
||||
117
patches/chromium/cherry-pick-50a1bddfca85.patch
Normal file
117
patches/chromium/cherry-pick-50a1bddfca85.patch
Normal file
@@ -0,0 +1,117 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Austin Eng <enga@chromium.org>
|
||||
Date: Tue, 19 Dec 2023 17:25:51 +0000
|
||||
Subject: Use cross thread handles to bind args for async webgpu context
|
||||
creation
|
||||
|
||||
(cherry picked from commit 542b278a0c1de7202f4bf5e3e5cbdc2dd6c337d4)
|
||||
|
||||
Fixed: 1506923
|
||||
Change-Id: I174703cbd993471e3afb39c0cfa4cce2770755f7
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5113019
|
||||
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
|
||||
Commit-Queue: Austin Eng <enga@chromium.org>
|
||||
Reviewed-by: Stephen White <senorblanco@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1237179}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5133239
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1551}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webgpu/gpu.cc b/third_party/blink/renderer/modules/webgpu/gpu.cc
|
||||
index f2f4e8be0cc73f5b569fd3345bd3b64f4539041d..5752c80fbbfc91d492f497c87f181d3211c71d86 100644
|
||||
--- a/third_party/blink/renderer/modules/webgpu/gpu.cc
|
||||
+++ b/third_party/blink/renderer/modules/webgpu/gpu.cc
|
||||
@@ -39,11 +39,13 @@
|
||||
#include "third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h"
|
||||
#include "third_party/blink/renderer/platform/graphics/gpu/webgpu_callback.h"
|
||||
#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.h"
|
||||
+#include "third_party/blink/renderer/platform/heap/cross_thread_handle.h"
|
||||
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
|
||||
#include "third_party/blink/renderer/platform/heap/thread_state.h"
|
||||
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
|
||||
#include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h"
|
||||
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
|
||||
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
@@ -300,9 +302,19 @@ void GPU::RequestAdapterImpl(ScriptState* script_state,
|
||||
CreateWebGPUGraphicsContext3DProviderAsync(
|
||||
execution_context->Url(),
|
||||
execution_context->GetTaskRunner(TaskType::kWebGPU),
|
||||
- WTF::BindOnce(
|
||||
- [](GPU* gpu, ExecutionContext* execution_context,
|
||||
+ CrossThreadBindOnce(
|
||||
+ [](CrossThreadHandle<GPU> gpu_handle,
|
||||
+ CrossThreadHandle<ExecutionContext> execution_context_handle,
|
||||
std::unique_ptr<WebGraphicsContext3DProvider> context_provider) {
|
||||
+ auto unwrap_gpu = MakeUnwrappingCrossThreadHandle(gpu_handle);
|
||||
+ auto unwrap_execution_context =
|
||||
+ MakeUnwrappingCrossThreadHandle(execution_context_handle);
|
||||
+ if (!unwrap_gpu || !unwrap_execution_context) {
|
||||
+ return;
|
||||
+ }
|
||||
+ auto* gpu = unwrap_gpu.GetOnCreationThread();
|
||||
+ auto* execution_context =
|
||||
+ unwrap_execution_context.GetOnCreationThread();
|
||||
const KURL& url = execution_context->Url();
|
||||
context_provider =
|
||||
CheckContextProvider(url, std::move(context_provider));
|
||||
@@ -324,7 +336,8 @@ void GPU::RequestAdapterImpl(ScriptState* script_state,
|
||||
std::move(callback).Run();
|
||||
}
|
||||
},
|
||||
- WrapPersistent(this), WrapPersistent(execution_context)));
|
||||
+ MakeCrossThreadHandle(this),
|
||||
+ MakeCrossThreadHandle(execution_context)));
|
||||
return;
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.cc b/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.cc
|
||||
index f859f3e62c54d26453a145321f697c5116c13348..3d9890b9b4a58a30a11e501fdb9297f4a57b601b 100644
|
||||
--- a/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.cc
|
||||
+++ b/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.cc
|
||||
@@ -121,8 +121,8 @@ CreateWebGPUGraphicsContext3DProvider(const KURL& url) {
|
||||
void CreateWebGPUGraphicsContext3DProviderAsync(
|
||||
const KURL& url,
|
||||
scoped_refptr<base::SingleThreadTaskRunner> current_thread_task_runner,
|
||||
- base::OnceCallback<void(std::unique_ptr<WebGraphicsContext3DProvider>)>
|
||||
- callback) {
|
||||
+ WTF::CrossThreadOnceFunction<
|
||||
+ void(std::unique_ptr<WebGraphicsContext3DProvider>)> callback) {
|
||||
if (IsMainThread()) {
|
||||
std::move(callback).Run(
|
||||
Platform::Current()->CreateWebGPUGraphicsContext3DProvider(url));
|
||||
@@ -140,8 +140,7 @@ void CreateWebGPUGraphicsContext3DProviderAsync(
|
||||
AccessMainThreadForWebGraphicsContext3DProvider()),
|
||||
FROM_HERE,
|
||||
CrossThreadBindOnce(&CreateWebGPUGraphicsContextOnMainThreadAsync, url,
|
||||
- current_thread_task_runner,
|
||||
- CrossThreadBindOnce(std::move(callback))));
|
||||
+ current_thread_task_runner, std::move(callback)));
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.h b/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.h
|
||||
index 8fcab24bfec2c9b2e9edf9885b66de4f99949b35..8b785cc30acdfffed0f59eb53b073d0cdedc2151 100644
|
||||
--- a/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.h
|
||||
+++ b/third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_util.h
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
|
||||
#include "third_party/blink/renderer/platform/platform_export.h"
|
||||
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
|
||||
+#include "third_party/blink/renderer/platform/wtf/functional.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
@@ -42,8 +43,8 @@ CreateWebGPUGraphicsContext3DProvider(const KURL& url);
|
||||
PLATFORM_EXPORT void CreateWebGPUGraphicsContext3DProviderAsync(
|
||||
const KURL& url,
|
||||
scoped_refptr<base::SingleThreadTaskRunner> current_thread_task_runner,
|
||||
- base::OnceCallback<void(std::unique_ptr<WebGraphicsContext3DProvider>)>
|
||||
- callback);
|
||||
+ WTF::CrossThreadOnceFunction<
|
||||
+ void(std::unique_ptr<WebGraphicsContext3DProvider>)> callback);
|
||||
|
||||
} // namespace blink
|
||||
|
||||
61
patches/chromium/cherry-pick-5b2fddadaa12.patch
Normal file
61
patches/chromium/cherry-pick-5b2fddadaa12.patch
Normal file
@@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hongchan Choi <hongchan@chromium.org>
|
||||
Date: Tue, 12 Dec 2023 02:34:29 +0000
|
||||
Subject: Clamp the input value correctly before scheduling an AudioParam event
|
||||
|
||||
When the AudioParam value is set via the setter, it internally calls
|
||||
the setValueAtTime() function to schedule the change. However, the
|
||||
current code does not correctly clamp the value within the nominal
|
||||
range. This CL fixes the problem.
|
||||
|
||||
(cherry picked from commit c97b506c1e32951dd39e11e453e1ecc29cc0b35c)
|
||||
|
||||
Bug: 1505086
|
||||
Test: Locally confirmed with both negative and positive param values.
|
||||
Change-Id: Ibb0aae168161af9ea95c5e11a929b3aa2c621c73
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5100625
|
||||
Reviewed-by: Michael Wilson <mjwilson@chromium.org>
|
||||
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1235028}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5112838
|
||||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Auto-Submit: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1497}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/audio_param.cc b/third_party/blink/renderer/modules/webaudio/audio_param.cc
|
||||
index 8c7b9d07bb68ec51d21ea2132cc5ecbc39e5cd95..95a40d39c9214fd6555523bd7e7bd91e36d2c6c0 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/audio_param.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/audio_param.cc
|
||||
@@ -120,12 +120,15 @@ void AudioParam::setValue(float value) {
|
||||
void AudioParam::setValue(float value, ExceptionState& exception_state) {
|
||||
WarnIfOutsideRange("value", value);
|
||||
|
||||
- // This is to signal any errors, if necessary, about conflicting
|
||||
- // automations.
|
||||
- setValueAtTime(value, Context()->currentTime(), exception_state);
|
||||
- // This is to change the value so that an immediate query for the
|
||||
- // value returns the expected values.
|
||||
+ // Change the intrinsic value so that an immediate query for the value
|
||||
+ // returns the value that the user code provided. It also clamps the value
|
||||
+ // to the nominal range.
|
||||
Handler().SetValue(value);
|
||||
+
|
||||
+ // Use the intrinsic value (after clamping) to schedule the actual
|
||||
+ // automation event.
|
||||
+ setValueAtTime(Handler().IntrinsicValue(), Context()->currentTime(),
|
||||
+ exception_state);
|
||||
}
|
||||
|
||||
float AudioParam::defaultValue() const {
|
||||
diff --git a/third_party/blink/web_tests/webaudio/AudioParam/worklet-warnings-expected.txt b/third_party/blink/web_tests/webaudio/AudioParam/worklet-warnings-expected.txt
|
||||
index 7bb2d0aec7feaed69424f209a2e3e031c7a9e512..ebe05a2c239d35be4729cc187aa77de6a44f5a41 100644
|
||||
--- a/third_party/blink/web_tests/webaudio/AudioParam/worklet-warnings-expected.txt
|
||||
+++ b/third_party/blink/web_tests/webaudio/AudioParam/worklet-warnings-expected.txt
|
||||
@@ -1,5 +1,4 @@
|
||||
CONSOLE WARNING: AudioWorkletNode("noise-generator").amplitude.value 99 outside nominal range [0, 1]; value will be clamped.
|
||||
-CONSOLE WARNING: AudioWorkletNode("noise-generator").amplitude.setValueAtTime value 99 outside nominal range [0, 1]; value will be clamped.
|
||||
CONSOLE WARNING: AudioWorkletNode("noise-generator").amplitude.setValueAtTime value -1 outside nominal range [0, 1]; value will be clamped.
|
||||
CONSOLE WARNING: AudioWorkletNode("noise-generator").amplitude.linearRampToValueAtTime value 5 outside nominal range [0, 1]; value will be clamped.
|
||||
This is a testharness.js-based test.
|
||||
73
patches/chromium/cherry-pick-5fde415e06f9.patch
Normal file
73
patches/chromium/cherry-pick-5fde415e06f9.patch
Normal file
@@ -0,0 +1,73 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Guido Urdaneta <guidou@chromium.org>
|
||||
Date: Fri, 10 Nov 2023 20:46:57 +0000
|
||||
Subject: Use KeepAlive to prevent lifetime race with audio delivery
|
||||
|
||||
(cherry picked from commit 186dad16ae69183f02730fb26d84e1d53f9f1b04)
|
||||
|
||||
Bug: 1497984
|
||||
Change-Id: Ic22729b2ef9690203bbb09555d32238959e93a0f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5009864
|
||||
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
|
||||
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1221614}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5018212
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#500}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
|
||||
index f68c265271b48f92ff67a752cf2bedac183bd2fc..a53053b12925b6aaa4fb201e7de2c00d4203bb2a 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.cc
|
||||
@@ -142,12 +142,12 @@ bool MediaStreamAudioTrackUnderlyingSource::StartFrameDelivery() {
|
||||
return false;
|
||||
}
|
||||
|
||||
- if (added_to_track_) {
|
||||
+ if (is_connected_to_track_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
WebMediaStreamAudioSink::AddToAudioTrack(this, WebMediaStreamTrack(track_));
|
||||
- added_to_track_ = true;
|
||||
+ is_connected_to_track_ = this;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ void MediaStreamAudioTrackUnderlyingSource::DisconnectFromTrack() {
|
||||
|
||||
WebMediaStreamAudioSink::RemoveFromAudioTrack(this,
|
||||
WebMediaStreamTrack(track_));
|
||||
- added_to_track_ = false;
|
||||
+ is_connected_to_track_.Clear();
|
||||
track_.Clear();
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
|
||||
index 334da29c2b210f92e9ee191275651406487601c3..4e7d22959dc8947c12d9ee2bb7acd814cc4db6b3 100644
|
||||
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
|
||||
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "third_party/blink/renderer/modules/breakout_box/transferred_frame_queue_underlying_source.h"
|
||||
#include "third_party/blink/renderer/modules/modules_export.h"
|
||||
#include "third_party/blink/renderer/platform/heap/prefinalizer.h"
|
||||
+#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
@@ -80,10 +81,13 @@ class MODULES_EXPORT MediaStreamAudioTrackUnderlyingSource
|
||||
const Member<ScriptWrappable> media_stream_track_processor_;
|
||||
|
||||
Member<MediaStreamComponent> track_;
|
||||
- bool added_to_track_ = false;
|
||||
|
||||
std::unique_ptr<AudioBufferPool> buffer_pool_;
|
||||
|
||||
+ // This prevents collection of this object while it is still connected to a
|
||||
+ // platform MediaStreamTrack.
|
||||
+ SelfKeepAlive<MediaStreamAudioTrackUnderlyingSource> is_connected_to_track_;
|
||||
+
|
||||
SEQUENCE_CHECKER(sequence_checker_);
|
||||
};
|
||||
|
||||
37
patches/chromium/cherry-pick-76340163a820.patch
Normal file
37
patches/chromium/cherry-pick-76340163a820.patch
Normal file
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Semel <paulsemel@chromium.org>
|
||||
Date: Wed, 6 Dec 2023 15:52:56 +0000
|
||||
Subject: ImageBitmapFactory: fix empty context dcheck
|
||||
|
||||
Approved by:
|
||||
https://bugs.chromium.org/p/chromium/issues/detail?id=1502102#c34
|
||||
|
||||
(cherry picked from commit c4d2f15b8f97076c8fd0f9aa5814b94db698b75c)
|
||||
|
||||
Fixed: 1502102
|
||||
Change-Id: Ib42d2897d62136ae835561bcf56884b5624060a5
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5071252
|
||||
Commit-Queue: Paul Semel <paulsemel@chromium.org>
|
||||
Reviewed-by: Jean-Philippe Gravel <jpgravel@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1230617}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5088373
|
||||
Auto-Submit: Arthur Sonzogni <arthursonzogni@google.com>
|
||||
Reviewed-by: Paul Semel <paulsemel@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1416}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc
|
||||
index 4693dbc043f27d3799c4df127a1a91905ca1860a..19a9bee39a6aafb528b004b7757a69f47cf10658 100644
|
||||
--- a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc
|
||||
+++ b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc
|
||||
@@ -155,7 +155,9 @@ ScriptPromise ImageBitmapFactories::CreateImageBitmapFromBlob(
|
||||
ImageBitmapSource* bitmap_source,
|
||||
absl::optional<gfx::Rect> crop_rect,
|
||||
const ImageBitmapOptions* options) {
|
||||
- DCHECK(script_state->ContextIsValid());
|
||||
+ if (!script_state->ContextIsValid()) {
|
||||
+ return ScriptPromise();
|
||||
+ }
|
||||
|
||||
// imageOrientation: 'from-image' will be used to replace imageOrientation:
|
||||
// 'none'. Adding a deprecation warning when 'none' is called in
|
||||
110
patches/chromium/cherry-pick-8755f76bec32.patch
Normal file
110
patches/chromium/cherry-pick-8755f76bec32.patch
Normal file
@@ -0,0 +1,110 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Guido Urdaneta <guidou@chromium.org>
|
||||
Date: Thu, 18 Jan 2024 16:47:18 +0000
|
||||
Subject: Exit early from RTCPeerConnectionHandler
|
||||
|
||||
For certain operations that require a live client
|
||||
(i.e., RTCPeerConnection, which is garbage collected),
|
||||
PeerConnectionHandler keeps a pointer to the client on the stack
|
||||
to prevent garbage collection.
|
||||
|
||||
In some cases, the client may have already been garbage collected
|
||||
(the client is null). In that case, there is no point in doing the
|
||||
operation and it should exit early to avoid UAF/crashes.
|
||||
|
||||
This CL adds early exit to the cases that do not already have it.
|
||||
|
||||
Bug: 1514777
|
||||
Change-Id: I27e9541cfaa74d978799c03e2832a0980f9e5710
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5210359
|
||||
Reviewed-by: Tomas Gunnarsson <tommi@chromium.org>
|
||||
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1248826}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
|
||||
index 473eb82685f004d960f3d488e3976a2305eda248..b6d893cc0f93d5bbb12b07734c63b31a52d662f1 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
|
||||
@@ -1056,15 +1056,19 @@ bool RTCPeerConnectionHandler::Initialize(
|
||||
WebLocalFrame* frame,
|
||||
ExceptionState& exception_state) {
|
||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||
- DCHECK(frame);
|
||||
DCHECK(dependency_factory_);
|
||||
- frame_ = frame;
|
||||
|
||||
CHECK(!initialize_called_);
|
||||
initialize_called_ = true;
|
||||
|
||||
// Prevent garbage collection of client_ during processing.
|
||||
auto* client_on_stack = client_.Get();
|
||||
+ if (!client_on_stack) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ DCHECK(frame);
|
||||
+ frame_ = frame;
|
||||
peer_connection_tracker_ = PeerConnectionTracker::From(*frame);
|
||||
|
||||
configuration_ = server_configuration;
|
||||
@@ -2312,10 +2316,13 @@ void RTCPeerConnectionHandler::OnIceCandidate(const String& sdp,
|
||||
int sdp_mline_index,
|
||||
int component,
|
||||
int address_family) {
|
||||
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||
// In order to ensure that the RTCPeerConnection is not garbage collected
|
||||
// from under the function, we keep a pointer to it on the stack.
|
||||
auto* client_on_stack = client_.Get();
|
||||
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||
+ if (!client_on_stack) {
|
||||
+ return;
|
||||
+ }
|
||||
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateImpl");
|
||||
// This line can cause garbage collection.
|
||||
auto* platform_candidate = MakeGarbageCollected<RTCIceCandidatePlatform>(
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
|
||||
index f8838ab0c5a31182e210cc6f42b9f489c7dd5365..f689a679a7589f16839349189cbfdf84efd14367 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
|
||||
@@ -601,7 +601,7 @@ class RTCPeerConnectionHandlerTest : public SimTest {
|
||||
waitable_event->Signal();
|
||||
}
|
||||
|
||||
- public:
|
||||
+ protected:
|
||||
ScopedTestingPlatformSupport<AudioCapturerSourceTestingPlatformSupport>
|
||||
webrtc_audio_device_platform_support_;
|
||||
Persistent<MockRTCPeerConnectionHandlerClient> mock_client_;
|
||||
@@ -1168,4 +1168,32 @@ TEST_F(RTCPeerConnectionHandlerTest,
|
||||
observer->OnIceCandidate(native_candidate.get());
|
||||
}
|
||||
|
||||
+TEST_F(RTCPeerConnectionHandlerTest,
|
||||
+ OnIceCandidateAfterClientGarbageCollectionDoesNothing) {
|
||||
+ testing::InSequence sequence;
|
||||
+ EXPECT_CALL(*mock_tracker_.Get(),
|
||||
+ TrackAddIceCandidate(pc_handler_.get(), _,
|
||||
+ PeerConnectionTracker::kSourceLocal, true))
|
||||
+ .Times(0);
|
||||
+
|
||||
+ std::unique_ptr<webrtc::IceCandidateInterface> native_candidate(
|
||||
+ mock_dependency_factory_->CreateIceCandidate("sdpMid", 1, kDummySdp));
|
||||
+ mock_client_ = nullptr;
|
||||
+ WebHeap::CollectAllGarbageForTesting();
|
||||
+ pc_handler_->observer()->OnIceCandidate(native_candidate.get());
|
||||
+ RunMessageLoopsUntilIdle();
|
||||
+}
|
||||
+
|
||||
+TEST_F(RTCPeerConnectionHandlerTest,
|
||||
+ OnIceCandidateAfterClientGarbageCollectionFails) {
|
||||
+ DummyExceptionStateForTesting exception_state;
|
||||
+ auto pc_handler = CreateRTCPeerConnectionHandlerUnderTest();
|
||||
+ mock_client_ = nullptr;
|
||||
+ WebHeap::CollectAllGarbageForTesting();
|
||||
+ EXPECT_FALSE(pc_handler->Initialize(
|
||||
+ /*context=*/nullptr, webrtc::PeerConnectionInterface::RTCConfiguration(),
|
||||
+ /*media_constraints=*/nullptr,
|
||||
+ /*frame=*/nullptr, exception_state));
|
||||
+}
|
||||
+
|
||||
} // namespace blink
|
||||
33
patches/chromium/cherry-pick-8d607d3921b8.patch
Normal file
33
patches/chromium/cherry-pick-8d607d3921b8.patch
Normal file
@@ -0,0 +1,33 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Gustaf Ullberg <gustaf@chromium.org>
|
||||
Date: Wed, 20 Dec 2023 16:59:29 +0000
|
||||
Subject: WebRtcAudioSink: Stop on invalid configuration
|
||||
|
||||
(cherry picked from commit 340b7e300d380460a039a07b90f62d1febae9da5)
|
||||
|
||||
Bug: 1513170
|
||||
Change-Id: Ia4ca55e9eafb81789b28b8b8c54e615ac28df633
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5136295
|
||||
Reviewed-by: Harald Alvestrand <hta@chromium.org>
|
||||
Commit-Queue: Gustaf Ullberg <gustaf@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1239233}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5136708
|
||||
Owners-Override: Krishna Govind <govind@chromium.org>
|
||||
Commit-Queue: Krishna Govind <govind@chromium.org>
|
||||
Reviewed-by: Krishna Govind <govind@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1566}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc b/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
|
||||
index cd5b8b83ce3904f0d13152627602a57b2af116cf..de4a661d6322220ed04c471a14570e91f3f76896 100644
|
||||
--- a/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
|
||||
+++ b/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
|
||||
@@ -121,7 +121,7 @@ void WebRtcAudioSink::OnData(const media::AudioBus& audio_bus,
|
||||
}
|
||||
|
||||
void WebRtcAudioSink::OnSetFormat(const media::AudioParameters& params) {
|
||||
- DCHECK(params.IsValid());
|
||||
+ CHECK(params.IsValid());
|
||||
SendLogMessage(base::StringPrintf("OnSetFormat([label=%s] {params=[%s]})",
|
||||
adapter_->label().c_str(),
|
||||
params.AsHumanReadableString().c_str()));
|
||||
125
patches/chromium/cherry-pick-91a02d67a83d.patch
Normal file
125
patches/chromium/cherry-pick-91a02d67a83d.patch
Normal file
@@ -0,0 +1,125 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jean-Philippe Gravel <jpgravel@chromium.org>
|
||||
Date: Tue, 23 Jan 2024 21:37:50 +0000
|
||||
Subject: Fix use-after-free in DrawTextInternal
|
||||
|
||||
DrawTextInternal was calling GetOrCreatePaintCanvas multiple times,
|
||||
once at the start of the function, once inside of the
|
||||
BaseRenderingContext2DAutoRestoreSkCanvas helper class and once in the
|
||||
Draw call. GetOrCreatePaintCanvas destroys the canvas resource provider
|
||||
if the GPU context is lost. If this happens on the second call to
|
||||
GetOrCreatePaintCanvas, destroying the resource provider will
|
||||
invalidate the cc::PaintCanvas returned by the first call to
|
||||
GetOrCreatePaintCanvas.
|
||||
|
||||
The GPU process can technically crash at any point during the renderer
|
||||
process execution (perhaps because of something another renderer
|
||||
process did). We therefore have to assume that any call to
|
||||
GetOrCreatePaintCanvas can invalidate previously returned
|
||||
cc::PaintCanvas.
|
||||
|
||||
(cherry picked from commit d4a197e4913f8e5072263b59aedc29f2b5af3e93)
|
||||
|
||||
Change-Id: Ifa77735ab1b2b55b3d494f886b8566299937f6fe
|
||||
Fixed: 1511567
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5198419
|
||||
Reviewed-by: Fernando Serboncini <fserb@chromium.org>
|
||||
Commit-Queue: Jean-Philippe Gravel <jpgravel@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1248204}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5230237
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1859}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
|
||||
index f09459b0b67c37d307c70a516731d05db49f49b8..89cb2a41b3eef8bb359984b0d14bfa0e4e19cfdc 100644
|
||||
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
|
||||
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
|
||||
@@ -2682,40 +2682,6 @@ const Font& BaseRenderingContext2D::AccessFont(HTMLCanvasElement* canvas) {
|
||||
return GetState().GetFont();
|
||||
}
|
||||
|
||||
-namespace {
|
||||
-
|
||||
-// Drawing methods need to use this instead of SkAutoCanvasRestore in case
|
||||
-// overdraw detection substitutes the recording canvas (to discard overdrawn
|
||||
-// draw calls).
|
||||
-class BaseRenderingContext2DAutoRestoreSkCanvas {
|
||||
- STACK_ALLOCATED();
|
||||
-
|
||||
- public:
|
||||
- explicit BaseRenderingContext2DAutoRestoreSkCanvas(
|
||||
- BaseRenderingContext2D* context)
|
||||
- : context_(context) {
|
||||
- DCHECK(context_);
|
||||
- cc::PaintCanvas* c = context_->GetOrCreatePaintCanvas();
|
||||
- if (c) {
|
||||
- save_count_ = c->getSaveCount();
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- ~BaseRenderingContext2DAutoRestoreSkCanvas() {
|
||||
- cc::PaintCanvas* c = context_->GetOrCreatePaintCanvas();
|
||||
- if (c) {
|
||||
- c->restoreToCount(save_count_);
|
||||
- }
|
||||
- context_->ValidateStateStack();
|
||||
- }
|
||||
-
|
||||
- private:
|
||||
- BaseRenderingContext2D* context_;
|
||||
- int save_count_ = 0;
|
||||
-};
|
||||
-
|
||||
-} // namespace
|
||||
-
|
||||
void BaseRenderingContext2D::DrawTextInternal(
|
||||
const String& text,
|
||||
double x,
|
||||
@@ -2736,8 +2702,10 @@ void BaseRenderingContext2D::DrawTextInternal(
|
||||
canvas->GetDocument().UpdateStyleAndLayoutTreeForNode(
|
||||
canvas, DocumentUpdateReason::kCanvas);
|
||||
}
|
||||
- cc::PaintCanvas* c = GetOrCreatePaintCanvas();
|
||||
- if (!c) {
|
||||
+
|
||||
+ // Abort if we don't have a paint canvas (e.g. the context was lost).
|
||||
+ cc::PaintCanvas* paint_canvas = GetOrCreatePaintCanvas();
|
||||
+ if (!paint_canvas) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2808,14 +2776,13 @@ void BaseRenderingContext2D::DrawTextInternal(
|
||||
InflateStrokeRect(bounds);
|
||||
}
|
||||
|
||||
- BaseRenderingContext2DAutoRestoreSkCanvas state_restorer(this);
|
||||
if (use_max_width) {
|
||||
- c->save();
|
||||
+ paint_canvas->save();
|
||||
// We draw when fontWidth is 0 so compositing operations (eg, a "copy" op)
|
||||
// still work. As the width of canvas is scaled, so text can be scaled to
|
||||
// match the given maxwidth, update text location so it appears on desired
|
||||
// place.
|
||||
- c->scale(ClampTo<float>(width / font_width), 1);
|
||||
+ paint_canvas->scale(ClampTo<float>(width / font_width), 1);
|
||||
location.set_x(location.x() / ClampTo<float>(width / font_width));
|
||||
}
|
||||
|
||||
@@ -2846,6 +2813,16 @@ void BaseRenderingContext2D::DrawTextInternal(
|
||||
{ return false; },
|
||||
bounds, paint_type, CanvasRenderingContext2DState::kNoImage,
|
||||
CanvasPerformanceMonitor::DrawType::kText);
|
||||
+
|
||||
+ if (use_max_width) {
|
||||
+ // Cannot use `paint_canvas` in case recording canvas was substituted or
|
||||
+ // destroyed during draw call.
|
||||
+ cc::PaintCanvas* c = GetPaintCanvas();
|
||||
+ if (c) {
|
||||
+ c->restore();
|
||||
+ }
|
||||
+ }
|
||||
+ ValidateStateStack();
|
||||
}
|
||||
|
||||
TextMetrics* BaseRenderingContext2D::measureText(const String& text) {
|
||||
175
patches/chromium/cherry-pick-998e947b265f.patch
Normal file
175
patches/chromium/cherry-pick-998e947b265f.patch
Normal file
@@ -0,0 +1,175 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yi Gu <yigu@chromium.org>
|
||||
Date: Fri, 1 Dec 2023 00:10:37 +0000
|
||||
Subject: Check API permission before showing accounts UI
|
||||
|
||||
The accounts fetch could be delayed for legitimate reasons. A user may be
|
||||
able to disable FedCM API (e.g. via settings or dismissing another FedCM
|
||||
UI on the same RP origin) before the browser receives the accounts
|
||||
response.
|
||||
|
||||
This patch checks the API permission before showing the accounts UI.
|
||||
|
||||
(cherry picked from commit 98676a2f66c4b4b802316eef70f4aab77e631f85)
|
||||
|
||||
Change-Id: Idbbe88912941113ec3f54d7f222845cd774dc897
|
||||
Bug: 1500921
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5064052
|
||||
Commit-Queue: Yi Gu <yigu@chromium.org>
|
||||
Reviewed-by: Christian Biesinger <cbiesinger@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1229912}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5074630
|
||||
Auto-Submit: Yi Gu <yigu@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1255}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc
|
||||
index b2717870cd40ec50fb8c6d22fab5fae89f5c9a20..5c8431c19e376f493fbb22bfdf626188e1fdaf20 100644
|
||||
--- a/content/browser/webid/federated_auth_request_impl.cc
|
||||
+++ b/content/browser/webid/federated_auth_request_impl.cc
|
||||
@@ -685,9 +685,7 @@ void FederatedAuthRequestImpl::RequestToken(
|
||||
request_dialog_controller_ = CreateDialogController();
|
||||
start_time_ = base::TimeTicks::Now();
|
||||
|
||||
- FederatedApiPermissionStatus permission_status =
|
||||
- GetApiPermissionStatus(url::Origin::Create(
|
||||
- idp_get_params_ptrs[0]->providers[0]->get_federated()->config_url));
|
||||
+ FederatedApiPermissionStatus permission_status = GetApiPermissionStatus();
|
||||
|
||||
absl::optional<TokenStatus> error_token_status;
|
||||
FederatedAuthRequestResult request_result =
|
||||
@@ -896,8 +894,7 @@ void FederatedAuthRequestImpl::LogoutRps(
|
||||
return;
|
||||
}
|
||||
|
||||
- if (GetApiPermissionStatus(origin()) !=
|
||||
- FederatedApiPermissionStatus::GRANTED) {
|
||||
+ if (GetApiPermissionStatus() != FederatedApiPermissionStatus::GRANTED) {
|
||||
CompleteLogoutRequest(LogoutRpsStatus::kError);
|
||||
return;
|
||||
}
|
||||
@@ -1181,6 +1178,18 @@ void FederatedAuthRequestImpl::MaybeShowAccountsDialog() {
|
||||
return;
|
||||
}
|
||||
|
||||
+ // The accounts fetch could be delayed for legitimate reasons. A user may be
|
||||
+ // able to disable FedCM API (e.g. via settings or dismissing another FedCM UI
|
||||
+ // on the same RP origin) before the browser receives the accounts response.
|
||||
+ // We should exit early without showing any UI.
|
||||
+ if (GetApiPermissionStatus() != FederatedApiPermissionStatus::GRANTED) {
|
||||
+ CompleteRequestWithError(
|
||||
+ FederatedAuthRequestResult::kErrorDisabledInSettings,
|
||||
+ TokenStatus::kDisabledInSettings,
|
||||
+ /*should_delay_callback=*/true);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
// The RenderFrameHost may be alive but not visible in the following
|
||||
// situations:
|
||||
// Situation #1: User switched tabs
|
||||
@@ -1619,9 +1628,7 @@ void FederatedAuthRequestImpl::OnAccountSelected(const GURL& idp_config_url,
|
||||
// settings are changed while an existing FedCM UI is displayed. Ideally, we
|
||||
// should enforce this check before all requests but users typically won't
|
||||
// have time to disable the FedCM API in other types of requests.
|
||||
- url::Origin idp_origin = url::Origin::Create(idp_config_url);
|
||||
- if (GetApiPermissionStatus(idp_origin) !=
|
||||
- FederatedApiPermissionStatus::GRANTED) {
|
||||
+ if (GetApiPermissionStatus() != FederatedApiPermissionStatus::GRANTED) {
|
||||
CompleteRequestWithError(
|
||||
FederatedAuthRequestResult::kErrorDisabledInSettings,
|
||||
TokenStatus::kDisabledInSettings,
|
||||
@@ -2262,8 +2269,8 @@ void FederatedAuthRequestImpl::OnRejectRequest() {
|
||||
}
|
||||
}
|
||||
|
||||
-FederatedApiPermissionStatus FederatedAuthRequestImpl::GetApiPermissionStatus(
|
||||
- const url::Origin& idp_origin) {
|
||||
+FederatedApiPermissionStatus
|
||||
+FederatedAuthRequestImpl::GetApiPermissionStatus() {
|
||||
DCHECK(api_permission_delegate_);
|
||||
FederatedApiPermissionStatus status =
|
||||
api_permission_delegate_->GetApiPermissionStatus(GetEmbeddingOrigin());
|
||||
@@ -2271,7 +2278,7 @@ FederatedApiPermissionStatus FederatedAuthRequestImpl::GetApiPermissionStatus(
|
||||
// status API is enabled, in general or through OT.
|
||||
if (status ==
|
||||
FederatedApiPermissionStatus::BLOCKED_THIRD_PARTY_COOKIES_BLOCKED &&
|
||||
- webid::GetIdpSigninStatusMode(render_frame_host(), idp_origin) ==
|
||||
+ webid::GetIdpSigninStatusMode(render_frame_host(), url::Origin()) ==
|
||||
FedCmIdpSigninStatusMode::ENABLED) {
|
||||
status = FederatedApiPermissionStatus::GRANTED;
|
||||
}
|
||||
diff --git a/content/browser/webid/federated_auth_request_impl.h b/content/browser/webid/federated_auth_request_impl.h
|
||||
index aaf21e3f443ae26d4918602943117d695c0e54ff..d7117ee9c1424107b168a45edc21b4182a27cbd8 100644
|
||||
--- a/content/browser/webid/federated_auth_request_impl.h
|
||||
+++ b/content/browser/webid/federated_auth_request_impl.h
|
||||
@@ -109,10 +109,9 @@ class CONTENT_EXPORT FederatedAuthRequestImpl
|
||||
// Rejects the pending request if it has not been resolved naturally yet.
|
||||
void OnRejectRequest();
|
||||
|
||||
- // This wrapper around FederatedIdentityApiPermissionContextDelegate ensures
|
||||
- // that we handle BLOCKED_THIRD_PARTY_COOKIES_BLOCKED correctly.
|
||||
+ // Returns whether the API is enabled or not.
|
||||
FederatedIdentityApiPermissionContextDelegate::PermissionStatus
|
||||
- GetApiPermissionStatus(const url::Origin& idp_origin);
|
||||
+ GetApiPermissionStatus();
|
||||
|
||||
struct IdentityProviderGetInfo {
|
||||
IdentityProviderGetInfo(blink::mojom::IdentityProviderConfigPtr,
|
||||
diff --git a/content/browser/webid/federated_auth_request_impl_unittest.cc b/content/browser/webid/federated_auth_request_impl_unittest.cc
|
||||
index 347fc6a19609c88313ccbbe7fda7841c7ff8268d..ea886ed50780007ec0f2a7babc9caeaa58cb1bb8 100644
|
||||
--- a/content/browser/webid/federated_auth_request_impl_unittest.cc
|
||||
+++ b/content/browser/webid/federated_auth_request_impl_unittest.cc
|
||||
@@ -711,15 +711,28 @@ class TestDialogController
|
||||
|
||||
class TestApiPermissionDelegate : public MockApiPermissionDelegate {
|
||||
public:
|
||||
- std::pair<url::Origin, ApiPermissionStatus> permission_override_ =
|
||||
+ using PermissionOverride = std::pair<url::Origin, ApiPermissionStatus>;
|
||||
+ PermissionOverride permission_override_ =
|
||||
std::make_pair(url::Origin(), ApiPermissionStatus::GRANTED);
|
||||
+ absl::optional<std::pair<size_t, PermissionOverride>>
|
||||
+ permission_override_for_nth_;
|
||||
std::set<url::Origin> embargoed_origins_;
|
||||
+ size_t api_invocation_counter{0};
|
||||
|
||||
ApiPermissionStatus GetApiPermissionStatus(
|
||||
const url::Origin& origin) override {
|
||||
+ ++api_invocation_counter;
|
||||
+
|
||||
if (embargoed_origins_.count(origin))
|
||||
return ApiPermissionStatus::BLOCKED_EMBARGO;
|
||||
|
||||
+ if (permission_override_for_nth_ &&
|
||||
+ permission_override_for_nth_->first == api_invocation_counter) {
|
||||
+ return (origin == permission_override_for_nth_->second.first)
|
||||
+ ? permission_override_for_nth_->second.second
|
||||
+ : ApiPermissionStatus::GRANTED;
|
||||
+ }
|
||||
+
|
||||
return (origin == permission_override_.first)
|
||||
? permission_override_.second
|
||||
: ApiPermissionStatus::GRANTED;
|
||||
@@ -4991,4 +5004,23 @@ TEST_F(FederatedAuthRequestImplTest, InvalidResponseErrorDialogDisabled) {
|
||||
EXPECT_FALSE(dialog_controller_state_.did_show_error_dialog);
|
||||
}
|
||||
|
||||
+// Test that the account UI is not displayed if FedCM is disabled after accounts
|
||||
+// fetch.
|
||||
+TEST_F(FederatedAuthRequestImplTest,
|
||||
+ AccountUiNotDisplayedIfFedCmDisabledAfterAccountsFetch) {
|
||||
+ test_api_permission_delegate_->permission_override_for_nth_ = std::make_pair(
|
||||
+ /*override the nth invocation=*/2,
|
||||
+ std::make_pair(main_test_rfh()->GetLastCommittedOrigin(),
|
||||
+ ApiPermissionStatus::BLOCKED_EMBARGO));
|
||||
+
|
||||
+ RequestExpectations expectations = {
|
||||
+ RequestTokenStatus::kError,
|
||||
+ FederatedAuthRequestResult::kErrorDisabledInSettings,
|
||||
+ /*standalone_console_message=*/absl::nullopt,
|
||||
+ /*selected_idp_config_url=*/absl::nullopt};
|
||||
+ RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
|
||||
+ EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
|
||||
+ EXPECT_FALSE(did_show_accounts_dialog());
|
||||
+}
|
||||
+
|
||||
} // namespace content
|
||||
31
patches/chromium/cherry-pick-c1cda70a433a.patch
Normal file
31
patches/chromium/cherry-pick-c1cda70a433a.patch
Normal file
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Wasserman <msw@chromium.org>
|
||||
Date: Thu, 21 Dec 2023 22:33:05 +0000
|
||||
Subject: Speculative fix for UAF in
|
||||
content::WebContentsImpl::ExitFullscreenMode
|
||||
|
||||
Bug: 1506535, 854815
|
||||
Change-Id: Iace64d63f8cea2dbfbc761ad233db42451ec101c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5146875
|
||||
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
|
||||
Auto-Submit: Mike Wasserman <msw@chromium.org>
|
||||
Reviewed-by: John Abd-El-Malek <jam@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1240353}
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index dd060f4207516af6b7db21593dcbed3848d47409..0ecc7989e7bfa459c80b4fe10705781257dd9b7d 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -3748,7 +3748,12 @@ void WebContentsImpl::ExitFullscreenMode(bool will_cause_resize) {
|
||||
static_cast<RenderWidgetHostViewBase*>(view)->ExitFullscreenMode();
|
||||
|
||||
if (delegate_) {
|
||||
+ // This may spin the message loop and destroy this object crbug.com/1506535
|
||||
+ base::WeakPtr<WebContentsImpl> weak_ptr = weak_factory_.GetWeakPtr();
|
||||
delegate_->ExitFullscreenModeForTab(this);
|
||||
+ if (!weak_ptr) {
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
if (keyboard_lock_widget_)
|
||||
delegate_->CancelKeyboardLockRequest(this);
|
||||
165
patches/chromium/cherry-pick-cc07a95bc309.patch
Normal file
165
patches/chromium/cherry-pick-cc07a95bc309.patch
Normal file
@@ -0,0 +1,165 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hongchan Choi <hongchan@chromium.org>
|
||||
Date: Fri, 19 Jan 2024 19:17:18 +0000
|
||||
Subject: Update rendering state of automatic pull nodes before graph rendering
|
||||
|
||||
In rare cases, the rendering fan out count of automatic pull node
|
||||
does not match the main thread fan out count after recreating
|
||||
a platform destination followed by disconnection.
|
||||
|
||||
This CL forces the update of the rendering state of automatic
|
||||
pull nodes before graph rendering to make sure that fan out counts
|
||||
are synchronized before executing the audio processing function call.
|
||||
|
||||
NOTE: This change makes 2 WPTs fail. The follow-up work is planned
|
||||
to address them once this patch is merged.
|
||||
|
||||
(cherry picked from commit f4bffa09b46c21147431179e1e6dd2b27bc35fbc)
|
||||
|
||||
Bug: 1505080
|
||||
Test: Locally confirmed that ASAN doesn't crash on all repro cases.
|
||||
Change-Id: I6768cd8bc64525ea9d56a19b9c58439e9cdab9a8
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5131958
|
||||
Reviewed-by: Michael Wilson <mjwilson@chromium.org>
|
||||
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1246718}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5214669
|
||||
Auto-Submit: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1833}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/analyser_handler.cc b/third_party/blink/renderer/modules/webaudio/analyser_handler.cc
|
||||
index b2f3242426930b06694a12296206da1e7a7abfb7..490143f710dc51a93dd89fdc85035519db5e292b 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/analyser_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/analyser_handler.cc
|
||||
@@ -40,9 +40,14 @@ AnalyserHandler::~AnalyserHandler() {
|
||||
}
|
||||
|
||||
void AnalyserHandler::Process(uint32_t frames_to_process) {
|
||||
- AudioBus* output_bus = Output(0).Bus();
|
||||
+ DCHECK(Context()->IsAudioThread());
|
||||
+
|
||||
+ // It's possible that output is not connected. Assign nullptr to indicate
|
||||
+ // such case.
|
||||
+ AudioBus* output_bus = Output(0).RenderingFanOutCount() > 0
|
||||
+ ? Output(0).Bus() : nullptr;
|
||||
|
||||
- if (!IsInitialized()) {
|
||||
+ if (!IsInitialized() && output_bus) {
|
||||
output_bus->Zero();
|
||||
return;
|
||||
}
|
||||
@@ -54,6 +59,11 @@ void AnalyserHandler::Process(uint32_t frames_to_process) {
|
||||
// Analyser reflects the current input.
|
||||
analyser_.WriteInput(input_bus.get(), frames_to_process);
|
||||
|
||||
+ // Subsequent steps require `output_bus` to be valid.
|
||||
+ if (!output_bus) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (!Input(0).IsConnected()) {
|
||||
// No inputs, so clear the output, and propagate the silence hint.
|
||||
output_bus->Zero();
|
||||
@@ -178,8 +188,12 @@ double AnalyserHandler::TailTime() const {
|
||||
}
|
||||
|
||||
void AnalyserHandler::PullInputs(uint32_t frames_to_process) {
|
||||
- // Render directly into the output bus
|
||||
- Input(0).Pull(Output(0).Bus(), frames_to_process);
|
||||
+ DCHECK(Context()->IsAudioThread());
|
||||
+
|
||||
+ AudioBus* output_bus = Output(0).RenderingFanOutCount() > 0
|
||||
+ ? Output(0).Bus() : nullptr;
|
||||
+
|
||||
+ Input(0).Pull(output_bus, frames_to_process);
|
||||
}
|
||||
|
||||
void AnalyserHandler::CheckNumberOfChannelsForInput(AudioNodeInput* input) {
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
|
||||
index 0bf86b7d659533e0acd9cd0c902c6dd68b51e1e6..903e8172d7c381da2e2cb8e9962ea601c76b375a 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
|
||||
@@ -119,12 +119,14 @@ void AudioWorkletHandler::Process(uint32_t frames_to_process) {
|
||||
return;
|
||||
}
|
||||
|
||||
- // If the input is not connected, inform the processor with nullptr.
|
||||
+ // If the input or the output is not connected, inform the processor with
|
||||
+ // nullptr.
|
||||
for (unsigned i = 0; i < NumberOfInputs(); ++i) {
|
||||
inputs_[i] = Input(i).IsConnected() ? Input(i).Bus() : nullptr;
|
||||
}
|
||||
for (unsigned i = 0; i < NumberOfOutputs(); ++i) {
|
||||
- outputs_[i] = WrapRefCounted(Output(i).Bus());
|
||||
+ outputs_[i] = Output(i).RenderingFanOutCount() > 0
|
||||
+ ? WrapRefCounted(Output(i).Bus()) : nullptr;
|
||||
}
|
||||
|
||||
for (const auto& param_name : param_value_map_.Keys()) {
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
|
||||
index 181dfa92723843d5ce9ae3e7399215870ac1dc80..c3c53d7a7099d67a6bb76df55a6c71965ca3bf02 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
|
||||
@@ -376,6 +376,12 @@ void AudioWorkletProcessor::CopyArrayBuffersToPort(
|
||||
|
||||
for (uint32_t bus_index = 0; bus_index < audio_port.size(); ++bus_index) {
|
||||
const scoped_refptr<AudioBus>& audio_bus = audio_port[bus_index];
|
||||
+
|
||||
+ // nullptr indicates the output bus is not connected. Do not proceed.
|
||||
+ if (!audio_bus) {
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
for (uint32_t channel_index = 0;
|
||||
channel_index < audio_bus->NumberOfChannels(); ++channel_index) {
|
||||
auto backing_store = array_buffers[bus_index][channel_index]
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
|
||||
index fa1de8f37b9be681f7ac447bc3e3859e8909216d..4730383dafa957c2e84c009387d15d6fe479e5ba 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
|
||||
@@ -172,6 +172,16 @@ void DeferredTaskHandler::UpdateAutomaticPullNodes() {
|
||||
base::AutoTryLock try_locker(automatic_pull_handlers_lock_);
|
||||
if (try_locker.is_acquired()) {
|
||||
rendering_automatic_pull_handlers_.assign(automatic_pull_handlers_);
|
||||
+
|
||||
+ // In rare cases, it is possible for automatic pull nodes' output bus
|
||||
+ // to become stale. Make sure update their rendering output counts.
|
||||
+ // crbug.com/1505080.
|
||||
+ for (auto& handler : rendering_automatic_pull_handlers_) {
|
||||
+ for (unsigned i = 0; i < handler->NumberOfOutputs(); ++i) {
|
||||
+ handler->Output(i).UpdateRenderingState();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
automatic_pull_handlers_need_updating_ = false;
|
||||
}
|
||||
}
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html
|
||||
index 33627204a6f538eba77bd8346952404814e4affa..ce0cfa40b691d859d372c9e6da7ff54fe64bbbe1 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html
|
||||
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html
|
||||
@@ -43,7 +43,10 @@
|
||||
if (actual.done)
|
||||
task.done();
|
||||
};
|
||||
- sourceNode.connect(workletNode);
|
||||
+ // To have valid ArrayBuffers for both input and output, we need
|
||||
+ // both connections.
|
||||
+ // See: https://github.com/WebAudio/web-audio-api/issues/2566
|
||||
+ sourceNode.connect(workletNode).connect(context.destination);
|
||||
sourceNode.start();
|
||||
});
|
||||
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/process-parameters.https-expected.txt b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/process-parameters.https-expected.txt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fbac76d9b865bfdec552bf280e4a19ae1743ef4a
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/process-parameters.https-expected.txt
|
||||
@@ -0,0 +1,6 @@
|
||||
+This is a testharness.js-based test.
|
||||
+[PASS] 3 inputs; 0 outputs
|
||||
+[FAIL] 0 inputs; 3 outputs
|
||||
+ assert_equals: outputs[0].length expected 1 but got 0
|
||||
+Harness: the test ran to completion.
|
||||
+
|
||||
181
patches/chromium/cherry-pick-f15cfb9371c4.patch
Normal file
181
patches/chromium/cherry-pick-f15cfb9371c4.patch
Normal file
@@ -0,0 +1,181 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kai Ninomiya <kainino@chromium.org>
|
||||
Date: Thu, 7 Dec 2023 14:31:32 +0000
|
||||
Subject: Fix reinit order in
|
||||
ContextProviderCommandBuffer::BindToCurrentSequence
|
||||
|
||||
See comments for explanation.
|
||||
|
||||
(cherry picked from commit 7d8400ceb56db5fd97249f787251fe8b3928e6fd)
|
||||
|
||||
Bug: 1505632
|
||||
Change-Id: I0f43821a9708af91303048332e9fae5e100deee5
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5069480
|
||||
Reviewed-by: Saifuddin Hitawala <hitawala@chromium.org>
|
||||
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
|
||||
Reviewed-by: Brendon Tiszka <tiszka@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1230735}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5095795
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Commit-Queue: Saifuddin Hitawala <hitawala@chromium.org>
|
||||
Auto-Submit: Kai Ninomiya <kainino@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1424}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
|
||||
index 4d516f50bf2270c7fcf152dad5a11795a3e02232..da496e51d04af6699058cea36de0da65a01cdc3a 100644
|
||||
--- a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
|
||||
+++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
|
||||
@@ -169,13 +169,13 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
|
||||
}
|
||||
|
||||
// The transfer buffer is used to serialize Dawn commands
|
||||
- transfer_buffer_ =
|
||||
+ auto transfer_buffer =
|
||||
std::make_unique<gpu::TransferBuffer>(webgpu_helper.get());
|
||||
|
||||
// The WebGPUImplementation exposes the WebGPUInterface, as well as the
|
||||
// gpu::ContextSupport interface.
|
||||
auto webgpu_impl = std::make_unique<gpu::webgpu::WebGPUImplementation>(
|
||||
- webgpu_helper.get(), transfer_buffer_.get(), command_buffer_.get());
|
||||
+ webgpu_helper.get(), transfer_buffer.get(), command_buffer_.get());
|
||||
bind_result_ = webgpu_impl->Initialize(memory_limits_);
|
||||
if (bind_result_ != gpu::ContextResult::kSuccess) {
|
||||
DLOG(ERROR) << "Failed to initialize WebGPUImplementation.";
|
||||
@@ -187,8 +187,11 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
|
||||
std::string unique_context_name =
|
||||
base::StringPrintf("%s-%p", type_name.c_str(), webgpu_impl.get());
|
||||
|
||||
+ // IMPORTANT: These hold raw_ptrs to each other, so must be set together.
|
||||
+ // See note in the header (and keep it up to date if things change).
|
||||
impl_ = webgpu_impl.get();
|
||||
webgpu_interface_ = std::move(webgpu_impl);
|
||||
+ transfer_buffer_ = std::move(transfer_buffer);
|
||||
helper_ = std::move(webgpu_helper);
|
||||
} else if (attributes_.enable_raster_interface &&
|
||||
!attributes_.enable_gles2_interface &&
|
||||
@@ -206,14 +209,14 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
|
||||
}
|
||||
// The transfer buffer is used to copy resources between the client
|
||||
// process and the GPU process.
|
||||
- transfer_buffer_ =
|
||||
+ auto transfer_buffer =
|
||||
std::make_unique<gpu::TransferBuffer>(raster_helper.get());
|
||||
|
||||
// The RasterImplementation exposes the RasterInterface, as well as the
|
||||
// gpu::ContextSupport interface.
|
||||
DCHECK(channel_);
|
||||
auto raster_impl = std::make_unique<gpu::raster::RasterImplementation>(
|
||||
- raster_helper.get(), transfer_buffer_.get(),
|
||||
+ raster_helper.get(), transfer_buffer.get(),
|
||||
attributes_.bind_generates_resource,
|
||||
attributes_.lose_context_when_out_of_memory, command_buffer_.get(),
|
||||
channel_->image_decode_accelerator_proxy());
|
||||
@@ -230,8 +233,11 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
|
||||
raster_impl->TraceBeginCHROMIUM("gpu_toplevel",
|
||||
unique_context_name.c_str());
|
||||
|
||||
+ // IMPORTANT: These hold raw_ptrs to each other, so must be set together.
|
||||
+ // See note in the header (and keep it up to date if things change).
|
||||
impl_ = raster_impl.get();
|
||||
raster_interface_ = std::move(raster_impl);
|
||||
+ transfer_buffer_ = std::move(transfer_buffer);
|
||||
helper_ = std::move(raster_helper);
|
||||
} else {
|
||||
// The GLES2 helper writes the command buffer protocol.
|
||||
@@ -246,7 +252,7 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
|
||||
|
||||
// The transfer buffer is used to copy resources between the client
|
||||
// process and the GPU process.
|
||||
- transfer_buffer_ =
|
||||
+ auto transfer_buffer =
|
||||
std::make_unique<gpu::TransferBuffer>(gles2_helper.get());
|
||||
|
||||
// The GLES2Implementation exposes the OpenGLES2 API, as well as the
|
||||
@@ -259,13 +265,13 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
|
||||
// we only use it if grcontext_support was requested.
|
||||
gles2_impl = std::make_unique<
|
||||
skia_bindings::GLES2ImplementationWithGrContextSupport>(
|
||||
- gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer_.get(),
|
||||
+ gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer.get(),
|
||||
attributes_.bind_generates_resource,
|
||||
attributes_.lose_context_when_out_of_memory,
|
||||
support_client_side_arrays, command_buffer_.get());
|
||||
} else {
|
||||
gles2_impl = std::make_unique<gpu::gles2::GLES2Implementation>(
|
||||
- gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer_.get(),
|
||||
+ gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer.get(),
|
||||
attributes_.bind_generates_resource,
|
||||
attributes_.lose_context_when_out_of_memory,
|
||||
support_client_side_arrays, command_buffer_.get());
|
||||
@@ -276,8 +282,11 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
|
||||
return bind_result_;
|
||||
}
|
||||
|
||||
+ // IMPORTANT: These hold raw_ptrs to each other, so must be set together.
|
||||
+ // See note in the header (and keep it up to date if things change).
|
||||
impl_ = gles2_impl.get();
|
||||
gles2_impl_ = std::move(gles2_impl);
|
||||
+ transfer_buffer_ = std::move(transfer_buffer);
|
||||
helper_ = std::move(gles2_helper);
|
||||
}
|
||||
|
||||
@@ -311,6 +320,7 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentSequence() {
|
||||
switches::kEnableGpuClientTracing)) {
|
||||
// This wraps the real GLES2Implementation and we should always use this
|
||||
// instead when it's present.
|
||||
+ // IMPORTANT: This holds a raw_ptr to gles2_impl_.
|
||||
trace_impl_ = std::make_unique<gpu::gles2::GLES2TraceImplementation>(
|
||||
gles2_impl_.get());
|
||||
gl = trace_impl_.get();
|
||||
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.h b/services/viz/public/cpp/gpu/context_provider_command_buffer.h
|
||||
index c5fdc66539ed7b0535e0ba84ac2858d7a95a4bb1..47600f1754a79a349ed48896bd8bab91b4634376 100644
|
||||
--- a/services/viz/public/cpp/gpu/context_provider_command_buffer.h
|
||||
+++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.h
|
||||
@@ -156,19 +156,42 @@ class ContextProviderCommandBuffer
|
||||
// associated shared images are destroyed.
|
||||
std::unique_ptr<gpu::ClientSharedImageInterface> shared_image_interface_;
|
||||
|
||||
- base::Lock context_lock_; // Referenced by command_buffer_.
|
||||
+ //////////////////////////////////////////////////////////////////////////////
|
||||
+ // IMPORTANT NOTE: All of the objects in this block are part of a complex //
|
||||
+ // graph of raw pointers (holder or pointee of various raw_ptrs). They are //
|
||||
+ // defined in topological order: only later items point to earlier items. //
|
||||
+ // - When writing any member, always ensure its pointers to earlier members
|
||||
+ // are guaranteed to stay alive.
|
||||
+ // - When clearing OR overwriting any member, always ensure objects that
|
||||
+ // point to it have already been cleared.
|
||||
+ // - The topological order of definitions guarantees that the
|
||||
+ // destructors will be called in the correct order (bottom to top).
|
||||
+ // - When overwriting multiple members, similarly do so in reverse order.
|
||||
+ //
|
||||
+ // Please note these comments are likely not to stay perfectly up-to-date.
|
||||
+
|
||||
+ base::Lock context_lock_;
|
||||
+ // Points to the context_lock_ field of `this`.
|
||||
std::unique_ptr<gpu::CommandBufferProxyImpl> command_buffer_;
|
||||
+
|
||||
+ // Points to command_buffer_.
|
||||
std::unique_ptr<gpu::CommandBufferHelper> helper_;
|
||||
+ // Points to helper_.
|
||||
std::unique_ptr<gpu::TransferBuffer> transfer_buffer_;
|
||||
|
||||
+ // Points to transfer_buffer_, helper_, and command_buffer_.
|
||||
std::unique_ptr<gpu::gles2::GLES2Implementation> gles2_impl_;
|
||||
+ // Points to gles2_impl_.
|
||||
std::unique_ptr<gpu::gles2::GLES2TraceImplementation> trace_impl_;
|
||||
+ // Points to transfer_buffer_, helper_, and command_buffer_.
|
||||
std::unique_ptr<gpu::raster::RasterInterface> raster_interface_;
|
||||
+ // Points to transfer_buffer_, helper_, and command_buffer_.
|
||||
std::unique_ptr<gpu::webgpu::WebGPUInterface> webgpu_interface_;
|
||||
+ // This is an alias for gles2_impl_, raster_interface_, or webgpu_interface_.
|
||||
+ raw_ptr<gpu::ImplementationBase> impl_ = nullptr;
|
||||
|
||||
- // Owned by one of gles2_impl_, raster_interface_, or webgpu_interface_. It
|
||||
- // must be declared last and cleared first.
|
||||
- raw_ptr<gpu::ImplementationBase> impl_;
|
||||
+ // END IMPORTANT NOTE //
|
||||
+ //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<skia_bindings::GrContextForGLES2Interface> gr_context_;
|
||||
|
||||
390
patches/chromium/feat_allow_code_cache_in_custom_schemes.patch
Normal file
390
patches/chromium/feat_allow_code_cache_in_custom_schemes.patch
Normal file
@@ -0,0 +1,390 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 26 Oct 2023 11:07:47 +0900
|
||||
Subject: Enable V8 code cache for custom schemes
|
||||
|
||||
Add a new category in ContentClient::AddAdditionalSchemes which allows
|
||||
embedders to make custom schemes allow V8 code cache.
|
||||
|
||||
Chromium CL: https://chromium-review.googlesource.com/c/chromium/src/+/5019665
|
||||
|
||||
diff --git a/content/browser/code_cache/generated_code_cache.cc b/content/browser/code_cache/generated_code_cache.cc
|
||||
index 86058c25d4128539c3f6f39691550a7ee8f23064..04dd303919a3dc12c6a3c6770df8dac456084f57 100644
|
||||
--- a/content/browser/code_cache/generated_code_cache.cc
|
||||
+++ b/content/browser/code_cache/generated_code_cache.cc
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
+#include "base/containers/contains.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/functional/callback_helpers.h"
|
||||
@@ -24,6 +25,7 @@
|
||||
#include "net/base/url_util.h"
|
||||
#include "net/http/http_cache.h"
|
||||
#include "url/gurl.h"
|
||||
+#include "url/url_util.h"
|
||||
|
||||
using storage::BigIOBuffer;
|
||||
|
||||
@@ -46,24 +48,37 @@ void CheckValidKeys(const GURL& resource_url,
|
||||
GeneratedCodeCache::CodeCacheType cache_type) {
|
||||
// If the resource url is invalid don't cache the code.
|
||||
DCHECK(resource_url.is_valid());
|
||||
+ bool resource_url_allows_code_cache =
|
||||
+ base::Contains(url::GetCodeCacheSchemes(), resource_url.scheme());
|
||||
bool resource_url_is_chrome_or_chrome_untrusted =
|
||||
resource_url.SchemeIs(content::kChromeUIScheme) ||
|
||||
resource_url.SchemeIs(content::kChromeUIUntrustedScheme);
|
||||
DCHECK(resource_url.SchemeIsHTTPOrHTTPS() ||
|
||||
+ resource_url_allows_code_cache ||
|
||||
resource_url_is_chrome_or_chrome_untrusted);
|
||||
|
||||
- // |origin_lock| should be either empty or should have
|
||||
- // Http/Https/chrome/chrome-untrusted schemes and it should not be a URL with
|
||||
- // opaque origin. Empty origin_locks are allowed when the renderer is not
|
||||
- // locked to an origin.
|
||||
+ // |origin_lock| should be either empty or should have code cache allowed
|
||||
+ // schemes (http/https/chrome/chrome-untrusted or other custom schemes added
|
||||
+ // by url::AddCodeCacheScheme), and it should not be a URL with opaque
|
||||
+ // origin. Empty origin_locks are allowed when the renderer is not locked to
|
||||
+ // an origin.
|
||||
+ bool origin_lock_allows_code_cache =
|
||||
+ base::Contains(url::GetCodeCacheSchemes(), origin_lock.scheme());
|
||||
bool origin_lock_is_chrome_or_chrome_untrusted =
|
||||
origin_lock.SchemeIs(content::kChromeUIScheme) ||
|
||||
origin_lock.SchemeIs(content::kChromeUIUntrustedScheme);
|
||||
DCHECK(origin_lock.is_empty() ||
|
||||
((origin_lock.SchemeIsHTTPOrHTTPS() ||
|
||||
+ origin_lock_allows_code_cache ||
|
||||
origin_lock_is_chrome_or_chrome_untrusted) &&
|
||||
!url::Origin::Create(origin_lock).opaque()));
|
||||
|
||||
+ // The custom schemes share the cache type with http(s).
|
||||
+ if (origin_lock_allows_code_cache || resource_url_allows_code_cache) {
|
||||
+ DCHECK(cache_type == GeneratedCodeCache::kJavaScript ||
|
||||
+ cache_type == GeneratedCodeCache::kWebAssembly);
|
||||
+ }
|
||||
+
|
||||
// The chrome and chrome-untrusted schemes are only used with the WebUI
|
||||
// code cache type.
|
||||
DCHECK_EQ(origin_lock_is_chrome_or_chrome_untrusted,
|
||||
diff --git a/content/browser/code_cache/generated_code_cache.h b/content/browser/code_cache/generated_code_cache.h
|
||||
index f5c5ff2c89489257003dfe3284ee9de9f517c99b..fdd2e2483171c4d43963590200817dac27d22cf9 100644
|
||||
--- a/content/browser/code_cache/generated_code_cache.h
|
||||
+++ b/content/browser/code_cache/generated_code_cache.h
|
||||
@@ -52,12 +52,14 @@ class CONTENT_EXPORT GeneratedCodeCache {
|
||||
// Cache type. Used for collecting statistics for JS and Wasm in separate
|
||||
// buckets.
|
||||
enum CodeCacheType {
|
||||
- // JavaScript from http(s) pages.
|
||||
+ // JavaScript from pages of http(s) schemes or custom schemes registered by
|
||||
+ // url::AddCodeCacheScheme.
|
||||
kJavaScript,
|
||||
|
||||
- // WebAssembly from http(s) pages. This cache allows more total size and
|
||||
- // more size per item than the JavaScript cache, since some
|
||||
- // WebAssembly programs are very large.
|
||||
+ // WebAssembly from pages of http(s) schemes or custom schemes registered by
|
||||
+ // url::AddCodeCacheScheme. This cache allows more total size and more size
|
||||
+ // per item than the JavaScript cache, since some WebAssembly programs are
|
||||
+ // very large.
|
||||
kWebAssembly,
|
||||
|
||||
// JavaScript from chrome and chrome-untrusted pages. The resource URLs are
|
||||
diff --git a/content/browser/code_cache/generated_code_cache_browsertest.cc b/content/browser/code_cache/generated_code_cache_browsertest.cc
|
||||
index c06245a4cf0fff1292927482032af5c02ddcbc67..a1cfa8c8e428d4c1cd32bda7707048a94c1001bb 100644
|
||||
--- a/content/browser/code_cache/generated_code_cache_browsertest.cc
|
||||
+++ b/content/browser/code_cache/generated_code_cache_browsertest.cc
|
||||
@@ -5,17 +5,27 @@
|
||||
#include "base/test/metrics/histogram_tester.h"
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "base/test/test_future.h"
|
||||
+#include "components/services/storage/storage_service_impl.h"
|
||||
#include "content/browser/code_cache/generated_code_cache.h"
|
||||
+#include "content/browser/code_cache/generated_code_cache_context.h"
|
||||
+#include "content/browser/storage_partition_impl.h"
|
||||
+#include "content/common/url_schemes.h"
|
||||
+#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/test/browser_test.h"
|
||||
#include "content/public/test/content_browser_test.h"
|
||||
#include "content/public/test/content_browser_test_utils.h"
|
||||
+#include "content/public/test/test_browser_context.h"
|
||||
#include "content/shell/browser/shell.h"
|
||||
+#include "content/test/test_content_client.h"
|
||||
#include "net/dns/mock_host_resolver.h"
|
||||
+#include "url/url_util.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
namespace {
|
||||
|
||||
+const std::string kCodeCacheScheme = "test-code-cache"
|
||||
+
|
||||
bool SupportsSharedWorker() {
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
// SharedWorkers are not enabled on Android. https://crbug.com/154571
|
||||
@@ -379,4 +389,80 @@ IN_PROC_BROWSER_TEST_P(CodeCacheBrowserTest,
|
||||
}
|
||||
}
|
||||
|
||||
+class CodeCacheInCustomSchemeBrowserTest : public ContentBrowserTest {
|
||||
+ public:
|
||||
+ CodeCacheInCustomSchemeBrowserTest() {
|
||||
+ SetContentClient(&test_content_client_);
|
||||
+ ReRegisterContentSchemesForTests();
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ class CustomSchemeContentClient : public TestContentClient {
|
||||
+ public:
|
||||
+ void AddAdditionalSchemes(Schemes* schemes) override {
|
||||
+ schemes->standard_schemes.push_back(kCodeCacheScheme);
|
||||
+ schemes->code_cache_schemes.push_back(kCodeCacheScheme);
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ CustomSchemeContentClient test_content_client_;
|
||||
+ url::ScopedSchemeRegistryForTests scheme_registry_;
|
||||
+};
|
||||
+
|
||||
+IN_PROC_BROWSER_TEST_F(CodeCacheInCustomSchemeBrowserTest,
|
||||
+ AllowedCustomSchemeCanGenerateCodeCache) {
|
||||
+ // Create browser context and get code cache context.
|
||||
+ base::ScopedAllowBlockingForTesting allow_blocking;
|
||||
+ TestBrowserContext browser_context;
|
||||
+ StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
|
||||
+ browser_context.GetDefaultStoragePartition());
|
||||
+ scoped_refptr<GeneratedCodeCacheContext> context =
|
||||
+ partition->GetGeneratedCodeCacheContext();
|
||||
+ EXPECT_NE(context, nullptr);
|
||||
+
|
||||
+ GURL url(kCodeCacheScheme + "://host4/script.js");
|
||||
+ GURL origin(kCodeCacheScheme + "://host1:1/");
|
||||
+ ASSERT_TRUE(url.is_valid());
|
||||
+ ASSERT_TRUE(origin.is_valid());
|
||||
+ std::string data("SomeData");
|
||||
+
|
||||
+ // Add a code cache entry for the custom scheme.
|
||||
+ base::test::TestFuture<void> add_entry_future;
|
||||
+ GeneratedCodeCacheContext::RunOrPostTask(
|
||||
+ context.get(), FROM_HERE,
|
||||
+ base::BindOnce([](scoped_refptr<GeneratedCodeCacheContext> context,
|
||||
+ const GURL& url,
|
||||
+ const GURL& origin,
|
||||
+ const std::string& data,
|
||||
+ base::OnceClosure callback) {
|
||||
+ context->generated_js_code_cache()->WriteEntry(
|
||||
+ url, origin, net::NetworkIsolationKey(),
|
||||
+ base::Time::Now(), std::vector<uint8_t>(data.begin(), data.end()));
|
||||
+ content::GetUIThreadTaskRunner({})->PostTask(
|
||||
+ FROM_HERE, std::move(callback));
|
||||
+ }, context, url, origin, data, add_entry_future.GetCallback()));
|
||||
+ ASSERT_TRUE(add_entry_future.Wait());
|
||||
+
|
||||
+ // Get the code cache entry.
|
||||
+ base::test::TestFuture<std::string> get_entry_future;
|
||||
+ GeneratedCodeCacheContext::RunOrPostTask(
|
||||
+ context.get(), FROM_HERE,
|
||||
+ base::BindOnce([](scoped_refptr<GeneratedCodeCacheContext> context,
|
||||
+ const GURL& url,
|
||||
+ const GURL& origin,
|
||||
+ base::OnceCallback<void(std::string)> callback) {
|
||||
+ context->generated_js_code_cache()->FetchEntry(
|
||||
+ url, origin, net::NetworkIsolationKey(),
|
||||
+ base::BindOnce([](base::OnceCallback<void(std::string)> callback,
|
||||
+ const base::Time& response_time,
|
||||
+ mojo_base::BigBuffer buffer) {
|
||||
+ std::string data(buffer.data(), buffer.data() + buffer.size());
|
||||
+ content::GetUIThreadTaskRunner({})->PostTask(
|
||||
+ FROM_HERE, base::BindOnce(std::move(callback), data));
|
||||
+ }, std::move(callback)));
|
||||
+ }, context, url, origin, get_entry_future.GetCallback()));
|
||||
+ ASSERT_TRUE(get_entry_future.Wait());
|
||||
+ ASSERT_EQ(data, get_entry_future.Get<0>());
|
||||
+}
|
||||
+
|
||||
} // namespace content
|
||||
diff --git a/content/browser/renderer_host/code_cache_host_impl.cc b/content/browser/renderer_host/code_cache_host_impl.cc
|
||||
index 6b9e5065dc570b506c4c2606d536319d98684e12..9d1f337b9c9890b6b7afda40bf2f829ff2a25bfd 100644
|
||||
--- a/content/browser/renderer_host/code_cache_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/code_cache_host_impl.cc
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
+#include "base/containers/contains.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/functional/callback_helpers.h"
|
||||
#include "base/metrics/histogram_functions.h"
|
||||
@@ -28,6 +29,7 @@
|
||||
#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
|
||||
#include "url/gurl.h"
|
||||
#include "url/origin.h"
|
||||
+#include "url/url_util.h"
|
||||
|
||||
using blink::mojom::CacheStorageError;
|
||||
|
||||
@@ -40,6 +42,11 @@ enum class Operation {
|
||||
kWrite,
|
||||
};
|
||||
|
||||
+bool ProcessLockURLIsCodeCacheScheme(const ProcessLock& process_lock) {
|
||||
+ return base::Contains(url::GetCodeCacheSchemes(),
|
||||
+ process_lock.lock_url().scheme());
|
||||
+}
|
||||
+
|
||||
bool CheckSecurityForAccessingCodeCacheData(const GURL& resource_url,
|
||||
int render_process_id,
|
||||
Operation operation) {
|
||||
@@ -47,11 +54,12 @@ bool CheckSecurityForAccessingCodeCacheData(const GURL& resource_url,
|
||||
ChildProcessSecurityPolicyImpl::GetInstance()->GetProcessLock(
|
||||
render_process_id);
|
||||
|
||||
- // Code caching is only allowed for http(s) and chrome/chrome-untrusted
|
||||
- // scripts. Furthermore, there is no way for http(s) pages to load chrome or
|
||||
- // chrome-untrusted scripts, so any http(s) page attempting to store data
|
||||
- // about a chrome or chrome-untrusted script would be an indication of
|
||||
- // suspicious activity.
|
||||
+ // Code caching is only allowed for scripts from open-web (http/https and
|
||||
+ // custom schemes registered with url::AddCodeCacheScheme) and
|
||||
+ // chrome/chrome-untrusted schemes. Furthermore, there is no way for
|
||||
+ // open-web pages to load chrome or chrome-untrusted scripts, so any
|
||||
+ // open-web page attempting to store data about a chrome or
|
||||
+ // chrome-untrusted script would be an indication of suspicious activity.
|
||||
if (resource_url.SchemeIs(content::kChromeUIScheme) ||
|
||||
resource_url.SchemeIs(content::kChromeUIUntrustedScheme)) {
|
||||
if (!process_lock.is_locked_to_site()) {
|
||||
@@ -60,9 +68,10 @@ bool CheckSecurityForAccessingCodeCacheData(const GURL& resource_url,
|
||||
return false;
|
||||
}
|
||||
if (process_lock.matches_scheme(url::kHttpScheme) ||
|
||||
- process_lock.matches_scheme(url::kHttpsScheme)) {
|
||||
+ process_lock.matches_scheme(url::kHttpsScheme) ||
|
||||
+ ProcessLockURLIsCodeCacheScheme(process_lock)) {
|
||||
if (operation == Operation::kWrite) {
|
||||
- mojo::ReportBadMessage("HTTP(S) pages cannot cache WebUI code");
|
||||
+ mojo::ReportBadMessage("Open-web pages cannot cache WebUI code");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -72,7 +81,16 @@ bool CheckSecurityForAccessingCodeCacheData(const GURL& resource_url,
|
||||
return process_lock.matches_scheme(content::kChromeUIScheme) ||
|
||||
process_lock.matches_scheme(content::kChromeUIUntrustedScheme);
|
||||
}
|
||||
- if (resource_url.SchemeIsHTTPOrHTTPS()) {
|
||||
+ if (base::Contains(url::GetCodeCacheSchemes(), resource_url.scheme()) &&
|
||||
+ (process_lock.matches_scheme(url::kHttpScheme) ||
|
||||
+ process_lock.matches_scheme(url::kHttpsScheme))) {
|
||||
+ // While custom schemes registered with url::AddCodeCacheScheme are
|
||||
+ // considered as open-web pages, we still do not trust http(s) pages
|
||||
+ // loading resources from custom schemes.
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (resource_url.SchemeIsHTTPOrHTTPS() ||
|
||||
+ base::Contains(url::GetCodeCacheSchemes(), resource_url.scheme())) {
|
||||
if (process_lock.matches_scheme(content::kChromeUIScheme) ||
|
||||
process_lock.matches_scheme(content::kChromeUIUntrustedScheme)) {
|
||||
// It is possible for WebUI pages to include open-web content, but such
|
||||
@@ -136,15 +154,17 @@ absl::optional<GURL> GetSecondaryKeyForCodeCache(const GURL& resource_url,
|
||||
return absl::nullopt;
|
||||
|
||||
// Case 3: process_lock_url is used to enfore site-isolation in code caches.
|
||||
- // Http/https/chrome schemes are safe to be used as a secondary key. Other
|
||||
- // schemes could be enabled if they are known to be safe and if it is
|
||||
- // required to cache code from those origins.
|
||||
+ // Code cache enabled schemes (http/https/chrome/chrome-untrusted and custom
|
||||
+ // schemes registered with url::AddCodeCacheScheme) are safe to be used as a
|
||||
+ // secondary key. Other schemes could be enabled if they are known to be safe
|
||||
+ // and if it is required to cache code from those origins.
|
||||
//
|
||||
// file:// URLs will have a "file:" process lock and would thus share a
|
||||
// cache across all file:// URLs. That would likely be ok for security, but
|
||||
// since this case is not performance sensitive we will keep things simple and
|
||||
- // limit the cache to http/https/chrome/chrome-untrusted processes.
|
||||
- if (process_lock.matches_scheme(url::kHttpScheme) ||
|
||||
+ // limit the cache to processes of code cache enabled schemes.
|
||||
+ if (ProcessLockURLIsCodeCacheScheme(process_lock) ||
|
||||
+ process_lock.matches_scheme(url::kHttpScheme) ||
|
||||
process_lock.matches_scheme(url::kHttpsScheme) ||
|
||||
process_lock.matches_scheme(content::kChromeUIScheme) ||
|
||||
process_lock.matches_scheme(content::kChromeUIUntrustedScheme)) {
|
||||
diff --git a/content/common/url_schemes.cc b/content/common/url_schemes.cc
|
||||
index ce9644d33fe83379127b01bf9a2b1c4badc3bc7c..532b14e013b9b65ba390f09e8bb8934bb278a0d8 100644
|
||||
--- a/content/common/url_schemes.cc
|
||||
+++ b/content/common/url_schemes.cc
|
||||
@@ -98,6 +98,9 @@ void RegisterContentSchemes(bool should_lock_registry) {
|
||||
for (auto& scheme : schemes.empty_document_schemes)
|
||||
url::AddEmptyDocumentScheme(scheme.c_str());
|
||||
|
||||
+ for (auto& scheme : schemes.code_cache_schemes)
|
||||
+ url::AddCodeCacheScheme(scheme.c_str());
|
||||
+
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
if (schemes.allow_non_standard_schemes_in_origins)
|
||||
url::EnableNonStandardSchemesForAndroidWebView();
|
||||
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h
|
||||
index 26bf98bc78b3a02dedf0b46b7c44d135507cb2d3..095582e753fe7b5012eaab7ade16a317aea20277 100644
|
||||
--- a/content/public/common/content_client.h
|
||||
+++ b/content/public/common/content_client.h
|
||||
@@ -139,6 +139,9 @@ class CONTENT_EXPORT ContentClient {
|
||||
// Registers a URL scheme as strictly empty documents, allowing them to
|
||||
// commit synchronously.
|
||||
std::vector<std::string> empty_document_schemes;
|
||||
+ // Registers a URL scheme whose js and wasm scripts have V8 code cache
|
||||
+ // enabled.
|
||||
+ std::vector<std::string> code_cache_schemes;
|
||||
// Registers a URL scheme as extension scheme.
|
||||
std::vector<std::string> extension_schemes;
|
||||
// Registers a URL scheme with a predefined default custom handler.
|
||||
diff --git a/url/url_util.cc b/url/url_util.cc
|
||||
index 001c50e72fd244a40f5629a2a26324bad4bbd300..4ad52f3faa1f67fc1f4047c6e1118c02d792402b 100644
|
||||
--- a/url/url_util.cc
|
||||
+++ b/url/url_util.cc
|
||||
@@ -114,6 +114,9 @@ struct SchemeRegistry {
|
||||
kAboutScheme,
|
||||
};
|
||||
|
||||
+ // Embedder schemes that have V8 code cache enabled in js and wasm scripts.
|
||||
+ std::vector<std::string> code_cache_schemes = {};
|
||||
+
|
||||
// Schemes with a predefined default custom handler.
|
||||
std::vector<SchemeWithHandler> predefined_handler_schemes;
|
||||
|
||||
@@ -673,6 +676,15 @@ const std::vector<std::string>& GetEmptyDocumentSchemes() {
|
||||
return GetSchemeRegistry().empty_document_schemes;
|
||||
}
|
||||
|
||||
+void AddCodeCacheScheme(const char* new_scheme) {
|
||||
+ DoAddScheme(new_scheme,
|
||||
+ &GetSchemeRegistryWithoutLocking()->code_cache_schemes);
|
||||
+}
|
||||
+
|
||||
+const std::vector<std::string>& GetCodeCacheSchemes() {
|
||||
+ return GetSchemeRegistry().code_cache_schemes;
|
||||
+}
|
||||
+
|
||||
void AddPredefinedHandlerScheme(const char* new_scheme, const char* handler) {
|
||||
DoAddSchemeWithHandler(
|
||||
new_scheme, handler,
|
||||
diff --git a/url/url_util.h b/url/url_util.h
|
||||
index 670552a8ce12ad50d7777a0fc52ca42f2aebbd99..14f09ecdbf6dfd63e0c7208ec7c74dd4a32f885d 100644
|
||||
--- a/url/url_util.h
|
||||
+++ b/url/url_util.h
|
||||
@@ -115,6 +115,15 @@ COMPONENT_EXPORT(URL) const std::vector<std::string>& GetCSPBypassingSchemes();
|
||||
COMPONENT_EXPORT(URL) void AddEmptyDocumentScheme(const char* new_scheme);
|
||||
COMPONENT_EXPORT(URL) const std::vector<std::string>& GetEmptyDocumentSchemes();
|
||||
|
||||
+// Adds an application-defined scheme to the list of schemes that have V8 code
|
||||
+// cache enabled for the js and wasm scripts.
|
||||
+// The WebUI schemes (chrome/chrome-untrusted) do not belong to this list, as
|
||||
+// they are treated as a separate cache type for security purpose.
|
||||
+// The http(s) schemes do not belong to this list neither, they always have V8
|
||||
+// code cache enabled and can not load scripts from schemes in this list.
|
||||
+COMPONENT_EXPORT(URL) void AddCodeCacheScheme(const char* new_scheme);
|
||||
+COMPONENT_EXPORT(URL) const std::vector<std::string>& GetCodeCacheSchemes();
|
||||
+
|
||||
// Adds a scheme with a predefined default handler.
|
||||
//
|
||||
// This pair of strings must be normalized protocol handler parameters as
|
||||
@@ -0,0 +1,106 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: John Stiles <johnstiles@google.com>
|
||||
Date: Thu, 1 Feb 2024 20:40:55 +0000
|
||||
Subject: Fix a crash when a BMP image contains an unnecessary EOF code.
|
||||
|
||||
Previously, this would try to perform color correction on a row
|
||||
one past the end of the image data.
|
||||
|
||||
(cherry picked from commit 4bdd8d61bebbba9fab77fa86a8f66b305995199b)
|
||||
|
||||
Bug: 1521893
|
||||
Change-Id: I425437005b9ef400138556705616095857d2cf0d
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5241305
|
||||
Auto-Submit: John Stiles <johnstiles@google.com>
|
||||
Commit-Queue: John Stiles <johnstiles@google.com>
|
||||
Reviewed-by: Peter Kasting <pkasting@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1253633}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5259699
|
||||
Commit-Queue: Peter Kasting <pkasting@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1915}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/blink_platform_unittests_bundle_data.filelist b/third_party/blink/renderer/platform/blink_platform_unittests_bundle_data.filelist
|
||||
index 42d0414da143f509a89551c8b09762949f8011c2..49e238e38fef374c698fcdc1d4b50d4ed7670c3d 100644
|
||||
--- a/third_party/blink/renderer/platform/blink_platform_unittests_bundle_data.filelist
|
||||
+++ b/third_party/blink/renderer/platform/blink_platform_unittests_bundle_data.filelist
|
||||
@@ -403,6 +403,7 @@
|
||||
../../web_tests/images/resources/truncated.webp
|
||||
../../web_tests/images/resources/truncated2.webp
|
||||
../../web_tests/images/resources/twitter_favicon.ico
|
||||
+../../web_tests/images/resources/unnecessary-eof.bmp
|
||||
../../web_tests/images/resources/webp-animated-icc-xmp.webp
|
||||
../../web_tests/images/resources/webp-animated-large.webp
|
||||
../../web_tests/images/resources/webp-animated-no-blend.webp
|
||||
diff --git a/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_decoder_test.cc b/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_decoder_test.cc
|
||||
index 85e3591ac707297944b81cc4673b75d308417bd1..6c867a76a44c57ae818e7a00df30d046077b4d4c 100644
|
||||
--- a/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_decoder_test.cc
|
||||
+++ b/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_decoder_test.cc
|
||||
@@ -98,6 +98,19 @@ TEST(BMPImageDecoderTest, crbug752898) {
|
||||
decoder->DecodeFrameBufferAtIndex(0);
|
||||
}
|
||||
|
||||
+// Verify that decoding an image with an unnecessary EOF marker does not crash.
|
||||
+TEST(BMPImageDecoderTest, allowEOFWhenPastEndOfImage) {
|
||||
+ static constexpr char kBmpFile[] = "/images/resources/unnecessary-eof.bmp";
|
||||
+ scoped_refptr<SharedBuffer> data = ReadFile(kBmpFile);
|
||||
+ ASSERT_TRUE(data.get());
|
||||
+
|
||||
+ std::unique_ptr<ImageDecoder> decoder = CreateBMPDecoder();
|
||||
+ decoder->SetData(data.get(), true);
|
||||
+ ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(0);
|
||||
+ EXPECT_EQ(ImageFrame::kFrameComplete, frame->GetStatus());
|
||||
+ EXPECT_FALSE(decoder->Failed());
|
||||
+}
|
||||
+
|
||||
class BMPImageDecoderCorpusTest : public ImageDecoderBaseTest {
|
||||
public:
|
||||
BMPImageDecoderCorpusTest() : ImageDecoderBaseTest("bmp") {}
|
||||
diff --git a/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc b/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc
|
||||
index 6b6bcb2e8fce05062e80b84283fd635f9d4bf008..b7bbbf51a1b419d1641db5e2f062cfefb2eae554 100644
|
||||
--- a/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc
|
||||
+++ b/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc
|
||||
@@ -886,7 +886,8 @@ BMPImageReader::ProcessingResult BMPImageReader::ProcessRLEData() {
|
||||
// the image.
|
||||
const uint8_t count = ReadUint8(0);
|
||||
const uint8_t code = ReadUint8(1);
|
||||
- if ((count || (code != 1)) && PastEndOfImage(0)) {
|
||||
+ const bool is_past_end_of_image = PastEndOfImage(0);
|
||||
+ if ((count || (code != 1)) && is_past_end_of_image) {
|
||||
return kFailure;
|
||||
}
|
||||
|
||||
@@ -911,7 +912,9 @@ BMPImageReader::ProcessingResult BMPImageReader::ProcessRLEData() {
|
||||
: (coord_.y() > 0))) {
|
||||
buffer_->SetHasAlpha(true);
|
||||
}
|
||||
- ColorCorrectCurrentRow();
|
||||
+ if (!is_past_end_of_image) {
|
||||
+ ColorCorrectCurrentRow();
|
||||
+ }
|
||||
// There's no need to move |coord_| here to trigger the caller
|
||||
// to call SetPixelsChanged(). If the only thing that's changed
|
||||
// is the alpha state, that will be properly written into the
|
||||
@@ -1136,6 +1139,13 @@ void BMPImageReader::ColorCorrectCurrentRow() {
|
||||
if (!transform) {
|
||||
return;
|
||||
}
|
||||
+ int decoder_width = parent_->Size().width();
|
||||
+ // Enforce 0 ≤ current row < bitmap height.
|
||||
+ CHECK_GE(coord_.y(), 0);
|
||||
+ CHECK_LT(coord_.y(), buffer_->Bitmap().height());
|
||||
+ // Enforce decoder width == bitmap width exactly. (The bitmap rowbytes might
|
||||
+ // add a bit of padding, but we are only converting one row at a time.)
|
||||
+ CHECK_EQ(decoder_width, buffer_->Bitmap().width());
|
||||
ImageFrame::PixelData* const row = buffer_->GetAddr(0, coord_.y());
|
||||
const skcms_PixelFormat fmt = XformColorFormat();
|
||||
const skcms_AlphaFormat alpha =
|
||||
@@ -1144,7 +1154,7 @@ void BMPImageReader::ColorCorrectCurrentRow() {
|
||||
: skcms_AlphaFormat_Unpremul;
|
||||
const bool success =
|
||||
skcms_Transform(row, fmt, alpha, transform->SrcProfile(), row, fmt, alpha,
|
||||
- transform->DstProfile(), parent_->Size().width());
|
||||
+ transform->DstProfile(), decoder_width);
|
||||
DCHECK(success);
|
||||
buffer_->SetPixelsChanged(true);
|
||||
}
|
||||
@@ -1,19 +1,23 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: clavin <clavin@electronjs.org>
|
||||
Date: Wed, 30 Aug 2023 18:15:36 -0700
|
||||
Date: Mon, 11 Dec 2023 20:43:34 -0300
|
||||
Subject: fix: activate background material on windows
|
||||
|
||||
This patch adds a condition to the HWND message handler to allow windows
|
||||
with translucent background materials to become activated.
|
||||
|
||||
It also ensures the lParam of WM_NCACTIVATE is set to -1 so as to not repaint
|
||||
the client area, which can lead to a title bar incorrectly being displayed in
|
||||
frameless windows.
|
||||
|
||||
This patch likely can't be upstreamed as-is, as Chromium doesn't have
|
||||
this use case in mind currently.
|
||||
|
||||
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
|
||||
index 13268bd89c710690eed5296f4b2157e9476f195e..37de479e95d49f4d2b1d8164c9e3f6a7bcd82612 100644
|
||||
index 13268bd89c710690eed5296f4b2157e9476f195e..0491dc500896a9ce0c8ad95ada6a175c9e94f3d3 100644
|
||||
--- a/ui/views/win/hwnd_message_handler.cc
|
||||
+++ b/ui/views/win/hwnd_message_handler.cc
|
||||
@@ -1094,7 +1094,7 @@ void HWNDMessageHandler::FrameTypeChanged() {
|
||||
@@ -1094,13 +1094,13 @@ void HWNDMessageHandler::FrameTypeChanged() {
|
||||
|
||||
void HWNDMessageHandler::PaintAsActiveChanged() {
|
||||
if (!delegate_->HasNonClientView() || !delegate_->CanActivate() ||
|
||||
@@ -22,3 +26,34 @@ index 13268bd89c710690eed5296f4b2157e9476f195e..37de479e95d49f4d2b1d8164c9e3f6a7
|
||||
(delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DefWindowProcWithRedrawLock(WM_NCACTIVATE, delegate_->ShouldPaintAsActive(),
|
||||
- 0);
|
||||
+ delegate_->HasFrame() ? 0 : -1);
|
||||
}
|
||||
|
||||
void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon,
|
||||
@@ -2393,17 +2393,18 @@ LRESULT HWNDMessageHandler::OnNCActivate(UINT message,
|
||||
if (IsVisible())
|
||||
delegate_->SchedulePaint();
|
||||
|
||||
- // Calling DefWindowProc is only necessary if there's a system frame being
|
||||
- // drawn. Otherwise it can draw an incorrect title bar and cause visual
|
||||
- // corruption.
|
||||
- if (!delegate_->HasFrame() ||
|
||||
+ // If the window is translucent, it may have the Mica background.
|
||||
+ // In that case, it's necessary to call |DefWindowProc|, but we can
|
||||
+ // pass -1 in the lParam to prevent any non-client area elements from
|
||||
+ // being displayed.
|
||||
+ if ((!delegate_->HasFrame() && !is_translucent_) ||
|
||||
delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN) {
|
||||
SetMsgHandled(TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return DefWindowProcWithRedrawLock(WM_NCACTIVATE, paint_as_active || active,
|
||||
- 0);
|
||||
+ delegate_->HasFrame() ? 0 : -1);
|
||||
}
|
||||
|
||||
LRESULT HWNDMessageHandler::OnNCCalcSize(BOOL mode, LPARAM l_param) {
|
||||
|
||||
279
patches/chromium/fix_font_flooding_in_dev_tools.patch
Normal file
279
patches/chromium/fix_font_flooding_in_dev_tools.patch
Normal file
@@ -0,0 +1,279 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ryan Manuel <ryanm@cypress.io>
|
||||
Date: Wed, 6 Dec 2023 14:38:07 -0600
|
||||
Subject: fix font flooding in dev tools
|
||||
|
||||
Added in this CL: https://chromium-review.googlesource.com/c/chromium/src/+/5033885
|
||||
|
||||
This patch resolves an issue that has been fixed in chromium involving font requests being sent multiple times to DevTools for a single request.
|
||||
|
||||
This patch can be removed when chromium reaches version 121.0.6157.0.
|
||||
|
||||
diff --git a/AUTHORS b/AUTHORS
|
||||
index 6714ac1cf3632138ba1a8f0ebc9f7b428f562449..ac5e5e98f20bcdc98a77426efc091340c3798191 100644
|
||||
--- a/AUTHORS
|
||||
+++ b/AUTHORS
|
||||
@@ -1121,6 +1121,7 @@ Rulong Chen <rulong.crl@alibaba-inc.com>
|
||||
Russell Davis <russell.davis@gmail.com>
|
||||
Ryan Ackley <ryanackley@gmail.com>
|
||||
Ryan Gonzalez <rymg19@gmail.com>
|
||||
+Ryan Manuel <rfmanuel@gmail.com>
|
||||
Ryan Norton <rnorton10@gmail.com>
|
||||
Ryan Sleevi <ryan-chromium-dev@sleevi.com>
|
||||
Ryan Yoakum <ryoakum@skobalt.com>
|
||||
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
|
||||
index f0f31dbd58ceb4507155e1c8f26351e14cb6f5cf..3b4b71d76b2fadaaeb5295a88e088a2388d5d525 100644
|
||||
--- a/third_party/blink/common/features.cc
|
||||
+++ b/third_party/blink/common/features.cc
|
||||
@@ -1851,6 +1851,14 @@ BASE_FEATURE(kUACHOverrideBlank,
|
||||
"UACHOverrideBlank",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
|
||||
+// If enabled, the body of `EmulateLoadStartedForInspector` is executed only
|
||||
+// once per Resource per ResourceFetcher, and thus duplicated network load
|
||||
+// entries in DevTools caused by `EmulateLoadStartedForInspector` are removed.
|
||||
+// https://crbug.com/1502591
|
||||
+BASE_FEATURE(kEmulateLoadStartedForInspectorOncePerResource,
|
||||
+ "kEmulateLoadStartedForInspectorOncePerResource",
|
||||
+ base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
+
|
||||
BASE_FEATURE(kURLSetPortCheckOverflow,
|
||||
"URLSetPortCheckOverflow",
|
||||
base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
|
||||
index b9eb81f257b3f3dfe288987ca853371f4efd300b..5ea3eb74a0a4111b0178c44b1f94f939f5f18857 100644
|
||||
--- a/third_party/blink/public/common/features.h
|
||||
+++ b/third_party/blink/public/common/features.h
|
||||
@@ -1209,6 +1209,9 @@ BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kTimedHTMLParserBudget);
|
||||
|
||||
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kUACHOverrideBlank);
|
||||
|
||||
+BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(
|
||||
+ kEmulateLoadStartedForInspectorOncePerResource);
|
||||
+
|
||||
// Disallow setting URL ports with a value that will overflow.
|
||||
// See https://crbug.com/1416017
|
||||
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kURLSetPortCheckOverflow);
|
||||
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
|
||||
index 5bfbe590f3200c8bdbd357347819bff1ba4e65e1..9bf0372aee79ffd62a475f9d9076b10e49634dba 100644
|
||||
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
|
||||
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
|
||||
@@ -755,6 +755,19 @@ Resource* ResourceFetcher::CachedResource(const KURL& resource_url) const {
|
||||
return it->value.Get();
|
||||
}
|
||||
|
||||
+bool ResourceFetcher::ResourceHasBeenEmulatedLoadStartedForInspector(
|
||||
+ const KURL& resource_url) const {
|
||||
+ if (resource_url.IsEmpty()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ KURL url = MemoryCache::RemoveFragmentIdentifierIfNeeded(resource_url);
|
||||
+ const auto it = emulated_load_started_for_inspector_resources_map_.find(url);
|
||||
+ if (it == emulated_load_started_for_inspector_resources_map_.end()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
const HeapHashSet<Member<Resource>>
|
||||
ResourceFetcher::MoveResourceStrongReferences() {
|
||||
document_resource_strong_refs_total_size_ = 0;
|
||||
@@ -2650,11 +2663,25 @@ void ResourceFetcher::EmulateLoadStartedForInspector(
|
||||
if (CachedResource(url)) {
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ if (ResourceHasBeenEmulatedLoadStartedForInspector(url)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (resource->ErrorOccurred()) {
|
||||
// We should ideally replay the error steps, but we cannot.
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (base::FeatureList::IsEnabled(
|
||||
+ features::kEmulateLoadStartedForInspectorOncePerResource)) {
|
||||
+ // Update the emulated load started for inspector resources map with the
|
||||
+ // resource so that future emulations of the same resource won't happen.
|
||||
+ String resource_url = MemoryCache::RemoveFragmentIdentifierIfNeeded(url);
|
||||
+ emulated_load_started_for_inspector_resources_map_.Set(resource_url,
|
||||
+ resource);
|
||||
+ }
|
||||
+
|
||||
ResourceRequest resource_request(url);
|
||||
resource_request.SetRequestContext(request_context);
|
||||
resource_request.SetRequestDestination(request_destination);
|
||||
@@ -2944,6 +2971,7 @@ void ResourceFetcher::Trace(Visitor* visitor) const {
|
||||
visitor->Trace(loaders_);
|
||||
visitor->Trace(non_blocking_loaders_);
|
||||
visitor->Trace(cached_resources_map_);
|
||||
+ visitor->Trace(emulated_load_started_for_inspector_resources_map_);
|
||||
visitor->Trace(image_resources_);
|
||||
visitor->Trace(not_loaded_image_resources_);
|
||||
visitor->Trace(preloads_);
|
||||
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
|
||||
index c437d854203b419091a15bac36e6292646af28e4..455b6676131fb9454afe140a5d0915fc27288565 100644
|
||||
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
|
||||
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
|
||||
@@ -179,6 +179,7 @@ class PLATFORM_EXPORT ResourceFetcher
|
||||
std::unique_ptr<WebCodeCacheLoader> CreateCodeCacheLoader();
|
||||
|
||||
Resource* CachedResource(const KURL&) const;
|
||||
+ bool ResourceHasBeenEmulatedLoadStartedForInspector(const KURL&) const;
|
||||
|
||||
// Registers an callback to be called with the resource priority of the fetch
|
||||
// made to the specified URL. When `new_load_only` is set to false,
|
||||
@@ -563,6 +564,15 @@ class PLATFORM_EXPORT ResourceFetcher
|
||||
// Weak reference to all the fetched resources.
|
||||
DocumentResourceMap cached_resources_map_;
|
||||
|
||||
+ // When a resource is in the global memory cache but not in the
|
||||
+ // cached_resources_map_ and it is referenced (e.g. when the StyleEngine
|
||||
+ // processes a @font-face rule), the resource will be emulated via
|
||||
+ // `EmulateLoadStartedForInspector` so that it shows up in DevTools.
|
||||
+ // In order to ensure that this only occurs once per resource, we keep
|
||||
+ // a weak reference to all emulated resources and only emulate resources
|
||||
+ // that have not been previously emulated.
|
||||
+ DocumentResourceMap emulated_load_started_for_inspector_resources_map_;
|
||||
+
|
||||
// document_resource_strong_refs_ keeps strong references for fonts, images,
|
||||
// scripts and stylesheets within their freshness lifetime.
|
||||
HeapHashSet<Member<Resource>> document_resource_strong_refs_;
|
||||
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
|
||||
index ef0ff8fa688eb30f88dff855964ff6aabce70790..d32a89f8db9eeec03494271d2193e7200802710f 100644
|
||||
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
|
||||
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
|
||||
@@ -160,6 +160,8 @@ class ResourceFetcherTest : public testing::Test {
|
||||
return request_;
|
||||
}
|
||||
|
||||
+ void ClearLastRequest() { request_ = absl::nullopt; }
|
||||
+
|
||||
private:
|
||||
absl::optional<PartialResourceRequest> request_;
|
||||
};
|
||||
@@ -1653,4 +1655,123 @@ TEST_F(ResourceFetcherTest, StrongReferenceThreshold) {
|
||||
ASSERT_FALSE(perform_fetch.Run(KURL("http://127.0.0.1:8000/baz.png")));
|
||||
}
|
||||
|
||||
+TEST_F(ResourceFetcherTest,
|
||||
+ EmulateLoadStartedForInspectorOncePerResourceDisabled) {
|
||||
+ base::test::ScopedFeatureList scoped_feature_list;
|
||||
+ scoped_feature_list.InitAndDisableFeature(
|
||||
+ features::kEmulateLoadStartedForInspectorOncePerResource);
|
||||
+ auto* observer = MakeGarbageCollected<TestResourceLoadObserver>();
|
||||
+
|
||||
+ // Set up the initial fetcher and mark the resource as cached.
|
||||
+ auto* fetcher = CreateFetcher();
|
||||
+ KURL url("http://127.0.0.1:8000/foo.woff2");
|
||||
+ RegisterMockedURLLoad(url);
|
||||
+ FetchParameters fetch_params =
|
||||
+ FetchParameters::CreateForTest(ResourceRequest(url));
|
||||
+ Resource* resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
|
||||
+ resource->SetStatus(ResourceStatus::kCached);
|
||||
+
|
||||
+ ASSERT_NE(fetcher->CachedResource(url), nullptr);
|
||||
+ ASSERT_FALSE(fetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
|
||||
+
|
||||
+ // Set up the second fetcher.
|
||||
+ auto* otherContextFetcher = CreateFetcher();
|
||||
+ otherContextFetcher->SetResourceLoadObserver(observer);
|
||||
+
|
||||
+ // Ensure that the url is initially not marked as cached or
|
||||
+ // emulated and the observer's last request is empty.
|
||||
+ ASSERT_EQ(otherContextFetcher->CachedResource(url), nullptr);
|
||||
+ ASSERT_FALSE(
|
||||
+ otherContextFetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
|
||||
+ ASSERT_EQ(observer->GetLastRequest(), absl::nullopt);
|
||||
+
|
||||
+ otherContextFetcher->EmulateLoadStartedForInspector(
|
||||
+ resource, url, mojom::blink::RequestContextType::FONT,
|
||||
+ network::mojom::RequestDestination::kFont,
|
||||
+ fetch_initiator_type_names::kCSS);
|
||||
+
|
||||
+ // After the first emulation, ensure that the url is not cached,
|
||||
+ // is not marked as emulated and the observer's last
|
||||
+ // request is not empty with the feature disabled.
|
||||
+ ASSERT_EQ(otherContextFetcher->CachedResource(url), nullptr);
|
||||
+ ASSERT_FALSE(
|
||||
+ otherContextFetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
|
||||
+ ASSERT_NE(observer->GetLastRequest(), absl::nullopt);
|
||||
+
|
||||
+ // Clear out the last request to start fresh
|
||||
+ observer->ClearLastRequest();
|
||||
+
|
||||
+ otherContextFetcher->EmulateLoadStartedForInspector(
|
||||
+ resource, url, mojom::blink::RequestContextType::FONT,
|
||||
+ network::mojom::RequestDestination::kFont,
|
||||
+ fetch_initiator_type_names::kCSS);
|
||||
+
|
||||
+ // After the second emulation, ensure that the url is not cached,
|
||||
+ // the resource is not marked as emulated, and the observer's last
|
||||
+ // request is not empty with the feature disabled. This means that
|
||||
+ // the observer was notified with this emulation.
|
||||
+ ASSERT_EQ(otherContextFetcher->CachedResource(url), nullptr);
|
||||
+ ASSERT_FALSE(
|
||||
+ otherContextFetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
|
||||
+ ASSERT_NE(observer->GetLastRequest(), absl::nullopt);
|
||||
+}
|
||||
+
|
||||
+TEST_F(ResourceFetcherTest,
|
||||
+ EmulateLoadStartedForInspectorOncePerResourceEnabled) {
|
||||
+ auto* observer = MakeGarbageCollected<TestResourceLoadObserver>();
|
||||
+
|
||||
+ // Set up the initial fetcher and mark the resource as cached.
|
||||
+ auto* fetcher = CreateFetcher();
|
||||
+ KURL url("http://127.0.0.1:8000/foo.woff2");
|
||||
+ RegisterMockedURLLoad(url);
|
||||
+ FetchParameters fetch_params =
|
||||
+ FetchParameters::CreateForTest(ResourceRequest(url));
|
||||
+ Resource* resource = MockResource::Fetch(fetch_params, fetcher, nullptr);
|
||||
+ resource->SetStatus(ResourceStatus::kCached);
|
||||
+
|
||||
+ ASSERT_NE(fetcher->CachedResource(url), nullptr);
|
||||
+ ASSERT_FALSE(fetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
|
||||
+
|
||||
+ // Set up the second fetcher.
|
||||
+ auto* otherContextFetcher = CreateFetcher();
|
||||
+ otherContextFetcher->SetResourceLoadObserver(observer);
|
||||
+
|
||||
+ // Ensure that the url is initially not cached, not marked as emulated,
|
||||
+ // and the observer's last request is empty.
|
||||
+ ASSERT_EQ(otherContextFetcher->CachedResource(url), nullptr);
|
||||
+ ASSERT_FALSE(
|
||||
+ otherContextFetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
|
||||
+ ASSERT_EQ(observer->GetLastRequest(), absl::nullopt);
|
||||
+
|
||||
+ otherContextFetcher->EmulateLoadStartedForInspector(
|
||||
+ resource, url, mojom::blink::RequestContextType::FONT,
|
||||
+ network::mojom::RequestDestination::kFont,
|
||||
+ fetch_initiator_type_names::kCSS);
|
||||
+
|
||||
+ // After the first emulation, ensure that the url is not cached,
|
||||
+ // marked as emulated, and the observer's last request is not empty with
|
||||
+ // the feature enabled.
|
||||
+ ASSERT_EQ(otherContextFetcher->CachedResource(url), nullptr);
|
||||
+ ASSERT_TRUE(
|
||||
+ otherContextFetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
|
||||
+ ASSERT_NE(observer->GetLastRequest(), absl::nullopt);
|
||||
+
|
||||
+ // Clear out the last request to start fresh
|
||||
+ observer->ClearLastRequest();
|
||||
+
|
||||
+ otherContextFetcher->EmulateLoadStartedForInspector(
|
||||
+ resource, url, mojom::blink::RequestContextType::FONT,
|
||||
+ network::mojom::RequestDestination::kFont,
|
||||
+ fetch_initiator_type_names::kCSS);
|
||||
+
|
||||
+ // After the first emulation, ensure that the url is not cached,
|
||||
+ // marked as emulated, and the observer's last request is empty with
|
||||
+ // the feature enabled. This means that the observer was not
|
||||
+ // notified with this emulation.
|
||||
+ ASSERT_EQ(otherContextFetcher->CachedResource(url), nullptr);
|
||||
+ ASSERT_TRUE(
|
||||
+ otherContextFetcher->ResourceHasBeenEmulatedLoadStartedForInspector(url));
|
||||
+ ASSERT_EQ(observer->GetLastRequest(), absl::nullopt);
|
||||
+}
|
||||
+
|
||||
} // namespace blink
|
||||
@@ -3,47 +3,89 @@ 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 b190c86708d5ae7f207bae3e923609814bf68a52..16395c4b5fd5262885118095784db820508087dd 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
|
||||
@@ -1041,6 +1041,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 ee2b3bc3aabf7f5a8e3d2ad57675537f21aafaa6..52235e8022e6122fbf0293b1653b62ee9551e889 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
@@ -2942,6 +2942,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 648896b13ad4f811fdd196bd2fe5bdf62e7154ab..e2e3b414e73052b2b5b8e443ded18ae3f18fd916 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 a50b68d69a80d05e154f0a49dfe0fd36e4a313ec..05334f6d53ccdd35e1262a16cbbbff8f67c3c500 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 e2e7b3e5cf8f581adee596903fc19886a23832c1..dd060f4207516af6b7db21593dcbed3848d47409 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
|
||||
@@ -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 935dbb05a5021ffb80737e2f8e5497e887235946..6d920c33562de8d2bf11ae74101cf7ab1e929f5e 100644
|
||||
--- a/cc/paint/paint_op_reader.cc
|
||||
+++ b/cc/paint/paint_op_reader.cc
|
||||
@@ -1532,9 +1532,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,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Peter=20Bostr=C3=B6m?= <pbos@chromium.org>
|
||||
Date: Thu, 1 Feb 2024 21:24:43 +0000
|
||||
Subject: Fix racy iterator use in Node::AddConnection
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Before this fix an iterator to `connections_` which requires a lock
|
||||
would be dereferenced outside an unlock operation because the `it` taken
|
||||
from the map isn't understood as guarded by the same lock.
|
||||
|
||||
This takes a Ref<NodeLink> before unlocking which'll keep the link
|
||||
reference alive even if `connections_` is concurrently modified and the
|
||||
entry removed (or replaced).
|
||||
|
||||
(cherry picked from commit 1f2cbf5833d7f00d3fcbfd1f3ef0c1aff10c04cd)
|
||||
|
||||
Bug: 1523704
|
||||
Change-Id: I6f6fe4e34ec2c8268d4e7f33965a13e3b10f9f92
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5254025
|
||||
Commit-Queue: Peter Boström <pbos@chromium.org>
|
||||
Reviewed-by: Ken Rockot <rockot@google.com>
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Auto-Submit: Peter Boström <pbos@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1254709}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5260163
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1916}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/third_party/ipcz/src/ipcz/node.cc b/third_party/ipcz/src/ipcz/node.cc
|
||||
index a7162f9017d86d3ab3369d04add98527189dd33f..3a8eef652cc3381b608d89cfb6acd006d4ba378b 100644
|
||||
--- a/third_party/ipcz/src/ipcz/node.cc
|
||||
+++ b/third_party/ipcz/src/ipcz/node.cc
|
||||
@@ -168,9 +168,10 @@ bool Node::AddConnection(const NodeName& remote_node_name,
|
||||
// handling an incoming NodeConnector message, we can err on the side of
|
||||
// caution (i.e. less re-entrancy in event handlers) by treating every
|
||||
// case like an API call.
|
||||
+ const Ref<NodeLink> link = it->second.link;
|
||||
mutex_.Unlock();
|
||||
const OperationContext context{OperationContext::kAPICall};
|
||||
- DropConnection(context, *it->second.link);
|
||||
+ DropConnection(context, *link);
|
||||
mutex_.Lock();
|
||||
}
|
||||
|
||||
87
patches/chromium/m120_ipcz_fix_a_few_weak_asserts.patch
Normal file
87
patches/chromium/m120_ipcz_fix_a_few_weak_asserts.patch
Normal file
@@ -0,0 +1,87 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Rockot <rockot@google.com>
|
||||
Date: Tue, 30 Jan 2024 21:36:01 +0000
|
||||
Subject: ipcz: Fix a few weak asserts
|
||||
|
||||
DriverMemory cloning should not weakly assert success, as it can fail in
|
||||
real production scenarios. Now Clone() will return an invalid
|
||||
DriverMemory object if it fails to duplicate the internal handle.
|
||||
Existing callers of Clone() are already durable to an invalid output, so
|
||||
this change results in graceful failures instead of undefined behavior.
|
||||
|
||||
This also replaces some weak asserts in DriverTransport creation with
|
||||
hardening asserts. We may want to fail more gracefully if these end
|
||||
up crashing a lot, but it seems unlikely.
|
||||
|
||||
(cherry picked from commit 4bd18c5a3a7a935716bbed197fba6d45a1122894)
|
||||
|
||||
Fixed: 1521571
|
||||
Change-Id: Id764b33ead8bbba58e61b3270920c839479eaa4a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5240312
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Reviewed-by: Alex Gough <ajgo@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1252882}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5250958
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Auto-Submit: Ken Rockot <rockot@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/6099@{#1905}
|
||||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||||
|
||||
diff --git a/third_party/ipcz/src/ipcz/driver_memory.cc b/third_party/ipcz/src/ipcz/driver_memory.cc
|
||||
index f8761985b78409fdb5420456661b0d227030cc8f..3bdc3aaf52d166a7691b5f28ebc86cc47600f7cc 100644
|
||||
--- a/third_party/ipcz/src/ipcz/driver_memory.cc
|
||||
+++ b/third_party/ipcz/src/ipcz/driver_memory.cc
|
||||
@@ -30,10 +30,11 @@ DriverMemory::DriverMemory(const IpczDriver& driver, size_t num_bytes)
|
||||
: size_(num_bytes) {
|
||||
ABSL_ASSERT(num_bytes > 0);
|
||||
IpczDriverHandle handle;
|
||||
- IpczResult result =
|
||||
+ const IpczResult result =
|
||||
driver.AllocateSharedMemory(num_bytes, IPCZ_NO_FLAGS, nullptr, &handle);
|
||||
- ABSL_ASSERT(result == IPCZ_RESULT_OK);
|
||||
- memory_ = DriverObject(driver, handle);
|
||||
+ if (result == IPCZ_RESULT_OK) {
|
||||
+ memory_ = DriverObject(driver, handle);
|
||||
+ }
|
||||
}
|
||||
|
||||
DriverMemory::DriverMemory(DriverMemory&& other) = default;
|
||||
@@ -43,12 +44,14 @@ DriverMemory& DriverMemory::operator=(DriverMemory&& other) = default;
|
||||
DriverMemory::~DriverMemory() = default;
|
||||
|
||||
DriverMemory DriverMemory::Clone() {
|
||||
- ABSL_ASSERT(is_valid());
|
||||
+ ABSL_HARDENING_ASSERT(is_valid());
|
||||
|
||||
IpczDriverHandle handle;
|
||||
- IpczResult result = memory_.driver()->DuplicateSharedMemory(
|
||||
+ const IpczResult result = memory_.driver()->DuplicateSharedMemory(
|
||||
memory_.handle(), 0, nullptr, &handle);
|
||||
- ABSL_ASSERT(result == IPCZ_RESULT_OK);
|
||||
+ if (result != IPCZ_RESULT_OK) {
|
||||
+ return DriverMemory();
|
||||
+ }
|
||||
|
||||
return DriverMemory(DriverObject(*memory_.driver(), handle));
|
||||
}
|
||||
diff --git a/third_party/ipcz/src/ipcz/driver_transport.cc b/third_party/ipcz/src/ipcz/driver_transport.cc
|
||||
index 096f1b3bed3cfbe0074b074edba21bcfceacd897..dbeb69a0a881a82c9360118a017942ec6eb920f8 100644
|
||||
--- a/third_party/ipcz/src/ipcz/driver_transport.cc
|
||||
+++ b/third_party/ipcz/src/ipcz/driver_transport.cc
|
||||
@@ -68,14 +68,14 @@ DriverTransport::Pair DriverTransport::CreatePair(
|
||||
IpczDriverHandle target_transport0 = IPCZ_INVALID_DRIVER_HANDLE;
|
||||
IpczDriverHandle target_transport1 = IPCZ_INVALID_DRIVER_HANDLE;
|
||||
if (transport0) {
|
||||
- ABSL_ASSERT(transport1);
|
||||
+ ABSL_HARDENING_ASSERT(transport1);
|
||||
target_transport0 = transport0->driver_object().handle();
|
||||
target_transport1 = transport1->driver_object().handle();
|
||||
}
|
||||
IpczResult result = driver.CreateTransports(
|
||||
target_transport0, target_transport1, IPCZ_NO_FLAGS, nullptr,
|
||||
&new_transport0, &new_transport1);
|
||||
- ABSL_ASSERT(result == IPCZ_RESULT_OK);
|
||||
+ ABSL_HARDENING_ASSERT(result == IPCZ_RESULT_OK);
|
||||
auto first =
|
||||
MakeRefCounted<DriverTransport>(DriverObject(driver, new_transport0));
|
||||
auto second =
|
||||
@@ -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 f3e311972eb41e768c905a451ef576706434eeec..17ffbdf2734a788ffbaab9df50fda68b56e91c53 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 71f2f933cc3b5a1064637036aed09459f2d1ce89..82cc186ea829ea60582ea0f7056125bc3ff310f3 100644
|
||||
--- a/third_party/libxml/src/xmlreader.c
|
||||
+++ b/third_party/libxml/src/xmlreader.c
|
||||
@@ -1445,6 +1445,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,82 @@
|
||||
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 628b891ecc5eb675d426c83a5ad235839ed7d6c1..0931feefa628af2060cd927666879a3e72ba2959 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'}]);
|
||||
-</script>
|
||||
\ No newline at end of file
|
||||
+ 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 365b18025d5a88af4910bdc4e544210c355c4105..eb7a2c50118f6515b2984c7f0a9fadabd9a5f16e 100644
|
||||
--- a/third_party/blink/renderer/modules/webcodecs/video_frame.cc
|
||||
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
|
||||
@@ -79,6 +79,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:
|
||||
@@ -1131,9 +1136,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) {
|
||||
@@ -0,0 +1,66 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Rebekah Potter <rbpotter@chromium.org>
|
||||
Date: Fri, 15 Dec 2023 19:23:42 +0000
|
||||
Subject: Reland mojom_ts_generator: Handle empty module path identically to
|
||||
'/'
|
||||
|
||||
Reason for revert: Original change was reverted incorrectly.
|
||||
|
||||
Original change's description:
|
||||
> Revert "mojom_ts_generator: Handle empty module path identically to '/'"
|
||||
>
|
||||
> This reverts commit 4d1f1115f0f70c7ff4493f64221fdf15810c5005.
|
||||
>
|
||||
> Reason for revert: The tree is down https://ci.chromium.org/ui/p/chromium/builders/ci/Linux%20Chromium%20OS%20ASan%20LSan%20Builder/82276/overview
|
||||
>
|
||||
> Original change's description:
|
||||
> > mojom_ts_generator: Handle empty module path identically to '/'
|
||||
> >
|
||||
> > Fixes an issue with Python 3.11.2. Workaround originally proposed at
|
||||
> > https://bugs.chromium.org/p/chromium/issues/detail?id=1422178#c4
|
||||
> >
|
||||
> > Bug: 1422178
|
||||
> > Change-Id: I4f02cbd4a0aafbab1a7fef8a36d812f1621c75e4
|
||||
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5121571
|
||||
> > Reviewed-by: Demetrios Papadopoulos <dpapad@chromium.org>
|
||||
> > Commit-Queue: Rebekah Potter <rbpotter@chromium.org>
|
||||
> > Cr-Commit-Position: refs/heads/main@{#1237792}
|
||||
>
|
||||
> Bug: 1422178
|
||||
> Change-Id: Icb352e5b437deee34100d213bd9c1bc0cedaaaf4
|
||||
> No-Presubmit: true
|
||||
> No-Tree-Checks: true
|
||||
> No-Try: true
|
||||
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5124992
|
||||
> Owners-Override: Shibalik Mohapatra <shibalik@chromium.org>
|
||||
> Commit-Queue: Shibalik Mohapatra <shibalik@chromium.org>
|
||||
> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
> Cr-Commit-Position: refs/heads/main@{#1237835}
|
||||
|
||||
Bug: 1422178
|
||||
Change-Id: I2486fca59de0b28efc38020de8cd3d01a56eca98
|
||||
No-Presubmit: true
|
||||
No-Tree-Checks: true
|
||||
No-Try: true
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5125915
|
||||
Commit-Queue: Demetrios Papadopoulos <dpapad@chromium.org>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/heads/main@{#1238190}
|
||||
|
||||
diff --git a/mojo/public/tools/bindings/generators/mojom_ts_generator.py b/mojo/public/tools/bindings/generators/mojom_ts_generator.py
|
||||
index d8e0cf30486690b5aa33906985642dc8f7f762f5..1c43796152811d020370aa0a42bc4fddf8b05c06 100644
|
||||
--- a/mojo/public/tools/bindings/generators/mojom_ts_generator.py
|
||||
+++ b/mojo/public/tools/bindings/generators/mojom_ts_generator.py
|
||||
@@ -175,8 +175,10 @@ def _GetWebUiModulePath(module):
|
||||
path. Otherwise, returned paths always end in a '/' and begin with either
|
||||
`chrome://resources/` or a '/'."""
|
||||
path = module.metadata.get('webui_module_path')
|
||||
- if path is None or path == '/':
|
||||
- return path
|
||||
+ if path is None:
|
||||
+ return None
|
||||
+ if path == '' or path == '/':
|
||||
+ return '/'
|
||||
if _IsAbsoluteChromeResourcesPath(path):
|
||||
return path.rstrip('/') + '/'
|
||||
return '/{}/'.format(path.strip('/'))
|
||||
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 0ecc7989e7bfa459c80b4fe10705781257dd9b7d..a0293f73810e2077ca53d691d3be3dbbda12faca 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -252,6 +252,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;
|
||||
|
||||
@@ -970,11 +975,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,76 @@
|
||||
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 9edcee3aa81a84cd38bba2660557dfc6f48e380c..bafe29b422506207a11a22f6793c38d6c5fa5a5f 100644
|
||||
--- a/third_party/crashpad/README.chromium
|
||||
+++ b/third_party/crashpad/README.chromium
|
||||
@@ -1,8 +1,8 @@
|
||||
Name: Crashpad
|
||||
Short Name: crashpad
|
||||
URL: https://crashpad.chromium.org/
|
||||
-Version: unknown
|
||||
-Revision: a7cfe95351e301512eb0efc03f92fee63c1c82b2
|
||||
+Version: N/A
|
||||
+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 b7d44b11c3f8eb8275971eb29c5bcca313f70179..f6f7a31963245b47724eb75584033e68c90a90d6 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 192b4cb10add6e3aaa70b96b86bc8ae90b90a070..476ebe019eee87d76a8bceaa885dc58f01c6af62 100644
|
||||
--- a/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc
|
||||
+++ b/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc
|
||||
@@ -97,9 +97,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,19 @@
|
||||
{
|
||||
"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/libavif", "repo": "src/third_party/libavif/src" },
|
||||
{ "patch_dir": "src/electron/patches/angle", "repo": "src/third_party/angle" },
|
||||
{ "patch_dir": "src/electron/patches/sqlite", "repo": "src/third_party/sqlite/src" },
|
||||
{ "patch_dir": "src/electron/patches/libvpx", "repo": "src/third_party/libvpx/source/libvpx" },
|
||||
{ "patch_dir": "src/electron/patches/DirectXShaderCompiler", "repo": "src/third_party/dawn/third_party/dxc" }
|
||||
]
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
fix_expose_globals_to_allow_patching_devtools_dock.patch
|
||||
fix_active_trace_index_when_updating_models.patch
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Wed, 13 Dec 2023 19:14:56 +0900
|
||||
Subject: fix: active trace index when updating models
|
||||
|
||||
https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/4660282 introduced
|
||||
an index variant for tracking current active trace. When trace recording finishes
|
||||
TimelinePanel.loadingComplete will update the active index via TimelinePanel.setModel,
|
||||
however it also installs an event listener for resolving names from the PerformanceModel
|
||||
which eventually calls TimelinePanel.updateModelAndFlameChart and this function updated
|
||||
the models current active trace to default index of -1 leading to broken save functionality.
|
||||
The issue got addressed in M119 and higher via https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/4871439
|
||||
in an unrelated feature CL.
|
||||
|
||||
This patch isolates the change required to address the save functionality and is only needed for M118 branch.
|
||||
|
||||
diff --git a/front_end/panels/timeline/TimelinePanel.ts b/front_end/panels/timeline/TimelinePanel.ts
|
||||
index c10c4d02c716f68b8c6cdcb422bc7fb21a67d923..d5343b73605239b0948fae19570a9a6a8965a89f 100644
|
||||
--- a/front_end/panels/timeline/TimelinePanel.ts
|
||||
+++ b/front_end/panels/timeline/TimelinePanel.ts
|
||||
@@ -1256,7 +1256,7 @@ export class TimelinePanel extends UI.Panel.Panel implements Client, TimelineMod
|
||||
if (!this.performanceModel) {
|
||||
return;
|
||||
}
|
||||
- this.setModel(this.performanceModel);
|
||||
+ this.setModel(this.performanceModel, null, this.#traceEngineActiveTraceIndex);
|
||||
this.flameChart.updateColorMapper();
|
||||
}
|
||||
|
||||
1
patches/dxc/.patches
Normal file
1
patches/dxc/.patches
Normal file
@@ -0,0 +1 @@
|
||||
fix_hlmatrixlowerpass_leaving_call_to_dangling_functionval.patch
|
||||
1
patches/libavif/.patches
Normal file
1
patches/libavif/.patches
Normal file
@@ -0,0 +1 @@
|
||||
do_not_store_colorproperties_until_alpha_item_is_found.patch
|
||||
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Vignesh Venkatasubramanian <vigneshv@google.com>
|
||||
Date: Tue, 28 Nov 2023 08:44:22 -0800
|
||||
Subject: Do not store colorproperties until alpha item is found
|
||||
|
||||
colorProperties could be pointing to a dangling pointer if
|
||||
findAlphaItem() resizes the meta.items array.
|
||||
|
||||
Manual cherry-pick of PR #1808 into the chromium-m118 branch.
|
||||
|
||||
diff --git a/src/read.c b/src/read.c
|
||||
index e3bad9833d665cdf704726ff47fd3b0ad3e8b02a..cf9f2a797c4b996f5b9877774e7848f3006dec54 100644
|
||||
--- a/src/read.c
|
||||
+++ b/src/read.c
|
||||
@@ -3938,7 +3938,6 @@ avifResult avifDecoderReset(avifDecoder * decoder)
|
||||
avifDiagnosticsPrintf(&decoder->diag, "Primary item not found");
|
||||
return AVIF_RESULT_MISSING_IMAGE_ITEM;
|
||||
}
|
||||
- colorProperties = &colorItem->properties;
|
||||
if (!memcmp(colorItem->type, "grid", 4)) {
|
||||
avifROData readData;
|
||||
AVIF_CHECKRES(avifDecoderItemRead(colorItem, decoder->io, &readData, 0, 0, data->diag));
|
||||
@@ -3995,6 +3994,8 @@ avifResult avifDecoderReset(avifDecoder * decoder)
|
||||
}
|
||||
}
|
||||
|
||||
+ colorProperties = &colorItem->properties;
|
||||
+
|
||||
// Find Exif and/or XMP metadata, if any
|
||||
AVIF_CHECKRES(avifDecoderFindMetadata(decoder, data->meta, decoder->image, colorItem->id));
|
||||
|
||||
@@ -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
|
||||
@@ -50,3 +48,4 @@ lib_fix_broadcastchannel_initialization_location.patch
|
||||
fix_handle_possible_disabled_sharedarraybuffer.patch
|
||||
win_process_avoid_assert_after_spawning_store_app_4152.patch
|
||||
fix_avx_detection.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 2e35cbba2ac02494c44821af395fe0195b1ab6b5..f5b6fecf6843a6204ec532a77f39a36d33bf061d 100644
|
||||
index 250a43c5455b4f9ff72dd3a34d5b0aa270f43cc6..31f5d1528c840a2926b59b2b1c82ff265588a37a 100644
|
||||
--- a/lib/internal/process/pre_execution.js
|
||||
+++ b/lib/internal/process/pre_execution.js
|
||||
@@ -149,11 +149,13 @@ function patchProcessObject(expandArgv1) {
|
||||
@@ -144,11 +144,13 @@ function patchProcessObject(expandArgv1) {
|
||||
if (expandArgv1 && process.argv[1] &&
|
||||
!StringPrototypeStartsWith(process.argv[1], '-')) {
|
||||
// Expand process.argv[1] into a full path.
|
||||
|
||||
@@ -11,7 +11,7 @@ trying to see whether or not the lines are greyed out. One possibility
|
||||
would be to upstream a changed test that doesn't hardcode line numbers.
|
||||
|
||||
diff --git a/test/fixtures/errors/force_colors.snapshot b/test/fixtures/errors/force_colors.snapshot
|
||||
index 0334a0b4faa3633aa8617b9538873e7f3540513b..fa9989f55980aeddd3fa944318488c0289e3ab6e 100644
|
||||
index 0334a0b4faa3633aa8617b9538873e7f3540513b..0d503d60931278ff9a7fb41177687688119390a3 100644
|
||||
--- a/test/fixtures/errors/force_colors.snapshot
|
||||
+++ b/test/fixtures/errors/force_colors.snapshot
|
||||
@@ -4,11 +4,12 @@ throw new Error('Should include grayed stack trace')
|
||||
@@ -27,7 +27,7 @@ index 0334a0b4faa3633aa8617b9538873e7f3540513b..fa9989f55980aeddd3fa944318488c02
|
||||
+[90m at Object..js (node:internal*modules*cjs*loader:1326:10)[39m
|
||||
+[90m at Module.load (node:internal*modules*cjs*loader:1126:32)[39m
|
||||
+[90m at node:internal*modules*cjs*loader:967:12[39m
|
||||
+[90m at Function._load (node:electron*js2c*asar_bundle:743:32)[39m
|
||||
+[90m at Function._load (node:electron*js2c*node_init:741:32)[39m
|
||||
+[90m at Function.executeUserEntryPoint [as runMain] (node:internal*modules*run_main:96:12)[39m
|
||||
[90m at node:internal*main*run_main_module:23:47[39m
|
||||
|
||||
|
||||
@@ -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 da553f6556a06d57d7490d74a3b4dd8f0132600c..168a6c72520d6540f0dbf84a62bc5e2b2f3ae022 100644
|
||||
index 59c37b97672d39a9da89ca2b78aa28a77ca78699..319d853a35d9191c64a4f21132306a774acd84e6 100644
|
||||
--- a/lib/child_process.js
|
||||
+++ b/lib/child_process.js
|
||||
@@ -60,6 +60,7 @@ let debug = require('internal/util/debuglog').debuglog(
|
||||
@@ -19,7 +19,7 @@ index da553f6556a06d57d7490d74a3b4dd8f0132600c..168a6c72520d6540f0dbf84a62bc5e2b
|
||||
|
||||
const {
|
||||
AbortError,
|
||||
@@ -163,7 +164,6 @@ function fork(modulePath, args = [], options) {
|
||||
@@ -152,7 +153,6 @@ function fork(modulePath, args = [], options) {
|
||||
ArrayPrototypeSplice(execArgv, index - 1, 2);
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ index da553f6556a06d57d7490d74a3b4dd8f0132600c..168a6c72520d6540f0dbf84a62bc5e2b
|
||||
args = [...execArgv, modulePath, ...args];
|
||||
|
||||
if (typeof options.stdio === 'string') {
|
||||
@@ -625,6 +625,21 @@ function normalizeSpawnArguments(file, args, options) {
|
||||
@@ -614,6 +614,21 @@ function normalizeSpawnArguments(file, args, options) {
|
||||
'options.windowsVerbatimArguments');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,54 +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/policy.js b/lib/internal/process/policy.js
|
||||
index 8e07cb92118c84b2bc1156532cae8b033b9a48f4..2073a024ad548fe80e84cafee012b003454d6c93 100644
|
||||
--- a/lib/internal/process/policy.js
|
||||
+++ b/lib/internal/process/policy.js
|
||||
@@ -39,9 +39,6 @@ module.exports = ObjectFreeze({
|
||||
process.binding = function binding(_module) {
|
||||
throw new ERR_ACCESS_DENIED('process.binding');
|
||||
};
|
||||
- process._linkedBinding = function _linkedBinding(_module) {
|
||||
- throw new ERR_ACCESS_DENIED('process._linkedBinding');
|
||||
- };
|
||||
},
|
||||
|
||||
get manifest() {
|
||||
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
|
||||
index 250a43c5455b4f9ff72dd3a34d5b0aa270f43cc6..2e35cbba2ac02494c44821af395fe0195b1ab6b5 100644
|
||||
--- a/lib/internal/process/pre_execution.js
|
||||
+++ b/lib/internal/process/pre_execution.js
|
||||
@@ -117,12 +117,17 @@ function setupUserModules() {
|
||||
loadPreloadModules();
|
||||
// Need to be done after --require setup.
|
||||
initializeFrozenIntrinsics();
|
||||
+ setupAsarSupport();
|
||||
}
|
||||
|
||||
function refreshRuntimeOptions() {
|
||||
refreshOptions();
|
||||
}
|
||||
|
||||
+function setupAsarSupport() {
|
||||
+ process._linkedBinding('electron_common_asar').initAsarSupport(require);
|
||||
+}
|
||||
+
|
||||
function patchProcessObject(expandArgv1) {
|
||||
const binding = internalBinding('process_methods');
|
||||
binding.patchProcessObject(process);
|
||||
diff --git a/test/fixtures/policy/process-binding/app.js b/test/fixtures/policy/process-binding/app.js
|
||||
index 16e26d12a160286b1b6aaeb64b15668b05b9865b..a287d0a2363acbf24077eec040116f96ef18a7b3 100644
|
||||
--- a/test/fixtures/policy/process-binding/app.js
|
||||
+++ b/test/fixtures/policy/process-binding/app.js
|
||||
@@ -5,6 +5,3 @@ const assert = require('assert');
|
||||
assert.throws(() => { process.binding(); }, {
|
||||
code: 'ERR_ACCESS_DENIED'
|
||||
});
|
||||
-assert.throws(() => { process._linkedBinding(); }, {
|
||||
- code: 'ERR_ACCESS_DENIED'
|
||||
-});
|
||||
@@ -1,31 +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 59c37b97672d39a9da89ca2b78aa28a77ca78699..da553f6556a06d57d7490d74a3b4dd8f0132600c 100644
|
||||
--- a/lib/child_process.js
|
||||
+++ b/lib/child_process.js
|
||||
@@ -137,7 +137,18 @@ function fork(modulePath, args = [], options) {
|
||||
validateObject(options, 'options');
|
||||
}
|
||||
options = { ...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');
|
||||
|
||||
// Prepare arguments for fork:
|
||||
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 31f5d1528c840a2926b59b2b1c82ff265588a37a..1e37bd59f53d3a194b2492c83f8e7299c42c828c 100644
|
||||
--- a/lib/internal/process/pre_execution.js
|
||||
+++ b/lib/internal/process/pre_execution.js
|
||||
@@ -114,6 +114,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 debd982c75805c51ea7d01229b9d635550060503..a6f160b6e28a01a31d6bb06fcfa384c748463c50 100644
|
||||
--- a/src/env-inl.h
|
||||
+++ b/src/env-inl.h
|
||||
@@ -388,6 +388,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 c914b621f50bcd6bce2617fef9e48737235aa516..e8ea98f193fcf579c20c3126dd441850c608752e 100644
|
||||
--- a/src/env.h
|
||||
+++ b/src/env.h
|
||||
@@ -933,6 +933,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);
|
||||
|
||||
@@ -1101,6 +1104,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 7ad8d80faee840e4dd224d946871b2ff08b0c23c..25842fd531fc7e1485bcd75f1f92aa9bc0640862 100644
|
||||
--- a/src/node_options.cc
|
||||
+++ b/src/node_options.cc
|
||||
@@ -1220,6 +1220,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 bfa048a4a8aa183e747dec84b11b1c1d847db2dd..970cec6c6e9c5e9646bfd758a2cf908e6b5799cf 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 547c8ddbffe243113bfe47a51072bb8f1541b94f..9f1fec4c4e47376c3b93a549f5c7ddf8e7ed3ac6 100644
|
||||
--- a/test/cctest/test_environment.cc
|
||||
+++ b/test/cctest/test_environment.cc
|
||||
@@ -749,3 +749,31 @@ TEST_F(EnvironmentTest, RequestInterruptAtExit) {
|
||||
node::FreeIsolateData(isolate_data);
|
||||
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");
|
||||
+}
|
||||
1
patches/sqlite/.patches
Normal file
1
patches/sqlite/.patches
Normal file
@@ -0,0 +1 @@
|
||||
fix_a_spurious_misuse_of_aggregate_function_error_that_could_occur.patch
|
||||
@@ -0,0 +1,323 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: dan <Dan Kennedy>
|
||||
Date: Thu, 2 Nov 2023 21:02:53 +0000
|
||||
Subject: Fix a spurious "misuse of aggregate function" error that could occur
|
||||
when an aggregate function was used within the FROM clause of a sub-select of
|
||||
the select that owns the aggregate. e.g. "SELECT (SELECT x FROM (SELECT
|
||||
sum(t1.a) AS x)) FROM t1". [forum:/forumpost/c9970a37ed | Forum post
|
||||
c9970a37ed].
|
||||
|
||||
FossilOrigin-Name: 4470f657d2069972d02a00983252dec1f814d90c0d8d0906e320e955111e8c11
|
||||
(cherry picked from commit 5e4233a9e48b124d4d342b757b34e4ae849f5cf8)
|
||||
|
||||
diff --git a/amalgamation/rename_exports.h b/amalgamation/rename_exports.h
|
||||
index 1dd9873cd698b9708c1e0897e6f270b5dd4e20c1..3b9835c71a5117dfeb249f30d930047c8722962c 100644
|
||||
--- a/amalgamation/rename_exports.h
|
||||
+++ b/amalgamation/rename_exports.h
|
||||
@@ -1,4 +1,4 @@
|
||||
-// Copyright 2023 The Chromium Authors. All rights reserved.
|
||||
+// Copyright 2024 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
diff --git a/amalgamation/sqlite3.c b/amalgamation/sqlite3.c
|
||||
index 19637a9234893df86d3d7b12b16617bca56f36e4..3b0548b328bc750665c7d0a67302c5f6097fde4e 100644
|
||||
--- a/amalgamation/sqlite3.c
|
||||
+++ b/amalgamation/sqlite3.c
|
||||
@@ -458,7 +458,7 @@ extern "C" {
|
||||
*/
|
||||
#define SQLITE_VERSION "3.42.0"
|
||||
#define SQLITE_VERSION_NUMBER 3042000
|
||||
-#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 ec7dafdf189a95ffcd452db5e3b5370d8f7007c56a7dee464cc700fdd1027368"
|
||||
+#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 19c0cc92aaff58e70789b761d7dcd23bc81869624e3aafea35673b5c3939a6ff"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
@@ -18921,6 +18921,7 @@ struct NameContext {
|
||||
int nRef; /* Number of names resolved by this context */
|
||||
int nNcErr; /* Number of errors encountered while resolving names */
|
||||
int ncFlags; /* Zero or more NC_* flags defined below */
|
||||
+ int nNestedSelect; /* Number of nested selects using this NC */
|
||||
Select *pWinSelect; /* SELECT statement for any window functions */
|
||||
};
|
||||
|
||||
@@ -105274,11 +105275,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
while( pNC2
|
||||
&& sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
|
||||
){
|
||||
- pExpr->op2++;
|
||||
+ pExpr->op2 += (1 + pNC2->nNestedSelect);
|
||||
pNC2 = pNC2->pNext;
|
||||
}
|
||||
assert( pDef!=0 || IN_RENAME_OBJECT );
|
||||
if( pNC2 && pDef ){
|
||||
+ pExpr->op2 += pNC2->nNestedSelect;
|
||||
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
|
||||
assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
|
||||
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
|
||||
@@ -105839,6 +105841,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
|
||||
/* Recursively resolve names in all subqueries in the FROM clause
|
||||
*/
|
||||
+ if( pOuterNC ) pOuterNC->nNestedSelect++;
|
||||
for(i=0; i<p->pSrc->nSrc; i++){
|
||||
SrcItem *pItem = &p->pSrc->a[i];
|
||||
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
|
||||
@@ -105863,6 +105866,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
}
|
||||
}
|
||||
}
|
||||
+ if( pOuterNC ) pOuterNC->nNestedSelect--;
|
||||
|
||||
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
|
||||
** resolve the result-set expression list.
|
||||
diff --git a/amalgamation/sqlite3.h b/amalgamation/sqlite3.h
|
||||
index 820dbeeb157b79d3380e089f1fdd5862a4cab087..c3738817186bbfd60aa7d19a3327d6a4ca118bc3 100644
|
||||
--- a/amalgamation/sqlite3.h
|
||||
+++ b/amalgamation/sqlite3.h
|
||||
@@ -148,7 +148,7 @@ extern "C" {
|
||||
*/
|
||||
#define SQLITE_VERSION "3.42.0"
|
||||
#define SQLITE_VERSION_NUMBER 3042000
|
||||
-#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 ec7dafdf189a95ffcd452db5e3b5370d8f7007c56a7dee464cc700fdd1027368"
|
||||
+#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 19c0cc92aaff58e70789b761d7dcd23bc81869624e3aafea35673b5c3939a6ff"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
diff --git a/amalgamation_dev/rename_exports.h b/amalgamation_dev/rename_exports.h
|
||||
index 1dd9873cd698b9708c1e0897e6f270b5dd4e20c1..3b9835c71a5117dfeb249f30d930047c8722962c 100644
|
||||
--- a/amalgamation_dev/rename_exports.h
|
||||
+++ b/amalgamation_dev/rename_exports.h
|
||||
@@ -1,4 +1,4 @@
|
||||
-// Copyright 2023 The Chromium Authors. All rights reserved.
|
||||
+// Copyright 2024 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
diff --git a/amalgamation_dev/sqlite3.c b/amalgamation_dev/sqlite3.c
|
||||
index 36a6a8306fffaf38ff6d2feb6541c0eccd8df8fc..b10707a5fb419fc64694de2642371e43899022b8 100644
|
||||
--- a/amalgamation_dev/sqlite3.c
|
||||
+++ b/amalgamation_dev/sqlite3.c
|
||||
@@ -458,7 +458,7 @@ extern "C" {
|
||||
*/
|
||||
#define SQLITE_VERSION "3.42.0"
|
||||
#define SQLITE_VERSION_NUMBER 3042000
|
||||
-#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 ec7dafdf189a95ffcd452db5e3b5370d8f7007c56a7dee464cc700fdd1027368"
|
||||
+#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 19c0cc92aaff58e70789b761d7dcd23bc81869624e3aafea35673b5c3939a6ff"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
@@ -18934,6 +18934,7 @@ struct NameContext {
|
||||
int nRef; /* Number of names resolved by this context */
|
||||
int nNcErr; /* Number of errors encountered while resolving names */
|
||||
int ncFlags; /* Zero or more NC_* flags defined below */
|
||||
+ int nNestedSelect; /* Number of nested selects using this NC */
|
||||
Select *pWinSelect; /* SELECT statement for any window functions */
|
||||
};
|
||||
|
||||
@@ -105287,11 +105288,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
while( pNC2
|
||||
&& sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
|
||||
){
|
||||
- pExpr->op2++;
|
||||
+ pExpr->op2 += (1 + pNC2->nNestedSelect);
|
||||
pNC2 = pNC2->pNext;
|
||||
}
|
||||
assert( pDef!=0 || IN_RENAME_OBJECT );
|
||||
if( pNC2 && pDef ){
|
||||
+ pExpr->op2 += pNC2->nNestedSelect;
|
||||
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
|
||||
assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
|
||||
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
|
||||
@@ -105852,6 +105854,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
|
||||
/* Recursively resolve names in all subqueries in the FROM clause
|
||||
*/
|
||||
+ if( pOuterNC ) pOuterNC->nNestedSelect++;
|
||||
for(i=0; i<p->pSrc->nSrc; i++){
|
||||
SrcItem *pItem = &p->pSrc->a[i];
|
||||
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
|
||||
@@ -105876,6 +105879,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
}
|
||||
}
|
||||
}
|
||||
+ if( pOuterNC ) pOuterNC->nNestedSelect--;
|
||||
|
||||
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
|
||||
** resolve the result-set expression list.
|
||||
diff --git a/amalgamation_dev/sqlite3.h b/amalgamation_dev/sqlite3.h
|
||||
index 820dbeeb157b79d3380e089f1fdd5862a4cab087..c3738817186bbfd60aa7d19a3327d6a4ca118bc3 100644
|
||||
--- a/amalgamation_dev/sqlite3.h
|
||||
+++ b/amalgamation_dev/sqlite3.h
|
||||
@@ -148,7 +148,7 @@ extern "C" {
|
||||
*/
|
||||
#define SQLITE_VERSION "3.42.0"
|
||||
#define SQLITE_VERSION_NUMBER 3042000
|
||||
-#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 ec7dafdf189a95ffcd452db5e3b5370d8f7007c56a7dee464cc700fdd1027368"
|
||||
+#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 19c0cc92aaff58e70789b761d7dcd23bc81869624e3aafea35673b5c3939a6ff"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
diff --git a/manifest b/manifest
|
||||
index 0841fab32a918f21970cf1806a984261f1aaccfb..e7b2f86954fa8078cb3211b5e5cfcb319b50b6dc 100644
|
||||
--- a/manifest
|
||||
+++ b/manifest
|
||||
@@ -634,14 +634,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
|
||||
F src/prepare.c 6350675966bd0e7ac3a464af9dbfe26db6f0d4237f4e1f1acdb17b12ad371e6e
|
||||
F src/printf.c b9320cdbeca0b336c3f139fd36dd121e4167dd62b35fbe9ccaa9bab44c0af38d
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
-F src/resolve.c 3e53e02ce87c9582bd7e7d22f13f4094a271678d9dc72820fa257a2abb5e4032
|
||||
+F src/resolve.c 9bcc9021a5b849ba8ccd2103147b75a3a98d885e00212b48672fe1ed8356338b
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c 738c3a3d6929f8be66c319bad17f6b297bd60a4eb14006075c48a28487dc7786
|
||||
F src/shell.c.in a8971a2ae4adee5f0a73d7a6c095026e8a2958ff3e9f56887a014df07733ca0c
|
||||
F src/sqlite.h.in c14a4471fcd897a03631ac7ad3d05505e895e7b6419ec5b96cae9bc4df7a9fc6
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
|
||||
-F src/sqliteInt.h a3ced8b9ebc573189c87b69f24bf10d2b9cd3cefefaae52623a2fa79e6fdd408
|
||||
+F src/sqliteInt.h 522f19804d86e193dbfd966cd0dd033e0f6ec092e60c3812ae066657fe152653
|
||||
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
|
||||
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@@ -731,7 +731,7 @@ F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867d
|
||||
F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggfault.test 777f269d0da5b0c2524c7ff6d99ae9a93db4f1b1839a914dd2a12e3035c29829
|
||||
-F test/aggnested.test 7269d07ac879fce161cb26c8fabe65cba5715742fac8a1fccac570dcdaf28f00
|
||||
+F test/aggnested.test e1977bdc0a154b99c139b879b78c46030aa6ee97fb06bf65d6784a536e25b743
|
||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||
F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13
|
||||
F test/alter.test 313073774ab5c3f2ef1d3f0d03757c9d3a81284ae7e1b4a6ca34db088f886896
|
||||
@@ -1920,7 +1920,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
|
||||
F test/win32lock.test e0924eb8daac02bf80e9da88930747bd44dd9b230b7759fed927b1655b467c9c
|
||||
F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976
|
||||
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||
-F test/window1.test 5ba48e9d33231e6ef16f21426bade9ccc52abf65a10587bff90a6c14fe174594
|
||||
+F test/window1.test 95d0d3e43a54600beba759f9a9f4f4bf546a596b1a8cc3f70dd26bf22ce7e41a
|
||||
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
|
||||
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
|
||||
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
|
||||
diff --git a/src/resolve.c b/src/resolve.c
|
||||
index adfcc8dbe9cf41581a23cfc42a6d699bf86d384f..b453a5b456ea1e0db814e1bd13c3fbe706a19a38 100644
|
||||
--- a/src/resolve.c
|
||||
+++ b/src/resolve.c
|
||||
@@ -1212,11 +1212,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
while( pNC2
|
||||
&& sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
|
||||
){
|
||||
- pExpr->op2++;
|
||||
+ pExpr->op2 += (1 + pNC2->nNestedSelect);
|
||||
pNC2 = pNC2->pNext;
|
||||
}
|
||||
assert( pDef!=0 || IN_RENAME_OBJECT );
|
||||
if( pNC2 && pDef ){
|
||||
+ pExpr->op2 += pNC2->nNestedSelect;
|
||||
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
|
||||
assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
|
||||
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
|
||||
@@ -1777,6 +1778,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
|
||||
/* Recursively resolve names in all subqueries in the FROM clause
|
||||
*/
|
||||
+ if( pOuterNC ) pOuterNC->nNestedSelect++;
|
||||
for(i=0; i<p->pSrc->nSrc; i++){
|
||||
SrcItem *pItem = &p->pSrc->a[i];
|
||||
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
|
||||
@@ -1801,6 +1803,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
}
|
||||
}
|
||||
}
|
||||
+ if( pOuterNC ) pOuterNC->nNestedSelect--;
|
||||
|
||||
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
|
||||
** resolve the result-set expression list.
|
||||
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
|
||||
index 2c893770b04e06932b9c4405ff9b41a13aff68d0..ab94b56c638724a9de8ea2da49c944fb85a1923f 100644
|
||||
--- a/src/sqliteInt.h
|
||||
+++ b/src/sqliteInt.h
|
||||
@@ -3332,6 +3332,7 @@ struct NameContext {
|
||||
int nRef; /* Number of names resolved by this context */
|
||||
int nNcErr; /* Number of errors encountered while resolving names */
|
||||
int ncFlags; /* Zero or more NC_* flags defined below */
|
||||
+ int nNestedSelect; /* Number of nested selects using this NC */
|
||||
Select *pWinSelect; /* SELECT statement for any window functions */
|
||||
};
|
||||
|
||||
diff --git a/test/aggnested.test b/test/aggnested.test
|
||||
index 1b8b608803912d5d8b7a7562dd31ec4a46627da4..6599fbf90940e49ce3467c67b7c8800aa90b17c0 100644
|
||||
--- a/test/aggnested.test
|
||||
+++ b/test/aggnested.test
|
||||
@@ -358,6 +358,60 @@ do_execsql_test 6.2.2 {
|
||||
FROM t2 GROUP BY 'constant_string';
|
||||
} {{}}
|
||||
|
||||
+#-------------------------------------------------------------------------
|
||||
+reset_db
|
||||
+
|
||||
+do_execsql_test 7.0 {
|
||||
+ CREATE TABLE invoice (
|
||||
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
+ amount DOUBLE PRECISION DEFAULT NULL,
|
||||
+ name VARCHAR(100) DEFAULT NULL
|
||||
+ );
|
||||
+
|
||||
+ INSERT INTO invoice (amount, name) VALUES
|
||||
+ (4.0, 'Michael'), (15.0, 'Bara'), (4.0, 'Michael'), (6.0, 'John');
|
||||
+}
|
||||
+
|
||||
+do_execsql_test 7.1 {
|
||||
+ SELECT sum(amount), name
|
||||
+ from invoice
|
||||
+ group by name
|
||||
+ having (select v > 6 from (select sum(amount) v) t)
|
||||
+} {
|
||||
+ 15.0 Bara
|
||||
+ 8.0 Michael
|
||||
+}
|
||||
+
|
||||
+do_execsql_test 7.2 {
|
||||
+ SELECT (select 1 from (select sum(amount))) FROM invoice
|
||||
+} {1}
|
||||
+
|
||||
+do_execsql_test 8.0 {
|
||||
+ CREATE TABLE t1(x INT);
|
||||
+ INSERT INTO t1 VALUES(100);
|
||||
+ INSERT INTO t1 VALUES(20);
|
||||
+ INSERT INTO t1 VALUES(3);
|
||||
+ SELECT (SELECT y FROM (SELECT sum(x) AS y) AS t2 ) FROM t1;
|
||||
+} {123}
|
||||
+
|
||||
+do_execsql_test 8.1 {
|
||||
+ SELECT (
|
||||
+ SELECT y FROM (
|
||||
+ SELECT z AS y FROM (SELECT sum(x) AS z) AS t2
|
||||
+ )
|
||||
+ ) FROM t1;
|
||||
+} {123}
|
||||
+
|
||||
+do_execsql_test 8.2 {
|
||||
+ SELECT (
|
||||
+ SELECT a FROM (
|
||||
+ SELECT y AS a FROM (
|
||||
+ SELECT z AS y FROM (SELECT sum(x) AS z) AS t2
|
||||
+ )
|
||||
+ )
|
||||
+ ) FROM t1;
|
||||
+} {123}
|
||||
+
|
||||
|
||||
|
||||
|
||||
diff --git a/test/window1.test b/test/window1.test
|
||||
index 783a739e3f1428f107932319a53e9cde91e79557..8044d43547718bb54b301c185adf60bf70ab1ae8 100644
|
||||
--- a/test/window1.test
|
||||
+++ b/test/window1.test
|
||||
@@ -1881,7 +1881,7 @@ do_catchsql_test 57.3 {
|
||||
SELECT max(y) OVER( ORDER BY (SELECT x FROM (SELECT sum(y) AS x FROM t1)))
|
||||
)
|
||||
FROM t3;
|
||||
-} {1 {misuse of aggregate: sum()}}
|
||||
+} {0 5}
|
||||
|
||||
# 2020-06-06 ticket 1f6f353b684fc708
|
||||
reset_db
|
||||
@@ -2,3 +2,13 @@ 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
|
||||
cherry-pick-cbd09b2ca928.patch
|
||||
merged_turboshaft_fix_structuraloptimization_because_of_ignored.patch
|
||||
cherry-pick-389ea9be7d68.patch
|
||||
cherry-pick-46cb67e3b296.patch
|
||||
cherry-pick-78dd4b31847a.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
|
||||
merged_wasm_check_the_cached_memory_for_growability.patch
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user