mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
047fdbf3ca | ||
|
|
1f91895d22 | ||
|
|
4ade2a6fb6 | ||
|
|
a68e328e53 | ||
|
|
047f474eab | ||
|
|
81bc1ea876 | ||
|
|
c676c0aaca | ||
|
|
399d2b2d2c | ||
|
|
1d60268033 | ||
|
|
609855101c | ||
|
|
d654650f7b | ||
|
|
a6ce1bc96d | ||
|
|
2cdaab741d | ||
|
|
b07f2f0f42 | ||
|
|
df6f23bbd1 | ||
|
|
900459e1b1 | ||
|
|
5af5b42422 | ||
|
|
de3a8a5389 | ||
|
|
8c172f2e95 | ||
|
|
6820094f8e | ||
|
|
f907c18bac | ||
|
|
27575566c9 | ||
|
|
518d3e490d | ||
|
|
29cdcb443a | ||
|
|
4c435b27e0 | ||
|
|
85317c3109 | ||
|
|
ea7e3c80ee | ||
|
|
f0685b60a7 | ||
|
|
7fd1f3da64 | ||
|
|
c6b44676e6 | ||
|
|
69d1434bcc | ||
|
|
f843f23363 | ||
|
|
fcbd88f8aa | ||
|
|
ee668f1472 | ||
|
|
c875adf7cf | ||
|
|
3cd2f2ede9 | ||
|
|
e2c4acd505 | ||
|
|
620bdcbb2a | ||
|
|
ae7b2ae3cb | ||
|
|
ffff96e33f | ||
|
|
7a4a94b18c | ||
|
|
62dddd12ed | ||
|
|
0b17a20119 | ||
|
|
f557f99631 | ||
|
|
4b5998e51a | ||
|
|
de3bc8cb4c | ||
|
|
ba1a2f3d0f | ||
|
|
352ab57670 | ||
|
|
4a7bf76fa1 | ||
|
|
978cc7bd7d | ||
|
|
94c7ad9ee2 | ||
|
|
be71423d32 | ||
|
|
565c4fe9a7 | ||
|
|
c0caa61022 | ||
|
|
f19e6d516a | ||
|
|
3931d5a84f | ||
|
|
8a2e936053 | ||
|
|
c43eed8782 | ||
|
|
f89e3e37de | ||
|
|
550b0d5a43 | ||
|
|
f2719edd1d | ||
|
|
cedf0014f6 | ||
|
|
2d1ba5626b | ||
|
|
c8fea8abcf | ||
|
|
bb88e69ccc | ||
|
|
14707ad2b5 | ||
|
|
24ce94856c | ||
|
|
a831d69dfd | ||
|
|
432eba9406 | ||
|
|
e4800bab86 | ||
|
|
d44fd39272 | ||
|
|
8352346fff | ||
|
|
76f5059db4 | ||
|
|
0b52938852 | ||
|
|
5d3eea5934 | ||
|
|
0384c57eb5 | ||
|
|
7e02e1d6da | ||
|
|
87ec774248 | ||
|
|
1df44118af | ||
|
|
9db65bac75 | ||
|
|
5f115c8967 |
@@ -54,7 +54,7 @@ executors:
|
||||
type: enum
|
||||
enum: ["macos.x86.medium.gen2", "large"]
|
||||
macos:
|
||||
xcode: 13.3.0
|
||||
xcode: 13.4.1
|
||||
resource_class: << parameters.size >>
|
||||
|
||||
# Electron Runners
|
||||
@@ -243,14 +243,27 @@ step-depot-tools-get: &step-depot-tools-get
|
||||
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
# Remove swift-format dep from cipd on macOS until we send a patch upstream.
|
||||
cd depot_tools
|
||||
patch gclient.py -R \<<'EOF'
|
||||
676,677c676
|
||||
< packages = dep_value.get('packages', [])
|
||||
< for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
|
||||
---
|
||||
> for package in dep_value.get('packages', []):
|
||||
cat > gclient.diff \<< 'EOF'
|
||||
diff --git a/gclient.py b/gclient.py
|
||||
index 3a9c5c6..f222043 100755
|
||||
--- a/gclient.py
|
||||
+++ b/gclient.py
|
||||
@@ -712,7 +712,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
|
||||
|
||||
if dep_type == 'cipd':
|
||||
cipd_root = self.GetCipdRoot()
|
||||
- for package in dep_value.get('packages', []):
|
||||
+ packages = dep_value.get('packages', [])
|
||||
+ for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
|
||||
deps_to_add.append(
|
||||
CipdDependency(
|
||||
parent=self,
|
||||
EOF
|
||||
git apply --3way gclient.diff
|
||||
fi
|
||||
# Ensure depot_tools does not update.
|
||||
test -d depot_tools && cd depot_tools
|
||||
touch .disable_auto_update
|
||||
|
||||
step-depot-tools-add-to-path: &step-depot-tools-add-to-path
|
||||
run:
|
||||
@@ -272,7 +285,7 @@ step-gclient-sync: &step-gclient-sync
|
||||
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags
|
||||
if [ "$IS_RELEASE" != "true" ]; then
|
||||
# Re-export all the patches to check if there were changes.
|
||||
python src/electron/script/export_all_patches.py src/electron/patches/config.json
|
||||
python3 src/electron/script/export_all_patches.py src/electron/patches/config.json
|
||||
cd src/electron
|
||||
git update-index --refresh || true
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
@@ -326,8 +339,8 @@ step-setup-goma-for-build: &step-setup-goma-for-build
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
export GOMA_FALLBACK_ON_AUTH_FAILURE=true
|
||||
third_party/goma/goma_ctl.py ensure_start
|
||||
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`third_party/goma/goma_auth.py info`" != "Login as Fermi Planck" ]; then
|
||||
python3 third_party/goma/goma_ctl.py ensure_start
|
||||
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`python3 third_party/goma/goma_auth.py info`" != "Login as Fermi Planck" ]; then
|
||||
echo "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token."
|
||||
exit 1
|
||||
fi
|
||||
@@ -355,14 +368,14 @@ step-restore-brew-cache: &step-restore-brew-cache
|
||||
- /usr/local/Cellar/gnu-tar
|
||||
- /usr/local/bin/gtar
|
||||
keys:
|
||||
- v5-brew-cache-{{ arch }}
|
||||
- v7-brew-cache-{{ arch }}
|
||||
|
||||
step-save-brew-cache: &step-save-brew-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- /usr/local/Cellar/gnu-tar
|
||||
- /usr/local/bin/gtar
|
||||
key: v5-brew-cache-{{ arch }}
|
||||
key: v7-brew-cache-{{ arch }}
|
||||
name: Persisting brew cache
|
||||
|
||||
step-get-more-space-on-mac: &step-get-more-space-on-mac
|
||||
@@ -731,9 +744,9 @@ step-verify-mksnapshot: &step-verify-mksnapshot
|
||||
if [ "$IS_ASAN" != "1" ]; then
|
||||
cd src
|
||||
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/cross-arch-snapshots
|
||||
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/cross-arch-snapshots
|
||||
else
|
||||
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
|
||||
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -743,7 +756,7 @@ step-verify-chromedriver: &step-verify-chromedriver
|
||||
command: |
|
||||
if [ "$IS_ASAN" != "1" ]; then
|
||||
cd src
|
||||
python electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/Default
|
||||
python3 electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/Default
|
||||
fi
|
||||
|
||||
step-setup-linux-for-headless-testing: &step-setup-linux-for-headless-testing
|
||||
@@ -859,7 +872,7 @@ step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
|
||||
elif [ "`uname`" == "Darwin" ]; then
|
||||
cp "out/Default/$MKSNAPSHOT_PATH/libffmpeg.dylib" out/Default
|
||||
fi
|
||||
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
|
||||
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
|
||||
mkdir cross-arch-snapshots
|
||||
cp out/Default-mksnapshot-test/*.bin cross-arch-snapshots
|
||||
fi
|
||||
@@ -1011,26 +1024,12 @@ step-ts-compile: &step-ts-compile
|
||||
# List of all steps.
|
||||
steps-electron-gn-check: &steps-electron-gn-check
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- install-python2-mac
|
||||
- *step-setup-env-for-build
|
||||
- *step-setup-goma-for-build
|
||||
- *step-generate-deps-hash
|
||||
- *step-touch-sync-done
|
||||
- maybe-restore-portaled-src-cache
|
||||
- run:
|
||||
name: Ensure src checkout worked
|
||||
command: |
|
||||
if [ ! -d "src/third_party/blink" ]; then
|
||||
echo src cache was not restored for an unknown reason
|
||||
exit 1
|
||||
fi
|
||||
- run:
|
||||
name: Wipe Electron
|
||||
command: rm -rf src/electron
|
||||
- *step-checkout-electron
|
||||
- checkout-from-cache
|
||||
- *step-setup-env-for-build
|
||||
- *step-wait-for-goma
|
||||
- *step-gn-gen-default
|
||||
- *step-gn-check
|
||||
|
||||
steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-change
|
||||
steps:
|
||||
@@ -1052,7 +1051,6 @@ steps-tests: &steps-tests
|
||||
- *step-setup-linux-for-headless-testing
|
||||
- *step-restore-brew-cache
|
||||
- *step-fix-known-hosts-linux
|
||||
- install-python2-mac
|
||||
- *step-install-signing-cert-on-mac
|
||||
|
||||
- run:
|
||||
@@ -1136,31 +1134,6 @@ steps-test-node: &steps-test-node
|
||||
|
||||
# Command Aliases
|
||||
commands:
|
||||
install-python2-mac:
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v2.7.18-python-cache-{{ arch }}
|
||||
name: Restore python cache
|
||||
- run:
|
||||
name: Install python2 on macos
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ] && [ "$IS_ELECTRON_RUNNER" != "1" ]; then
|
||||
if [ ! -f "python-downloads/python-2.7.18-macosx10.9.pkg" ]; then
|
||||
mkdir python-downloads
|
||||
echo 'Downloading Python 2.7.18'
|
||||
curl -O https://dev-cdn.electronjs.org/python/python-2.7.18-macosx10.9.pkg
|
||||
mv python-2.7.18-macosx10.9.pkg python-downloads
|
||||
else
|
||||
echo 'Using Python install from cache'
|
||||
fi
|
||||
sudo installer -pkg python-downloads/python-2.7.18-macosx10.9.pkg -target /
|
||||
fi
|
||||
- save_cache:
|
||||
paths:
|
||||
- python-downloads
|
||||
key: v2.7.18-python-cache-{{ arch }}
|
||||
name: Persisting python cache
|
||||
maybe-restore-portaled-src-cache:
|
||||
parameters:
|
||||
halt-if-successful:
|
||||
@@ -1324,7 +1297,6 @@ commands:
|
||||
- run: rm -rf src/electron
|
||||
- *step-restore-brew-cache
|
||||
- *step-install-gnutar-on-mac
|
||||
- install-python2-mac
|
||||
- *step-save-brew-cache
|
||||
- when:
|
||||
condition: << parameters.build >>
|
||||
@@ -1496,7 +1468,6 @@ commands:
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
- install-python2-mac
|
||||
- *step-get-more-space-on-mac
|
||||
- when:
|
||||
condition: << parameters.checkout >>
|
||||
@@ -2214,4 +2185,4 @@ workflows:
|
||||
jobs:
|
||||
- lint
|
||||
|
||||
# VS Code Extension Version: 1.4.0
|
||||
# VS Code Extension Version: 1.4.0
|
||||
|
||||
@@ -83,6 +83,8 @@ for:
|
||||
Remove-Item -Recurse -Force $pwd\build-tools
|
||||
}
|
||||
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
|
||||
- depot_tools\bootstrap\win_tools.bat
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\src\electron") {
|
||||
|
||||
@@ -81,6 +81,8 @@ for:
|
||||
Remove-Item -Recurse -Force $pwd\build-tools
|
||||
}
|
||||
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
|
||||
- depot_tools\bootstrap\win_tools.bat
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\src\electron") {
|
||||
|
||||
@@ -128,8 +128,6 @@ Emitted when the user wants to open a URL with the application. Your application
|
||||
`Info.plist` file must define the URL scheme within the `CFBundleURLTypes` key, and
|
||||
set `NSPrincipalClass` to `AtomApplication`.
|
||||
|
||||
You should call `event.preventDefault()` if you want to handle this event.
|
||||
|
||||
As with the `open-file` event, be sure to register a listener for the `open-url`
|
||||
event early in your application startup to detect if the the application being
|
||||
is being opened to handle a URL. If you register the listener in response to a
|
||||
@@ -750,14 +748,21 @@ This API can be used for purposes such as deciding what language to present the
|
||||
|
||||
Here are some examples of return values of the various language and locale APIs with different configurations:
|
||||
|
||||
* For Windows, where the application locale is German, the regional format is Finnish (Finland), and the preferred system languages from most to least preferred are French (Canada), English (US), Simplified Chinese (China), Finnish, and Spanish (Latin America):
|
||||
* `app.getLocale()` returns `'de'`
|
||||
* `app.getSystemLocale()` returns `'fi-FI'`
|
||||
* `app.getPreferredSystemLanguages()` returns `['fr-CA', 'en-US', 'zh-Hans-CN', 'fi', 'es-419']`
|
||||
* On macOS, where the application locale is German, the region is Finland, and the preferred system languages from most to least preferred are French (Canada), English (US), Simplified Chinese, and Spanish (Latin America):
|
||||
* `app.getLocale()` returns `'de'`
|
||||
* `app.getSystemLocale()` returns `'fr-FI'`
|
||||
* `app.getPreferredSystemLanguages()` returns `['fr-CA', 'en-US', 'zh-Hans-FI', 'es-419']`
|
||||
On Windows, given application locale is German, the regional format is Finnish (Finland), and the preferred system languages from most to least preferred are French (Canada), English (US), Simplified Chinese (China), Finnish, and Spanish (Latin America):
|
||||
|
||||
```js
|
||||
app.getLocale() // 'de'
|
||||
app.getSystemLocale() // 'fi-FI'
|
||||
app.getPreferredSystemLanguages() // ['fr-CA', 'en-US', 'zh-Hans-CN', 'fi', 'es-419']
|
||||
```
|
||||
|
||||
On macOS, given the application locale is German, the region is Finland, and the preferred system languages from most to least preferred are French (Canada), English (US), Simplified Chinese, and Spanish (Latin America):
|
||||
|
||||
```js
|
||||
app.getLocale() // 'de'
|
||||
app.getSystemLocale() // 'fr-FI'
|
||||
app.getPreferredSystemLanguages() // ['fr-CA', 'en-US', 'zh-Hans-FI', 'es-419']
|
||||
```
|
||||
|
||||
Both the available languages and regions and the possible return values differ between the two operating systems.
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
zoom to the width of the screen. This will also affect the behavior when
|
||||
calling `maximize()` directly. Default is `false`.
|
||||
* `tabbingIdentifier` string (optional) _macOS_ - Tab group name, allows
|
||||
opening the window as a native tab on macOS 10.12+. Windows with the same
|
||||
opening the window as a native tab. Windows with the same
|
||||
tabbing identifier will be grouped together. This also adds a native new
|
||||
tab button to your window's tab bar and allows your `app` and window to
|
||||
receive the `new-window-for-tab` event.
|
||||
@@ -1847,7 +1847,7 @@ frameless window.
|
||||
|
||||
Sets the touchBar layout for the current window. Specifying `null` or
|
||||
`undefined` clears the touch bar. This method only has an effect if the
|
||||
machine has a touch bar and is running on macOS 10.12.1+.
|
||||
machine has a touch bar.
|
||||
|
||||
**Note:** The TouchBar API is currently experimental and may change or be
|
||||
removed in future Electron releases.
|
||||
|
||||
@@ -51,7 +51,7 @@ See [`Menu`](menu.md) for examples.
|
||||
the placement of their containing group after the containing group of the item
|
||||
with the specified label.
|
||||
|
||||
**Note:** `acceleratorWorksWhenHidden` is specified as being macOS-only because accelerators always work when items are hidden on Windows and Linux. The option is exposed to users to give them the option to turn it off, as this is possible in native macOS development. This property is only usable on macOS High Sierra 10.13 or newer.
|
||||
**Note:** `acceleratorWorksWhenHidden` is specified as being macOS-only because accelerators always work when items are hidden on Windows and Linux. The option is exposed to users to give them the option to turn it off, as this is possible in native macOS development.
|
||||
|
||||
### Roles
|
||||
|
||||
|
||||
@@ -394,8 +394,6 @@ system default and override the value of `getEffectiveAppearance`.
|
||||
|
||||
Returns `boolean` - whether or not this device has the ability to use Touch ID.
|
||||
|
||||
**NOTE:** This API will return `false` on macOS systems older than Sierra 10.12.2.
|
||||
|
||||
### `systemPreferences.promptTouchID(reason)` _macOS_
|
||||
|
||||
* `reason` string - The reason you are asking for Touch ID authentication
|
||||
@@ -414,8 +412,6 @@ systemPreferences.promptTouchID('To get consent for a Security-Gated Thing').the
|
||||
|
||||
This API itself will not protect your user data; rather, it is a mechanism to allow you to do so. Native apps will need to set [Access Control Constants](https://developer.apple.com/documentation/security/secaccesscontrolcreateflags?language=objc) like [`kSecAccessControlUserPresence`](https://developer.apple.com/documentation/security/secaccesscontrolcreateflags/ksecaccesscontroluserpresence?language=objc) on their keychain entry so that reading it would auto-prompt for Touch ID biometric consent. This could be done with [`node-keytar`](https://github.com/atom/node-keytar), such that one would store an encryption key with `node-keytar` and only fetch it if `promptTouchID()` resolves.
|
||||
|
||||
**NOTE:** This API will return a rejected Promise on macOS systems older than Sierra 10.12.2.
|
||||
|
||||
### `systemPreferences.isTrustedAccessibilityClient(prompt)` _macOS_
|
||||
|
||||
* `prompt` boolean - whether or not the user will be informed via prompt if the current process is untrusted.
|
||||
@@ -428,7 +424,7 @@ Returns `boolean` - `true` if the current process is a trusted accessibility cli
|
||||
|
||||
Returns `string` - Can be `not-determined`, `granted`, `denied`, `restricted` or `unknown`.
|
||||
|
||||
This user consent was not required on macOS 10.13 High Sierra or lower so this method will always return `granted`.
|
||||
This user consent was not required on macOS 10.13 High Sierra so this method will always return `granted`.
|
||||
macOS 10.14 Mojave or higher requires consent for `microphone` and `camera` access.
|
||||
macOS 10.15 Catalina or higher requires consent for `screen` access.
|
||||
|
||||
@@ -443,7 +439,7 @@ Returns `Promise<boolean>` - A promise that resolves with `true` if consent was
|
||||
|
||||
**Important:** In order to properly leverage this API, you [must set](https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/requesting_authorization_for_media_capture_on_macos?language=objc) the `NSMicrophoneUsageDescription` and `NSCameraUsageDescription` strings in your app's `Info.plist` file. The values for these keys will be used to populate the permission dialogs so that the user will be properly informed as to the purpose of the permission request. See [Electron Application Distribution](../tutorial/application-distribution.md#rebranding-with-downloaded-binaries) for more information about how to set these in the context of Electron.
|
||||
|
||||
This user consent was not required until macOS 10.14 Mojave, so this method will always return `true` if your system is running 10.13 High Sierra or lower.
|
||||
This user consent was not required until macOS 10.14 Mojave, so this method will always return `true` if your system is running 10.13 High Sierra.
|
||||
|
||||
### `systemPreferences.getAnimationSettings()`
|
||||
|
||||
|
||||
@@ -235,7 +235,7 @@ Sets the hover text for this tray icon.
|
||||
|
||||
* `title` string
|
||||
* `options` Object (optional)
|
||||
* `fontType` string (optional) - The font family variant to display, can be `monospaced` or `monospacedDigit`. `monospaced` is available in macOS 10.15+ and `monospacedDigit` is available in macOS 10.11+. When left blank, the title uses the default system font.
|
||||
* `fontType` string (optional) - The font family variant to display, can be `monospaced` or `monospacedDigit`. `monospaced` is available in macOS 10.15+ When left blank, the title uses the default system font.
|
||||
|
||||
Sets the title displayed next to the tray icon in the status bar (Support ANSI colors).
|
||||
|
||||
|
||||
@@ -713,20 +713,24 @@ Returns:
|
||||
* `callback` Function
|
||||
* `deviceId` string
|
||||
|
||||
Emitted when bluetooth device needs to be selected on call to
|
||||
`navigator.bluetooth.requestDevice`. To use `navigator.bluetooth` api
|
||||
`webBluetooth` should be enabled. If `event.preventDefault` is not called,
|
||||
first available device will be selected. `callback` should be called with
|
||||
`deviceId` to be selected, passing empty string to `callback` will
|
||||
cancel the request.
|
||||
Emitted when a bluetooth device needs to be selected when a call to
|
||||
`navigator.bluetooth.requestDevice` is made. `callback` should be called with
|
||||
the `deviceId` of the device to be selected. Passing an empty string to
|
||||
`callback` will cancel the request.
|
||||
|
||||
If no event listener is added for this event, all bluetooth requests will be cancelled.
|
||||
If an event listener is not added for this event, or if `event.preventDefault`
|
||||
is not called when handling this event, the first available device will be
|
||||
automatically selected.
|
||||
|
||||
Due to the nature of bluetooth, scanning for devices when
|
||||
`navigator.bluetooth.requestDevice` is called may take time and will cause
|
||||
`select-bluetooth-device` to fire multiple times until `callback` is called
|
||||
with either a device id or an empty string to cancel the request.
|
||||
|
||||
```javascript
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let win = null
|
||||
app.commandLine.appendSwitch('enable-experimental-web-platform-features')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
win = new BrowserWindow({ width: 800, height: 600 })
|
||||
@@ -736,6 +740,9 @@ app.whenReady().then(() => {
|
||||
return device.deviceName === 'test'
|
||||
})
|
||||
if (!result) {
|
||||
// The device wasn't found so we need to either wait longer (eg until the
|
||||
// device is turned on) or cancel the request by calling the callback
|
||||
// with an empty string.
|
||||
callback('')
|
||||
} else {
|
||||
callback(result.deviceId)
|
||||
|
||||
@@ -56,6 +56,39 @@ webContents.setWindowOpenHandler((details) => {
|
||||
})
|
||||
```
|
||||
|
||||
### Removed: `<webview>` `new-window` event
|
||||
|
||||
The `new-window` event of `<webview>` has been removed. There is no direct replacement.
|
||||
|
||||
```js
|
||||
// Removed in Electron 22
|
||||
webview.addEventListener('new-window', (event) => {})
|
||||
```
|
||||
|
||||
```javascript fiddle='docs/fiddles/ipc/webview-new-window'
|
||||
// Replace with
|
||||
|
||||
// main.js
|
||||
mainWindow.webContents.on('did-attach-webview', (event, wc) => {
|
||||
wc.setWindowOpenHandler((details) => {
|
||||
mainWindow.webContents.send('webview-new-window', wc.id, details)
|
||||
return { action: 'deny' }
|
||||
})
|
||||
})
|
||||
|
||||
// preload.js
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.on('webview-new-window', (e, webContentsId, details) => {
|
||||
console.log('webview-new-window', webContentsId, details)
|
||||
document.getElementById('webview').dispatchEvent(new Event('new-window'))
|
||||
})
|
||||
|
||||
// renderer.js
|
||||
document.getElementById('webview').addEventListener('new-window', () => {
|
||||
console.log('got new-window event')
|
||||
})
|
||||
```
|
||||
|
||||
### Deprecated: BrowserWindow `scroll-touch-*` events
|
||||
|
||||
The `scroll-touch-begin`, `scroll-touch-end` and `scroll-touch-edge` events on
|
||||
@@ -146,6 +179,13 @@ webContents.printToPDF({
|
||||
|
||||
## Planned Breaking API Changes (20.0)
|
||||
|
||||
### Removed: macOS 10.11 / 10.12 support
|
||||
|
||||
macOS 10.11 (El Capitan) and macOS 10.12 (Sierra) are no longer supported by [Chromium](https://chromium-review.googlesource.com/c/chromium/src/+/3646050).
|
||||
|
||||
Older versions of Electron will continue to run on these operating systems, but macOS 10.13 (High Sierra)
|
||||
or later will be required to run Electron v20.0.0 and higher.
|
||||
|
||||
### Default Changed: renderers without `nodeIntegration: true` are sandboxed by default
|
||||
|
||||
Previously, renderers that specified a preload script defaulted to being
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<h1>Web Bluetooth API</h1>
|
||||
|
||||
<button id="clickme">Test Bluetooth</button>
|
||||
<button id="cancel">Cancel Bluetooth Request</button>
|
||||
|
||||
<p>Currently selected bluetooth device: <strong id="device-name""></strong></p>
|
||||
|
||||
|
||||
@@ -1,22 +1,37 @@
|
||||
const {app, BrowserWindow, ipcMain} = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
let bluetoothPinCallback
|
||||
let selectBluetoothCallback
|
||||
|
||||
function createWindow () {
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
|
||||
event.preventDefault()
|
||||
if (deviceList && deviceList.length > 0) {
|
||||
callback(deviceList[0].deviceId)
|
||||
}
|
||||
selectBluetoothCallback = callback
|
||||
const result = deviceList.find((device) => {
|
||||
return device.deviceName === 'test'
|
||||
})
|
||||
if (result) {
|
||||
callback(result.deviceId)
|
||||
} else {
|
||||
// The device wasn't found so we need to either wait longer (eg until the
|
||||
// device is turned on) or until the user cancels the request
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('cancel-bluetooth-request', (event) => {
|
||||
selectBluetoothCallback('')
|
||||
})
|
||||
|
||||
|
||||
// Listen for a message from the renderer to get the response for the Bluetooth pairing.
|
||||
ipcMain.on('bluetooth-pairing-response', (event, response) => {
|
||||
bluetoothPinCallback(response)
|
||||
@@ -27,14 +42,14 @@ function createWindow () {
|
||||
bluetoothPinCallback = callback
|
||||
// Send a message to the renderer to prompt the user to confirm the pairing.
|
||||
mainWindow.webContents.send('bluetooth-pairing-request', details)
|
||||
})
|
||||
})
|
||||
|
||||
mainWindow.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
|
||||
|
||||
app.on('activate', function () {
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
cancelBluetoothRequest: (callback) => ipcRenderer.send('cancel-bluetooth-request', callback),
|
||||
bluetoothPairingRequest: (callback) => ipcRenderer.on('bluetooth-pairing-request', callback),
|
||||
bluetoothPairingResponse: (response) => ipcRenderer.send('bluetooth-pairing-response', response)
|
||||
})
|
||||
@@ -7,9 +7,15 @@ async function testIt() {
|
||||
|
||||
document.getElementById('clickme').addEventListener('click',testIt)
|
||||
|
||||
function cancelRequest() {
|
||||
window.electronAPI.cancelBluetoothRequest()
|
||||
}
|
||||
|
||||
document.getElementById('cancel').addEventListener('click', cancelRequest)
|
||||
|
||||
window.electronAPI.bluetoothPairingRequest((event, details) => {
|
||||
const response = {}
|
||||
|
||||
|
||||
switch (details.pairingKind) {
|
||||
case 'confirm': {
|
||||
response.confirmed = confirm(`Do you want to connect to device ${details.deviceId}?`)
|
||||
@@ -31,4 +37,4 @@ window.electronAPI.bluetoothPairingRequest((event, details) => {
|
||||
}
|
||||
|
||||
window.electronAPI.bluetoothPairingResponse(response)
|
||||
})
|
||||
})
|
||||
|
||||
3
docs/fiddles/ipc/webview-new-window/child.html
Normal file
3
docs/fiddles/ipc/webview-new-window/child.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<body>
|
||||
<a href="child.html" target="_blank">new window</a>
|
||||
</body>
|
||||
4
docs/fiddles/ipc/webview-new-window/index.html
Normal file
4
docs/fiddles/ipc/webview-new-window/index.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<body>
|
||||
<webview id=webview src="child.html" allowpopups></webview>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
51
docs/fiddles/ipc/webview-new-window/main.js
Normal file
51
docs/fiddles/ipc/webview-new-window/main.js
Normal file
@@ -0,0 +1,51 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
webviewTag: true
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.webContents.on('did-attach-webview', (event, wc) => {
|
||||
wc.setWindowOpenHandler((details) => {
|
||||
mainWindow.webContents.send('webview-new-window', wc.id, details)
|
||||
return { action: 'deny' }
|
||||
})
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
})
|
||||
})
|
||||
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
// for applications and their menu bar to stay active until the user quits
|
||||
// explicitly with Cmd + Q.
|
||||
app.on('window-all-closed', function () {
|
||||
if (process.platform !== 'darwin') app.quit()
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
6
docs/fiddles/ipc/webview-new-window/preload.js
Normal file
6
docs/fiddles/ipc/webview-new-window/preload.js
Normal file
@@ -0,0 +1,6 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
const webview = document.getElementById('webview')
|
||||
ipcRenderer.on('webview-new-window', (e, webContentsId, details) => {
|
||||
console.log('webview-new-window', webContentsId, details)
|
||||
webview.dispatchEvent(new Event('new-window'))
|
||||
})
|
||||
4
docs/fiddles/ipc/webview-new-window/renderer.js
Normal file
4
docs/fiddles/ipc/webview-new-window/renderer.js
Normal file
@@ -0,0 +1,4 @@
|
||||
const webview = document.getElementById('webview')
|
||||
webview.addEventListener('new-window', () => {
|
||||
console.log('got new-window event')
|
||||
})
|
||||
@@ -84,7 +84,7 @@ the `sandbox: false` preference in the [`BrowserWindow`][browser-window] constru
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow({
|
||||
webPreferences: {
|
||||
sandbox: true
|
||||
sandbox: false
|
||||
}
|
||||
})
|
||||
win.loadURL('https://google.com')
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"@azure/storage-blob": "^12.9.0",
|
||||
"@electron/docs-parser": "^1.0.0",
|
||||
"@electron/fiddle-core": "^1.0.4",
|
||||
"@electron/github-app-auth": "^1.5.0",
|
||||
"@electron/github-app-auth": "^2.0.0",
|
||||
"@electron/typescript-definitions": "^8.10.0",
|
||||
"@octokit/rest": "^19.0.7",
|
||||
"@primer/octicons": "^10.0.0",
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
fix_rename_webswapcgllayer_to_webswapcgllayerchromium.patch
|
||||
cherry-pick-55e2b6daba9d.patch
|
||||
cherry-pick-ce029c91a662.patch
|
||||
cherry-pick-aed05b609629.patch
|
||||
translator_limit_the_size_of_private_variables_in_webgl_shaders.patch
|
||||
webgl_limit_total_size_of_private_data.patch
|
||||
|
||||
136
patches/angle/cherry-pick-55e2b6daba9d.patch
Normal file
136
patches/angle/cherry-pick-55e2b6daba9d.patch
Normal file
@@ -0,0 +1,136 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Thu, 16 Feb 2023 23:16:46 -0500
|
||||
Subject: Vulkan: Don't close render pass if rebind to same fbo
|
||||
|
||||
M108 merge issues:
|
||||
src/libANGLE/renderer/vulkan/ContextVk.cpp:
|
||||
- hasActiveRenderPass named hasStartedRenderPass in 108
|
||||
- getLastRenderPassQueueSerial named getLastRenderPassSerial in 108
|
||||
|
||||
In the Vulkan backend, the render pass can occasionally (and
|
||||
transiently) be in a state of "open but inactive". This is when the
|
||||
render pass is closed, but has the potential for future modifications
|
||||
(for example to add a resolve attachment). Under many circumstances, it
|
||||
is expected that an open render pass cannot be in such a state.
|
||||
|
||||
This assumption can be broken in this scenario:
|
||||
|
||||
- Open render pass, draw, etc
|
||||
- Change framebuffer binding
|
||||
- Change framebuffer binding back to original
|
||||
- Masked Clear
|
||||
|
||||
When ContextVk is synced before clear, it sees that the framebuffer
|
||||
binding is changed (though it hasn't really), and it closes the render
|
||||
passes and sets the render pass dirty bit. If a draw were to follow, a
|
||||
new render pass would have started (unnecessarily). However, in the
|
||||
case of a masked clear, UtilsVk notices that the render pass is started,
|
||||
assumes it must be active, and continues recording to it. While the
|
||||
operation itself succeeds, the assumption that the render pass is active
|
||||
is false (and fails assertion).
|
||||
|
||||
This change makes sure that framebuffer binding change is no-oped if the
|
||||
framebuffer is the same one that has opened the current render pass. If
|
||||
any application does unnecessary binding changes and back, it will be
|
||||
optimized by this change as well.
|
||||
|
||||
Bug: chromium:1411210
|
||||
Change-Id: I37a3a9f2eaa1a81a1b3393840b9458ec71a87377
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4261215
|
||||
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
(cherry picked from commit 05e62f39412e8c6bfc98582f5e7a49041991c97b)
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4303738
|
||||
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
|
||||
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
|
||||
index f08877444f66ac2d61953c9c56d4c71d253d53c6..31e1882c8923b81bf5fd74fbe40d8233c7551ec9 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
|
||||
@@ -5022,6 +5022,15 @@ angle::Result ContextVk::syncState(const gl::Context *context,
|
||||
// as some optimizations in non-draw commands require the render pass to remain
|
||||
// open, such as invalidate or blit. Note that we always start a new command buffer
|
||||
// because we currently can only support one open RenderPass at a time.
|
||||
+ //
|
||||
+ // The render pass is not closed if binding is changed to the same framebuffer as
|
||||
+ // before.
|
||||
+ if (hasStartedRenderPass() &&
|
||||
+ hasStartedRenderPassWithSerial(drawFramebufferVk->getLastRenderPassSerial()))
|
||||
+ {
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
onRenderPassFinished(RenderPassClosureReason::FramebufferBindingChange);
|
||||
if (getFeatures().preferSubmitAtFBOBoundary.enabled)
|
||||
{
|
||||
diff --git a/src/tests/gl_tests/ClearTest.cpp b/src/tests/gl_tests/ClearTest.cpp
|
||||
index 1a6b425da6be1e1c2526a8f5e5d84ea8049ee7ab..41e3ea7efe26d1aa0e0dd0e8e9d5bcd7b6472017 100644
|
||||
--- a/src/tests/gl_tests/ClearTest.cpp
|
||||
+++ b/src/tests/gl_tests/ClearTest.cpp
|
||||
@@ -2864,6 +2864,26 @@ TEST_P(ClearTest, DISABLED_ClearReachesWindow)
|
||||
angle::Sleep(2000);
|
||||
}
|
||||
|
||||
+// Tests that masked clear after a no-op framebuffer binding change with an open render pass works.
|
||||
+TEST_P(ClearTest, DrawThenChangeFBOBindingAndBackThenMaskedClear)
|
||||
+{
|
||||
+ ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
|
||||
+
|
||||
+ // Draw blue.
|
||||
+ drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
|
||||
+
|
||||
+ // Change framebuffer and back
|
||||
+ glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
|
||||
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
+
|
||||
+ // Masked clear
|
||||
+ glColorMask(1, 0, 0, 1);
|
||||
+ glClearColor(1.0f, 0.5f, 0.5f, 1.0f);
|
||||
+ glClear(GL_COLOR_BUFFER_BIT);
|
||||
+
|
||||
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
|
||||
+}
|
||||
+
|
||||
// Test that clearing slices of a 3D texture and reading them back works.
|
||||
TEST_P(ClearTestES3, ClearAndReadPixels3DTexture)
|
||||
{
|
||||
diff --git a/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp b/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp
|
||||
index 7268d08da90e27022f7139aa98b5972e1dfe62f1..6a91ecc2b4329696f573db3451dac35a0a795c8c 100644
|
||||
--- a/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp
|
||||
+++ b/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp
|
||||
@@ -5,7 +5,7 @@
|
||||
//
|
||||
// VulkanPerformanceCounterTest:
|
||||
// Validates specific GL call patterns with ANGLE performance counters.
|
||||
-// For example we can verify a certain call set doesn't break the RenderPass.
|
||||
+// For example we can verify a certain call set doesn't break the render pass.
|
||||
|
||||
#include "test_utils/ANGLETest.h"
|
||||
#include "test_utils/angle_test_instantiate.h"
|
||||
@@ -6991,6 +6991,26 @@ TEST_P(VulkanPerformanceCounterTest, EndXfbAfterRenderPassClosed)
|
||||
EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);
|
||||
}
|
||||
|
||||
+// Verify that changing framebuffer and back doesn't break the render pass.
|
||||
+TEST_P(VulkanPerformanceCounterTest, FBOChangeAndBackDoesNotBreakRenderPass)
|
||||
+{
|
||||
+ uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;
|
||||
+
|
||||
+ ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
|
||||
+ drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0);
|
||||
+
|
||||
+ GLFramebuffer fbo;
|
||||
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
+
|
||||
+ drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0);
|
||||
+
|
||||
+ // Verify render pass count.
|
||||
+ EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);
|
||||
+
|
||||
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
|
||||
+}
|
||||
+
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanPerformanceCounterTest);
|
||||
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest, ES3_VULKAN(), ES3_VULKAN_SWIFTSHADER());
|
||||
|
||||
108
patches/angle/cherry-pick-aed05b609629.patch
Normal file
108
patches/angle/cherry-pick-aed05b609629.patch
Normal file
@@ -0,0 +1,108 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Lang <geofflang@chromium.org>
|
||||
Date: Fri, 31 Mar 2023 16:44:35 -0400
|
||||
Subject: M112: Mark RGBX and BGRX formats as having 8 unused bits.
|
||||
|
||||
This makes sure that pixelBytes ends up being 4 and fixes potential
|
||||
buffer size validation.
|
||||
|
||||
Fix EGL configs using pixelBytes to compute EGL_BUFFER_SIZE which
|
||||
is not supposed to include unused bits. This is covered by
|
||||
dEQP-EGL.functional.query_config.constraints.color_buffer_size
|
||||
|
||||
Bug: chromium:1404790
|
||||
Change-Id: Ie0480cbdc6229c4bb3a6c6242337eaed5a3ae3b7
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4428752
|
||||
Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
|
||||
|
||||
diff --git a/src/libANGLE/formatutils.cpp b/src/libANGLE/formatutils.cpp
|
||||
index 76273f3be3406a1c4be11c8fe564e3f703aed4b9..4014953311976b0f1ae2d1842e8fced75ffecfc9 100644
|
||||
--- a/src/libANGLE/formatutils.cpp
|
||||
+++ b/src/libANGLE/formatutils.cpp
|
||||
@@ -549,6 +549,21 @@ bool InternalFormat::isDepthOrStencil() const
|
||||
return depthBits != 0 || stencilBits != 0;
|
||||
}
|
||||
|
||||
+GLuint InternalFormat::getEGLConfigBufferSize() const
|
||||
+{
|
||||
+ // EGL config's EGL_BUFFER_SIZE is measured in bits and is the sum of all the color channels for
|
||||
+ // color formats or the luma channels for luma formats. It ignores unused bits so compute the
|
||||
+ // bit count by summing instead of using pixelBytes.
|
||||
+ if (isLUMA())
|
||||
+ {
|
||||
+ return luminanceBits + alphaBits;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return redBits + greenBits + blueBits + alphaBits;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
Format::Format(GLenum internalFormat) : Format(GetSizedInternalFormatInfo(internalFormat)) {}
|
||||
|
||||
Format::Format(const InternalFormat &internalFormat) : info(&internalFormat) {}
|
||||
@@ -1141,10 +1156,10 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap()
|
||||
AddRGBAFormat(&map, GL_BGR10_A2_ANGLEX, true, 10, 10, 10, 2, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
|
||||
|
||||
// Special format to emulate RGB8 with RGBA8 within ANGLE.
|
||||
- AddRGBAFormat(&map, GL_RGBX8_ANGLE, true, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported, NeverSupported);
|
||||
+ AddRGBAXFormat(&map, GL_RGBX8_ANGLE, true, FB< 8, 8, 8, 0, 8, 0>(), GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported, NeverSupported);
|
||||
|
||||
// Special format to emulate BGR8 with BGRA8 within ANGLE.
|
||||
- AddRGBAFormat(&map, GL_BGRX8_ANGLEX, true, 8, 8, 8, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
|
||||
+ AddRGBAXFormat(&map, GL_BGRX8_ANGLEX, true, FB< 8, 8, 8, 0, 8, 0>(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
|
||||
|
||||
// This format is supported on ES 2.0 with two extensions, so keep it out-of-line to not widen the table above even more.
|
||||
// | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
|
||||
diff --git a/src/libANGLE/formatutils.h b/src/libANGLE/formatutils.h
|
||||
index 64cc42ec1f50ea017216063896ba2c07296cde37..e6154072365a8a253937a3f148ae12f7199c593c 100644
|
||||
--- a/src/libANGLE/formatutils.h
|
||||
+++ b/src/libANGLE/formatutils.h
|
||||
@@ -205,6 +205,8 @@ struct InternalFormat
|
||||
bool isInt() const;
|
||||
bool isDepthOrStencil() const;
|
||||
|
||||
+ GLuint getEGLConfigBufferSize() const;
|
||||
+
|
||||
bool operator==(const InternalFormat &other) const;
|
||||
bool operator!=(const InternalFormat &other) const;
|
||||
|
||||
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
|
||||
index cc56e9868248a192b6c22e650528986c88722503..040623866da9b78ca66efb7de4f8678dd98f5f1c 100644
|
||||
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
|
||||
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
|
||||
@@ -1242,7 +1242,7 @@ egl::ConfigSet Renderer11::generateConfigs()
|
||||
egl::Config config;
|
||||
config.renderTargetFormat = colorBufferInternalFormat;
|
||||
config.depthStencilFormat = depthStencilBufferInternalFormat;
|
||||
- config.bufferSize = colorBufferFormatInfo.pixelBytes * 8;
|
||||
+ config.bufferSize = colorBufferFormatInfo.getEGLConfigBufferSize();
|
||||
config.redSize = colorBufferFormatInfo.redBits;
|
||||
config.greenSize = colorBufferFormatInfo.greenBits;
|
||||
config.blueSize = colorBufferFormatInfo.blueBits;
|
||||
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
|
||||
index d80997392d2d5d25cadc1381c84929401bce90a9..6979fe5445360e6703cdb35fd9a15a6e34d188c8 100644
|
||||
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
|
||||
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
|
||||
@@ -523,7 +523,7 @@ egl::ConfigSet Renderer9::generateConfigs()
|
||||
egl::Config config;
|
||||
config.renderTargetFormat = colorBufferInternalFormat;
|
||||
config.depthStencilFormat = depthStencilBufferInternalFormat;
|
||||
- config.bufferSize = colorBufferFormatInfo.pixelBytes * 8;
|
||||
+ config.bufferSize = colorBufferFormatInfo.getEGLConfigBufferSize();
|
||||
config.redSize = colorBufferFormatInfo.redBits;
|
||||
config.greenSize = colorBufferFormatInfo.greenBits;
|
||||
config.blueSize = colorBufferFormatInfo.blueBits;
|
||||
diff --git a/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp b/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
|
||||
index f49b24744682910ae5142f784c9e01ba1977c360..f601b516441fdb4db9e17db5ad22cb6198755e99 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
|
||||
@@ -1238,7 +1238,7 @@ egl::Config GenerateDefaultConfig(DisplayVk *display,
|
||||
|
||||
config.renderTargetFormat = colorFormat.internalFormat;
|
||||
config.depthStencilFormat = depthStencilFormat.internalFormat;
|
||||
- config.bufferSize = colorFormat.pixelBytes * 8;
|
||||
+ config.bufferSize = colorFormat.getEGLConfigBufferSize();
|
||||
config.redSize = colorFormat.redBits;
|
||||
config.greenSize = colorFormat.greenBits;
|
||||
config.blueSize = colorFormat.blueBits;
|
||||
158
patches/angle/cherry-pick-ce029c91a662.patch
Normal file
158
patches/angle/cherry-pick-ce029c91a662.patch
Normal file
@@ -0,0 +1,158 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Lang <geofflang@chromium.org>
|
||||
Date: Fri, 10 Mar 2023 13:48:03 -0500
|
||||
Subject: M110: D3D11: Add logic to disassociate EGL image storages.
|
||||
|
||||
The TextureStorage classes for External and EGLImages were missing the
|
||||
logic to disassociate from images. This lead to the images continuing
|
||||
to hold references to deleted storages.
|
||||
|
||||
Bug: chromium:1415330
|
||||
Change-Id: I8303f6751d87a9b0a52993c7d4e9509b086b93f3
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4328347
|
||||
Reviewed-by: Peng Huang <penghuang@chromium.org>
|
||||
Commit-Queue: Geoff Lang <geofflang@chromium.org>
|
||||
(cherry picked from commit a8720455fda43167465c3d2f9a13fca60c21f56e)
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4348335
|
||||
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
|
||||
diff --git a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
|
||||
index f1277462a929ed867a325f12db5fbf011b3f678e..c2fe439ca826e86b023dbe982ff44dd3bfb56470 100644
|
||||
--- a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
|
||||
+++ b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
|
||||
@@ -1652,7 +1652,8 @@ TextureStorage11_External::TextureStorage11_External(
|
||||
egl::Stream *stream,
|
||||
const egl::Stream::GLTextureDescription &glDesc,
|
||||
const std::string &label)
|
||||
- : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat, label)
|
||||
+ : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat, label),
|
||||
+ mAssociatedImage(nullptr)
|
||||
{
|
||||
ASSERT(stream->getProducerType() == egl::Stream::ProducerType::D3D11Texture);
|
||||
auto *producer = static_cast<StreamProducerD3DTexture *>(stream->getImplementation());
|
||||
@@ -1678,6 +1679,15 @@ angle::Result TextureStorage11_External::onDestroy(const gl::Context *context)
|
||||
mRenderer->getStateManager()->invalidateBoundViews();
|
||||
}
|
||||
|
||||
+ if (mAssociatedImage != nullptr)
|
||||
+ {
|
||||
+ mAssociatedImage->verifyAssociatedStorageValid(this);
|
||||
+
|
||||
+ // We must let the Images recover their data before we delete it from the
|
||||
+ // TextureStorage.
|
||||
+ ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context));
|
||||
+ }
|
||||
+
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
@@ -1885,7 +1895,8 @@ TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer,
|
||||
mImage(eglImage),
|
||||
mCurrentRenderTarget(0),
|
||||
mSwizzleTexture(),
|
||||
- mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
|
||||
+ mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS),
|
||||
+ mAssociatedImage(nullptr)
|
||||
{
|
||||
mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);
|
||||
|
||||
@@ -1897,6 +1908,20 @@ TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer,
|
||||
|
||||
TextureStorage11_EGLImage::~TextureStorage11_EGLImage() {}
|
||||
|
||||
+angle::Result TextureStorage11_EGLImage::onDestroy(const gl::Context *context)
|
||||
+{
|
||||
+ if (mAssociatedImage != nullptr)
|
||||
+ {
|
||||
+ mAssociatedImage->verifyAssociatedStorageValid(this);
|
||||
+
|
||||
+ // We must let the Images recover their data before we delete it from the
|
||||
+ // TextureStorage.
|
||||
+ ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context));
|
||||
+ }
|
||||
+
|
||||
+ return angle::Result::Continue;
|
||||
+}
|
||||
+
|
||||
angle::Result TextureStorage11_EGLImage::getSubresourceIndex(const gl::Context *context,
|
||||
const gl::ImageIndex &index,
|
||||
UINT *outSubresourceIndex) const
|
||||
@@ -2120,6 +2145,42 @@ void TextureStorage11_EGLImage::onLabelUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
+void TextureStorage11_EGLImage::associateImage(Image11 *image, const gl::ImageIndex &index)
|
||||
+{
|
||||
+ ASSERT(index.getLevelIndex() == 0);
|
||||
+ mAssociatedImage = image;
|
||||
+}
|
||||
+
|
||||
+void TextureStorage11_EGLImage::verifyAssociatedImageValid(const gl::ImageIndex &index,
|
||||
+ Image11 *expectedImage)
|
||||
+{
|
||||
+ ASSERT(index.getLevelIndex() == 0 && mAssociatedImage == expectedImage);
|
||||
+}
|
||||
+
|
||||
+void TextureStorage11_EGLImage::disassociateImage(const gl::ImageIndex &index,
|
||||
+ Image11 *expectedImage)
|
||||
+{
|
||||
+ ASSERT(index.getLevelIndex() == 0);
|
||||
+ ASSERT(mAssociatedImage == expectedImage);
|
||||
+ mAssociatedImage = nullptr;
|
||||
+}
|
||||
+
|
||||
+angle::Result TextureStorage11_EGLImage::releaseAssociatedImage(const gl::Context *context,
|
||||
+ const gl::ImageIndex &index,
|
||||
+ Image11 *incomingImage)
|
||||
+{
|
||||
+ ASSERT(index.getLevelIndex() == 0);
|
||||
+
|
||||
+ if (mAssociatedImage != nullptr && mAssociatedImage != incomingImage)
|
||||
+ {
|
||||
+ mAssociatedImage->verifyAssociatedStorageValid(this);
|
||||
+
|
||||
+ ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context));
|
||||
+ }
|
||||
+
|
||||
+ return angle::Result::Continue;
|
||||
+}
|
||||
+
|
||||
TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer,
|
||||
GLenum internalformat,
|
||||
BindFlags bindFlags,
|
||||
diff --git a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
|
||||
index 72bc1b802c5d4f2befe7a440aae8e115d5b94c8a..7c5245acd8fcb7880f19905c0f69c7b7886e9e72 100644
|
||||
--- a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
|
||||
+++ b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
|
||||
@@ -492,6 +492,8 @@ class TextureStorage11_EGLImage final : public TextureStorage11ImmutableBase
|
||||
const std::string &label);
|
||||
~TextureStorage11_EGLImage() override;
|
||||
|
||||
+ angle::Result onDestroy(const gl::Context *context) override;
|
||||
+
|
||||
angle::Result getSubresourceIndex(const gl::Context *context,
|
||||
const gl::ImageIndex &index,
|
||||
UINT *outSubresourceIndex) const override;
|
||||
@@ -518,6 +520,13 @@ class TextureStorage11_EGLImage final : public TextureStorage11ImmutableBase
|
||||
bool useLevelZeroTexture) override;
|
||||
void onLabelUpdate() override;
|
||||
|
||||
+ void associateImage(Image11 *image, const gl::ImageIndex &index) override;
|
||||
+ void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
|
||||
+ void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
|
||||
+ angle::Result releaseAssociatedImage(const gl::Context *context,
|
||||
+ const gl::ImageIndex &index,
|
||||
+ Image11 *incomingImage) override;
|
||||
+
|
||||
protected:
|
||||
angle::Result getSwizzleTexture(const gl::Context *context,
|
||||
const TextureHelper11 **outTexture) override;
|
||||
@@ -545,6 +554,8 @@ class TextureStorage11_EGLImage final : public TextureStorage11ImmutableBase
|
||||
// Swizzle-related variables
|
||||
TextureHelper11 mSwizzleTexture;
|
||||
std::vector<d3d11::RenderTargetView> mSwizzleRenderTargets;
|
||||
+
|
||||
+ Image11 *mAssociatedImage;
|
||||
};
|
||||
|
||||
class TextureStorage11_Cube : public TextureStorage11
|
||||
@@ -0,0 +1,87 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Tue, 28 Mar 2023 11:43:23 -0400
|
||||
Subject: Translator: Limit the size of private variables in WebGL shaders
|
||||
|
||||
As a follow up to
|
||||
https://chromium-review.googlesource.com/c/angle/angle/+/3023033, the
|
||||
limit to shader-private variables (locals and globals) is further
|
||||
reduced to 1MB. A variable that large will not fit in GPU registers and
|
||||
will spill to memory, killing performance.
|
||||
|
||||
Bug: chromium:1427865
|
||||
Change-Id: I77314d4b891c591cd9a83ad2aebb77d7256f3ada
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4377639
|
||||
Reviewed-by: Kenneth Russell <kbr@chromium.org>
|
||||
|
||||
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
index c9607db74b53487950d31f6a56d55f3e834556a0..6097b6d236b547710aeaf37a6fb45df97d621ca0 100644
|
||||
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
@@ -20,9 +20,13 @@ namespace sh
|
||||
namespace
|
||||
{
|
||||
|
||||
-// Arbitrarily enforce that types - even local variables' - declared
|
||||
-// with a size in bytes of over 2 GB will cause compilation failure.
|
||||
-constexpr size_t kMaxTypeSizeInBytes = static_cast<size_t>(2) * 1024 * 1024 * 1024;
|
||||
+// 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 (1MB) 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>(1) * 1024 * 1024;
|
||||
|
||||
// Traverses intermediate tree to ensure that the shader does not
|
||||
// exceed certain implementation-defined limits on the sizes of types.
|
||||
@@ -78,13 +82,24 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
|
||||
// whether the row-major layout is correctly determined.
|
||||
bool isRowMajorLayout = false;
|
||||
TraverseShaderVariable(shaderVar, isRowMajorLayout, &visitor);
|
||||
- if (layoutEncoder.getCurrentOffset() > kMaxTypeSizeInBytes)
|
||||
+ if (layoutEncoder.getCurrentOffset() > kMaxVariableSizeInBytes)
|
||||
{
|
||||
error(asSymbol->getLine(),
|
||||
"Size of declared variable exceeds implementation-defined limit",
|
||||
asSymbol->getName());
|
||||
return false;
|
||||
}
|
||||
+
|
||||
+ const bool isPrivate = variableType.getQualifier() == EvqTemporary ||
|
||||
+ variableType.getQualifier() == EvqGlobal ||
|
||||
+ variableType.getQualifier() == EvqConst;
|
||||
+ if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes && isPrivate)
|
||||
+ {
|
||||
+ error(asSymbol->getLine(),
|
||||
+ "Size of declared private variable exceeds implementation-defined limit",
|
||||
+ asSymbol->getName());
|
||||
+ return false;
|
||||
+ }
|
||||
}
|
||||
|
||||
return true;
|
||||
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
index 7dc56cddbc63add1aca6fca3bfd031f3da8d04fc..f4bd19baf3582c0b4a840d73a57ea6fc385159a6 100644
|
||||
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
@@ -5283,8 +5283,8 @@ void main()
|
||||
|
||||
constexpr char kVSArrayTooLarge[] =
|
||||
R"(varying vec4 color;
|
||||
-// 2 GB / 32 aligned bytes per mat2 = 67108864
|
||||
-const int array_size = 67108865;
|
||||
+// 1 MB / 32 aligned bytes per mat2 = 32768
|
||||
+const int array_size = 32769;
|
||||
void main()
|
||||
{
|
||||
mat2 array[array_size];
|
||||
@@ -5296,7 +5296,7 @@ void main()
|
||||
|
||||
constexpr char kVSArrayMuchTooLarge[] =
|
||||
R"(varying vec4 color;
|
||||
-const int array_size = 556007917;
|
||||
+const int array_size = 55600;
|
||||
void main()
|
||||
{
|
||||
mat2 array[array_size];
|
||||
207
patches/angle/webgl_limit_total_size_of_private_data.patch
Normal file
207
patches/angle/webgl_limit_total_size_of_private_data.patch
Normal file
@@ -0,0 +1,207 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Wed, 3 May 2023 13:41:36 -0400
|
||||
Subject: WebGL: Limit total size of private data
|
||||
|
||||
... not just individual arrays.
|
||||
|
||||
Bug: chromium:1431761
|
||||
Change-Id: I721e29aeceeaf12c3f6a67b668abffb8dfbc89b0
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4503753
|
||||
Reviewed-by: Kenneth Russell <kbr@chromium.org>
|
||||
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
|
||||
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
index 6097b6d236b547710aeaf37a6fb45df97d621ca0..2a033ad9d9422349865a9f2af7084bbf1c2c23d9 100644
|
||||
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
@@ -35,7 +35,9 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
ValidateTypeSizeLimitationsTraverser(TSymbolTable *symbolTable, TDiagnostics *diagnostics)
|
||||
- : TIntermTraverser(true, false, false, symbolTable), mDiagnostics(diagnostics)
|
||||
+ : TIntermTraverser(true, false, false, symbolTable),
|
||||
+ mDiagnostics(diagnostics),
|
||||
+ mTotalPrivateVariablesSize(0)
|
||||
{
|
||||
ASSERT(diagnostics);
|
||||
}
|
||||
@@ -93,18 +95,33 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
|
||||
const bool isPrivate = variableType.getQualifier() == EvqTemporary ||
|
||||
variableType.getQualifier() == EvqGlobal ||
|
||||
variableType.getQualifier() == EvqConst;
|
||||
- if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes && isPrivate)
|
||||
+ if (isPrivate)
|
||||
{
|
||||
- error(asSymbol->getLine(),
|
||||
- "Size of declared private variable exceeds implementation-defined limit",
|
||||
- asSymbol->getName());
|
||||
- return false;
|
||||
+ if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes)
|
||||
+ {
|
||||
+ error(asSymbol->getLine(),
|
||||
+ "Size of declared private variable exceeds implementation-defined limit",
|
||||
+ asSymbol->getName());
|
||||
+ return false;
|
||||
+ }
|
||||
+ mTotalPrivateVariablesSize += layoutEncoder.getCurrentOffset();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+ void validateTotalPrivateVariableSize()
|
||||
+ {
|
||||
+ if (mTotalPrivateVariablesSize > kMaxPrivateVariableSizeInBytes)
|
||||
+ {
|
||||
+ mDiagnostics->error(
|
||||
+ TSourceLoc{},
|
||||
+ "Total size of declared private variables exceeds implementation-defined limit",
|
||||
+ "");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
void error(TSourceLoc loc, const char *reason, const ImmutableString &token)
|
||||
{
|
||||
@@ -213,6 +230,8 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
|
||||
|
||||
TDiagnostics *mDiagnostics;
|
||||
std::vector<int> mLoopSymbolIds;
|
||||
+
|
||||
+ size_t mTotalPrivateVariablesSize;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -223,6 +242,7 @@ bool ValidateTypeSizeLimitations(TIntermNode *root,
|
||||
{
|
||||
ValidateTypeSizeLimitationsTraverser validate(symbolTable, diagnostics);
|
||||
root->traverse(&validate);
|
||||
+ validate.validateTotalPrivateVariableSize();
|
||||
return diagnostics->numErrors() == 0;
|
||||
}
|
||||
|
||||
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
index f4bd19baf3582c0b4a840d73a57ea6fc385159a6..1b265568fc8a87280cc192fbd573a8b11dfb29ec 100644
|
||||
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
@@ -5271,11 +5271,12 @@ TEST_P(WebGLCompatibilityTest, ValidateArraySizes)
|
||||
// fairly small array.
|
||||
constexpr char kVSArrayOK[] =
|
||||
R"(varying vec4 color;
|
||||
-const int array_size = 1000;
|
||||
+const int array_size = 500;
|
||||
void main()
|
||||
{
|
||||
mat2 array[array_size];
|
||||
- if (array[0][0][0] == 2.0)
|
||||
+ mat2 array2[array_size];
|
||||
+ if (array[0][0][0] + array2[0][0][0] == 2.0)
|
||||
color = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
else
|
||||
color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
@@ -5353,6 +5354,103 @@ void main()
|
||||
EXPECT_EQ(0u, program);
|
||||
}
|
||||
|
||||
+// Reject attempts to allocate too much private memory.
|
||||
+// This is an implementation-defined limit - crbug.com/1431761.
|
||||
+TEST_P(WebGLCompatibilityTest, ValidateTotalPrivateSize)
|
||||
+{
|
||||
+ constexpr char kTooLargeGlobalMemory1[] =
|
||||
+ R"(precision mediump float;
|
||||
+
|
||||
+// 1 MB / 16 bytes per vec4 = 65536
|
||||
+vec4 array[32768];
|
||||
+vec4 array2[32769];
|
||||
+
|
||||
+void main()
|
||||
+{
|
||||
+ if (array[0].x + array[1].x == 0.)
|
||||
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
+ else
|
||||
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ constexpr char kTooLargeGlobalMemory2[] =
|
||||
+ R"(precision mediump float;
|
||||
+
|
||||
+// 1 MB / 16 bytes per vec4 = 65536
|
||||
+vec4 array[32767];
|
||||
+vec4 array2[32767];
|
||||
+vec4 x, y, z;
|
||||
+
|
||||
+void main()
|
||||
+{
|
||||
+ if (array[0].x + array[1].x == x.w + y.w + z.w)
|
||||
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
+ else
|
||||
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ constexpr char kTooLargeGlobalAndLocalMemory1[] =
|
||||
+ R"(precision mediump float;
|
||||
+
|
||||
+// 1 MB / 16 bytes per vec4 = 65536
|
||||
+vec4 array[32768];
|
||||
+
|
||||
+void main()
|
||||
+{
|
||||
+ vec4 array2[32769];
|
||||
+ if (array[0].x + array[1].x == 2.0)
|
||||
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
+ else
|
||||
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ // Note: The call stack is not taken into account for the purposes of total memory calculation.
|
||||
+ constexpr char kTooLargeGlobalAndLocalMemory2[] =
|
||||
+ R"(precision mediump float;
|
||||
+
|
||||
+// 1 MB / 16 bytes per vec4 = 65536
|
||||
+vec4 array[32768];
|
||||
+
|
||||
+float f()
|
||||
+{
|
||||
+ vec4 array2[16384];
|
||||
+ return array2[0].x;
|
||||
+}
|
||||
+
|
||||
+float g()
|
||||
+{
|
||||
+ vec4 array3[16383];
|
||||
+ return array3[0].x;
|
||||
+}
|
||||
+
|
||||
+float h()
|
||||
+{
|
||||
+ vec4 value;
|
||||
+ float value2
|
||||
+ return value.x + value2;
|
||||
+}
|
||||
+
|
||||
+void main()
|
||||
+{
|
||||
+ if (array[0].x + f() + g() + h() == 2.0)
|
||||
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
+ else
|
||||
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ GLuint program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory1);
|
||||
+ EXPECT_EQ(0u, program);
|
||||
+
|
||||
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory2);
|
||||
+ EXPECT_EQ(0u, program);
|
||||
+
|
||||
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory1);
|
||||
+ EXPECT_EQ(0u, program);
|
||||
+
|
||||
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory2);
|
||||
+ EXPECT_EQ(0u, program);
|
||||
+}
|
||||
+
|
||||
// Linking should fail when corresponding vertex/fragment uniform blocks have different precision
|
||||
// qualifiers.
|
||||
TEST_P(WebGL2CompatibilityTest, UniformBlockPrecisionMismatch)
|
||||
@@ -127,3 +127,42 @@ cherry-pick-3235c1d1955b.patch
|
||||
expose_v8initializer_codegenerationcheckcallbackinmainthread.patch
|
||||
cherry-pick-43637378b14e.patch
|
||||
axselectedtextmarkerrange_should_not_be_backwards.patch
|
||||
fix_x11_window_restore_minimized_maximized_window.patch
|
||||
m108-lts_simplify_webmediaplayermscompositor_destruction.patch
|
||||
m108-lts_further_simplify_webmediaplayermscompositor_lifetime.patch
|
||||
cherry-pick-e79b89b47dac.patch
|
||||
cherry-pick-06851790480e.patch
|
||||
cherry-pick-aeec1ba5893d.patch
|
||||
cherry-pick-0407102d19b9.patch
|
||||
fix_crash_in_annotationagentimpl.patch
|
||||
cherry-pick-bfd926be8178.patch
|
||||
cherry-pick-9aa4c45f21b1.patch
|
||||
m108-lts_do_not_register_browser_watcher_activity_report_with.patch
|
||||
prevent_potential_integer_overflow_in_persistentmemoryallocator_1_2.patch
|
||||
m108-lts_prevent_potential_integer_overflow_in.patch
|
||||
cherry-pick-38de42d2bbc3.patch
|
||||
cherry-pick-8731bd8a30f6.patch
|
||||
cherry-pick-26bfa5807606.patch
|
||||
cherry-pick-b5c9e5efe5dd.patch
|
||||
cherry-pick-56bd20b295b4.patch
|
||||
cherry-pick-1235110fce18.patch
|
||||
cherry-pick-b041159d06ad.patch
|
||||
cherry-pick-d6946b70b431.patch
|
||||
cherry-pick-d9081493c4b2.patch
|
||||
cherry-pick-2b30a50d0e62.patch
|
||||
merge_m112_remove_the_second_weakptrfactory_from.patch
|
||||
merge_m112_check_spdyproxyclientsocket_is_alive_after_write.patch
|
||||
check_callback_availability_in.patch
|
||||
cherry-pick-63686953dc22.patch
|
||||
cherry-pick-f098ff0d1230.patch
|
||||
cherry-pick-f58218891f8c.patch
|
||||
wayland_ensure_dnd_buffer_size_is_a_multiple_of_scale.patch
|
||||
m112_cherry_pick_libxml_cve_fix.patch
|
||||
m112_fix_scopedobservation_uaf_in.patch
|
||||
cherry-pick-ea1cd76358e0.patch
|
||||
cherry-pick-48785f698b1c.patch
|
||||
m108-lts_return_after_readycommitnavigation_call_in_commiterrorpage.patch
|
||||
m114_merge_fix_a_crash_caused_by_calling_trace_event.patch
|
||||
base_do_not_use_va_args_twice_in_asprintf.patch
|
||||
cherry-pick-85beff6fd302.patch
|
||||
m114_webcodecs_fix_crash_when_changing_temporal_layer_count_in_av1.patch
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benoit Lize <lizeb@chromium.org>
|
||||
Date: Fri, 9 Jun 2023 17:59:08 +0000
|
||||
Subject: Do not use va_args twice in asprintf()
|
||||
|
||||
(cherry picked from commit 3cff0cb19a6d01cbdd9932f43dabaaeda9c0330a)
|
||||
|
||||
Bug: 1450536
|
||||
Change-Id: Ib34d96935278869a63897f9a1c66afc98865d90f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4579347
|
||||
Reviewed-by: Egor Pasko <pasko@chromium.org>
|
||||
Commit-Queue: Benoit Lize <lizeb@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1151796}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4604070
|
||||
Reviewed-by: Michael Thiessen <mthiesse@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5735@{#1224}
|
||||
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
|
||||
|
||||
diff --git a/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h b/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
|
||||
index 621873126602463a09efca1bf1548ed10910d323..de2af6d7d54e254b9e7b8264b53d30a338fb13e8 100644
|
||||
--- a/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
|
||||
+++ b/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
|
||||
@@ -123,13 +123,21 @@ SHIM_ALWAYS_EXPORT char* __wrap_getcwd(char* buffer, size_t size) {
|
||||
SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
|
||||
const char* fmt,
|
||||
va_list va_args) {
|
||||
+ // There are cases where we need to use the list of arguments twice, namely
|
||||
+ // when the original buffer is too small. It is not allowed to walk the list
|
||||
+ // twice, so make a copy for the second invocation of vsnprintf().
|
||||
+ va_list va_args_copy;
|
||||
+ va_copy(va_args_copy, va_args);
|
||||
+
|
||||
constexpr int kInitialSize = 128;
|
||||
*strp = static_cast<char*>(
|
||||
malloc(kInitialSize)); // Our malloc() doesn't return nullptr.
|
||||
|
||||
int actual_size = vsnprintf(*strp, kInitialSize, fmt, va_args);
|
||||
- if (actual_size < 0)
|
||||
+ if (actual_size < 0) {
|
||||
+ va_end(va_args_copy);
|
||||
return actual_size;
|
||||
+ }
|
||||
*strp =
|
||||
static_cast<char*>(realloc(*strp, static_cast<size_t>(actual_size + 1)));
|
||||
|
||||
@@ -139,9 +147,14 @@ SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
|
||||
//
|
||||
// This is very lightly used in Chromium in practice, see crbug.com/116558 for
|
||||
// details.
|
||||
- if (actual_size >= kInitialSize)
|
||||
- return vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt, va_args);
|
||||
-
|
||||
+ if (actual_size >= kInitialSize) {
|
||||
+ int ret = vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt,
|
||||
+ va_args_copy);
|
||||
+ va_end(va_args_copy);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ va_end(va_args_copy);
|
||||
return actual_size;
|
||||
}
|
||||
|
||||
diff --git a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
|
||||
index 6caf9d6ffe0db92602ac1e448f45da422e077c2c..57d36f722e1aa747cda3a808104cc108147552c1 100644
|
||||
--- a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
|
||||
+++ b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
|
||||
@@ -706,6 +706,28 @@ TEST_F(AllocatorShimTest, InterceptVasprintf) {
|
||||
// Should not crash.
|
||||
}
|
||||
|
||||
+TEST_F(AllocatorShimTest, InterceptLongVasprintf) {
|
||||
+ char* str = nullptr;
|
||||
+ const char* lorem_ipsum =
|
||||
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. "
|
||||
+ "Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, "
|
||||
+ "ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula "
|
||||
+ "massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci "
|
||||
+ "nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit "
|
||||
+ "amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat "
|
||||
+ "in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero "
|
||||
+ "pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo "
|
||||
+ "in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue "
|
||||
+ "blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus "
|
||||
+ "et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed "
|
||||
+ "pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales "
|
||||
+ "hendrerit.";
|
||||
+ int err = asprintf(&str, "%s", lorem_ipsum);
|
||||
+ EXPECT_EQ(err, static_cast<int>(strlen(lorem_ipsum)));
|
||||
+ EXPECT_TRUE(str);
|
||||
+ free(str);
|
||||
+}
|
||||
+
|
||||
#endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
|
||||
|
||||
#endif // BUILDFLAG(IS_ANDROID)
|
||||
36
patches/chromium/check_callback_availability_in.patch
Normal file
36
patches/chromium/check_callback_availability_in.patch
Normal file
@@ -0,0 +1,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Date: Tue, 18 Apr 2023 05:58:29 +0000
|
||||
Subject: Check callback availability in
|
||||
SpdyProxyClientSocket::RunWriteCallback
|
||||
|
||||
OnClose() could consume `write_callback_` so it may not be available
|
||||
when RunWriteCallback() is invoked.
|
||||
|
||||
Bug: 1428820
|
||||
Change-Id: I9a5ade62d67f5bf15e12d0915d1ad6098657ffd4
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4437791
|
||||
Code-Coverage: Findit <findit-for-me@appspot.gserviceaccount.com>
|
||||
Reviewed-by: Adam Rice <ricea@chromium.org>
|
||||
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1131689}
|
||||
|
||||
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc
|
||||
index d9b67febc27cc99e5b3383a372451345cec6daaa..bdcf24a1cb65f5df291bd91784d68aa9c05e7b0d 100644
|
||||
--- a/net/spdy/spdy_proxy_client_socket.cc
|
||||
+++ b/net/spdy/spdy_proxy_client_socket.cc
|
||||
@@ -278,10 +278,11 @@ int SpdyProxyClientSocket::GetLocalAddress(IPEndPoint* address) const {
|
||||
}
|
||||
|
||||
void SpdyProxyClientSocket::RunWriteCallback(int result) {
|
||||
- CHECK(write_callback_);
|
||||
-
|
||||
base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr();
|
||||
- std::move(write_callback_).Run(result);
|
||||
+ // `write_callback_` might be consumed by OnClose().
|
||||
+ if (write_callback_) {
|
||||
+ std::move(write_callback_).Run(result);
|
||||
+ }
|
||||
if (!weak_ptr) {
|
||||
// `this` was already destroyed while running `write_callback_`. Must
|
||||
// return immediately without touching any field member.
|
||||
91
patches/chromium/cherry-pick-0407102d19b9.patch
Normal file
91
patches/chromium/cherry-pick-0407102d19b9.patch
Normal file
@@ -0,0 +1,91 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Peter=20Bostr=C3=B6m?= <pbos@chromium.org>
|
||||
Date: Tue, 14 Mar 2023 16:49:10 +0000
|
||||
Subject: Convert known it != end() DCHECK failures to CHECK
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
These have hit on DCHECK builds in the wild and precede erasing or
|
||||
dereferencing an iterator that is UB.
|
||||
|
||||
This CL excludes DCHECK failures that precede non-DCHECK handling of the
|
||||
it != end() failures. Those should probably be rewritten as CHECKs
|
||||
but are less urgent and semi-orthogonal.
|
||||
|
||||
Known crashes (one per file) are:
|
||||
|
||||
crash/dc49e3cadab36d4c
|
||||
crash/0ee3427d25937024
|
||||
crash/b89303e84d123019
|
||||
crash/cc35183b861a4992
|
||||
|
||||
(cherry picked from commit 1aec0b297900a7b59bd24314dff239f3c5697f45)
|
||||
|
||||
Bug: 1418734
|
||||
Change-Id: I81ed7b45be33769e250c65c8bb7334a34be4380e
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4288168
|
||||
Commit-Queue: Peter Boström <pbos@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1109350}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4296138
|
||||
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Reviewed-by: Peter Boström <pbos@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1406}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/base/scoped_multi_source_observation.h b/base/scoped_multi_source_observation.h
|
||||
index 07ea3edd71246f02fe0044b33129f13699ce43b2..cd368c23956078acd6d5694f7f16c106f6461b31 100644
|
||||
--- a/base/scoped_multi_source_observation.h
|
||||
+++ b/base/scoped_multi_source_observation.h
|
||||
@@ -68,7 +68,7 @@ class ScopedMultiSourceObservation {
|
||||
// Remove the object passed to the constructor as an observer from |source|.
|
||||
void RemoveObservation(Source* source) {
|
||||
auto it = base::ranges::find(sources_, source);
|
||||
- DCHECK(it != sources_.end());
|
||||
+ CHECK(it != sources_.end());
|
||||
sources_.erase(it);
|
||||
(source->*RemoveObsFn)(observer_);
|
||||
}
|
||||
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc
|
||||
index 8a49e44647d8c6d35e7fa04dafbd32c06c153927..4ad050db8a3e590742501507d7777ba923ad3832 100644
|
||||
--- a/cc/tiles/gpu_image_decode_cache.cc
|
||||
+++ b/cc/tiles/gpu_image_decode_cache.cc
|
||||
@@ -1379,8 +1379,8 @@ Iterator GpuImageDecodeCache::RemoveFromPersistentCache(Iterator it) {
|
||||
}
|
||||
|
||||
auto entries_it = paint_image_entries_.find(it->second->paint_image_id);
|
||||
- DCHECK(entries_it != paint_image_entries_.end());
|
||||
- DCHECK_GT(entries_it->second.count, 0u);
|
||||
+ CHECK(entries_it != paint_image_entries_.end());
|
||||
+ CHECK_GT(entries_it->second.count, 0u);
|
||||
|
||||
// If this is the last entry for this image, remove its tracking.
|
||||
--entries_it->second.count;
|
||||
diff --git a/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc b/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc
|
||||
index 4f4fbb6c8775e1019a6c2938812f5535737433a3..9e9181677fb676100ff2a20890e902f298b16644 100644
|
||||
--- a/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc
|
||||
@@ -117,7 +117,7 @@ void AnnotationAgentImpl::ScrollIntoView() const {
|
||||
|
||||
EphemeralRangeInFlatTree range = attached_range_->ToEphemeralRange();
|
||||
|
||||
- DCHECK(range.Nodes().begin() != range.Nodes().end());
|
||||
+ CHECK(range.Nodes().begin() != range.Nodes().end());
|
||||
|
||||
Node& first_node = *range.Nodes().begin();
|
||||
|
||||
diff --git a/ui/base/interaction/element_tracker_mac.mm b/ui/base/interaction/element_tracker_mac.mm
|
||||
index d3b8d98e499a074678d7e06efcc2146d92ae3eb4..b467aa234043ebc8537bb4576ce0eed713593597 100644
|
||||
--- a/ui/base/interaction/element_tracker_mac.mm
|
||||
+++ b/ui/base/interaction/element_tracker_mac.mm
|
||||
@@ -50,7 +50,7 @@ void AddElement(ElementIdentifier identifier,
|
||||
|
||||
void ActivateElement(ElementIdentifier identifier) {
|
||||
const auto it = elements_.find(identifier);
|
||||
- DCHECK(it != elements_.end());
|
||||
+ CHECK(it != elements_.end());
|
||||
ui::ElementTracker::GetFrameworkDelegate()->NotifyElementActivated(
|
||||
it->second.get());
|
||||
}
|
||||
91
patches/chromium/cherry-pick-06851790480e.patch
Normal file
91
patches/chromium/cherry-pick-06851790480e.patch
Normal file
@@ -0,0 +1,91 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Tommy C. Li" <tommycli@chromium.org>
|
||||
Date: Tue, 21 Feb 2023 18:55:00 +0000
|
||||
Subject: Exclude Policy and Play API engines from Sync merging
|
||||
|
||||
There's a security bug in which the call to ResetTemplateURLGUID can
|
||||
cause a policy-created engine to be deleted. This means that after
|
||||
the call, either the current `conflicting_turl` pointer, or future
|
||||
iterations in the loop may point to an already-freed TemplateURL,
|
||||
causing the use-after free bug.
|
||||
|
||||
This CL addresses that by forbidding Policy-created and Play API
|
||||
engines from being merged into Synced engines.
|
||||
|
||||
Although Play API engines aren't directly affected, they seem to also
|
||||
not be something that should be merged to Synced engines.
|
||||
|
||||
(cherry picked from commit 315632458eb795ef9d9dce3fd1062f9e6f2c2077)
|
||||
|
||||
Bug: 1414224
|
||||
Change-Id: Ide43d71e9844e04a7ffe2e7ad2a522b6ca1535a3
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4250623
|
||||
Reviewed-by: Matthew Denton <mpdenton@chromium.org>
|
||||
Reviewed-by: Mikel Astiz <mastiz@chromium.org>
|
||||
Commit-Queue: Tommy Li <tommycli@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1106249}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4274984
|
||||
Reviewed-by: Tommy Li <tommycli@chromium.org>
|
||||
Commit-Queue: Krishna Govind <govind@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5481@{#1238}
|
||||
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
|
||||
|
||||
diff --git a/chrome/browser/search_engines/template_url_service_sync_unittest.cc b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
|
||||
index 2de150bbca0bf9032e207754203e60f2ee1f115f..b552f1d844e44b34eadaca850408754488b9d27b 100644
|
||||
--- a/chrome/browser/search_engines/template_url_service_sync_unittest.cc
|
||||
+++ b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
|
||||
@@ -732,6 +732,34 @@ TEST_F(TemplateURLServiceSyncTest, MergeAddFromNewerSyncData) {
|
||||
processor()->change_for_guid("localguid3").change_type());
|
||||
}
|
||||
|
||||
+TEST_F(TemplateURLServiceSyncTest, MergeIgnoresPolicyAndPlayAPIEngines) {
|
||||
+ // Add a policy-created engine.
|
||||
+ model()->Add(CreateTestTemplateURL(u"key1", "http://key1.com", "localguid1",
|
||||
+ base::Time::FromTimeT(100),
|
||||
+ /*safe_for_autoreplace=*/false,
|
||||
+ /*created_by_policy=*/true));
|
||||
+
|
||||
+ {
|
||||
+ auto play_api_engine = CreateTestTemplateURL(
|
||||
+ u"key2", "http://key2.com", "localguid2", base::Time::FromTimeT(100));
|
||||
+ TemplateURLData data(play_api_engine->data());
|
||||
+ data.created_from_play_api = true;
|
||||
+ play_api_engine = std::make_unique<TemplateURL>(data);
|
||||
+ model()->Add(std::move(play_api_engine));
|
||||
+ }
|
||||
+
|
||||
+ ASSERT_EQ(1U, model()->GetAllSyncData(syncer::SEARCH_ENGINES).size());
|
||||
+ MergeAndExpectNotify(CreateInitialSyncData(), 1);
|
||||
+
|
||||
+ // The policy engine should be ignored when it comes to conflict resolution.
|
||||
+ EXPECT_TRUE(model()->GetTemplateURLForGUID("guid1"));
|
||||
+ EXPECT_TRUE(model()->GetTemplateURLForGUID("localguid1"));
|
||||
+
|
||||
+ // The Play API engine should be ignored when it comes to conflict resolution.
|
||||
+ EXPECT_TRUE(model()->GetTemplateURLForGUID("guid2"));
|
||||
+ EXPECT_TRUE(model()->GetTemplateURLForGUID("localguid2"));
|
||||
+}
|
||||
+
|
||||
TEST_F(TemplateURLServiceSyncTest, ProcessChangesEmptyModel) {
|
||||
// We initially have no data.
|
||||
MergeAndExpectNotify({}, 0);
|
||||
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc
|
||||
index 61e7fabfed76c251ee2e3186ab60c56da54be551..824383536eed1560aa50b6892603e3a1aa601c53 100644
|
||||
--- a/components/search_engines/template_url_service.cc
|
||||
+++ b/components/search_engines/template_url_service.cc
|
||||
@@ -2175,7 +2175,14 @@ void TemplateURLService::MergeInSyncTemplateURL(
|
||||
keyword_to_turl_and_length_.equal_range(sync_turl->keyword());
|
||||
for (auto it = match_range.first; it != match_range.second; ++it) {
|
||||
TemplateURL* local_turl = it->second.first;
|
||||
- if (local_turl->type() == TemplateURL::NORMAL) {
|
||||
+ // The conflict resolution code below sometimes resets the TemplateURL's
|
||||
+ // GUID, which can trigger deleting any Policy-created engines. Avoid this
|
||||
+ // use-after-free bug by excluding any Policy-created engines. Also exclude
|
||||
+ // Play API created engines, as those also seem local-only and should not
|
||||
+ // be merged into Synced engines. crbug.com/1414224.
|
||||
+ if (local_turl->type() == TemplateURL::NORMAL &&
|
||||
+ !local_turl->created_by_policy() &&
|
||||
+ !local_turl->created_from_play_api()) {
|
||||
local_duplicates.push_back(local_turl);
|
||||
}
|
||||
}
|
||||
43
patches/chromium/cherry-pick-1235110fce18.patch
Normal file
43
patches/chromium/cherry-pick-1235110fce18.patch
Normal file
@@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Lang <geofflang@chromium.org>
|
||||
Date: Tue, 14 Mar 2023 21:15:46 +0000
|
||||
Subject: Disable glShaderBinary in the passthrough cmd decoder.
|
||||
|
||||
This matches the behaviour of the validating command decoder. The client
|
||||
does not use this function and it's not exposed to WebGL.
|
||||
|
||||
(cherry picked from commit 4a81311a62d853a43e002f45c6867f73c0accdab)
|
||||
|
||||
Bug: 1422594
|
||||
Change-Id: I87c670e4e80b0078fddb9f089b7ac7777a6debfa
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4324998
|
||||
Reviewed-by: Kenneth Russell <kbr@chromium.org>
|
||||
Commit-Queue: Geoff Lang <geofflang@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1115379}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4335184
|
||||
Cr-Commit-Position: refs/branch-heads/5481@{#1357}
|
||||
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
|
||||
|
||||
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
|
||||
index 9b09ddfe074ebe2786c7bc341b84a5eb5b7b73c9..373dab1c379152c45878faa60a5648bf0bc662e7 100644
|
||||
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
|
||||
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
|
||||
@@ -2666,6 +2666,10 @@ error::Error GLES2DecoderPassthroughImpl::DoShaderBinary(GLsizei n,
|
||||
GLenum binaryformat,
|
||||
const void* binary,
|
||||
GLsizei length) {
|
||||
+#if 1 // No binary shader support.
|
||||
+ InsertError(GL_INVALID_ENUM, "Invalid enum.");
|
||||
+ return error::kNoError;
|
||||
+#else
|
||||
std::vector<GLuint> service_shaders(n, 0);
|
||||
for (GLsizei i = 0; i < n; i++) {
|
||||
service_shaders[i] = GetShaderServiceID(shaders[i], resources_);
|
||||
@@ -2673,6 +2677,7 @@ error::Error GLES2DecoderPassthroughImpl::DoShaderBinary(GLsizei n,
|
||||
api()->glShaderBinaryFn(n, service_shaders.data(), binaryformat, binary,
|
||||
length);
|
||||
return error::kNoError;
|
||||
+#endif
|
||||
}
|
||||
|
||||
error::Error GLES2DecoderPassthroughImpl::DoShaderSource(GLuint shader,
|
||||
61
patches/chromium/cherry-pick-26bfa5807606.patch
Normal file
61
patches/chromium/cherry-pick-26bfa5807606.patch
Normal file
@@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "Steinar H. Gunderson" <sesse@chromium.org>
|
||||
Date: Tue, 14 Mar 2023 15:53:57 +0000
|
||||
Subject: In Typed CSSOM, reject adding to something that is not a list.
|
||||
|
||||
M108 merge issues:
|
||||
third_party/blink/renderer/core/css/cssom/style_property_map.cc:
|
||||
The check before the added IsValueList check isn't present in 108
|
||||
|
||||
(cherry picked from commit 7301cf1e40fdd97594ea491676b867cf4e577edc)
|
||||
|
||||
Fixed: 1417176
|
||||
Change-Id: Idef1a81af46d334c181979778c28f19ce6369718
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4293477
|
||||
Commit-Queue: Steinar H Gunderson <sesse@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1110281}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4306796
|
||||
Commit-Queue: Zakhar Voit <voit@google.com>
|
||||
Reviewed-by: Steinar H Gunderson <sesse@chromium.org>
|
||||
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1405}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/css/cssom/style_property_map.cc b/third_party/blink/renderer/core/css/cssom/style_property_map.cc
|
||||
index 2c1bcba6022519c3a865ae8e3c2ffcd5bc385cf3..0cde402b49510514599201d2b3104e56ddd7b572 100644
|
||||
--- a/third_party/blink/renderer/core/css/cssom/style_property_map.cc
|
||||
+++ b/third_party/blink/renderer/core/css/cssom/style_property_map.cc
|
||||
@@ -365,6 +365,17 @@ void StylePropertyMap::append(
|
||||
|
||||
CSSValueList* current_value = nullptr;
|
||||
if (const CSSValue* css_value = GetProperty(property_id)) {
|
||||
+ if (!css_value->IsValueList()) {
|
||||
+ // The standard doesn't seem to cover this explicitly
|
||||
+ // (https://github.com/w3c/css-houdini-drafts/issues/823),
|
||||
+ // but the only really reasonable solution seems to be
|
||||
+ // to throw a TypeError.
|
||||
+ //
|
||||
+ // This covers e.g. system-wide CSS keywords, like inherit.
|
||||
+ exception_state.ThrowTypeError(
|
||||
+ "Cannot append to something that is not a list");
|
||||
+ return;
|
||||
+ }
|
||||
current_value = To<CSSValueList>(css_value)->Copy();
|
||||
} else {
|
||||
current_value = CssValueListForPropertyID(property_id);
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/inline/append.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/inline/append.tentative.html
|
||||
index ee9a9e4ddbcf78a7517d8d038d66844880719e63..f80875622366939f48a7471513fb6319f75be718 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/inline/append.tentative.html
|
||||
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/inline/append.tentative.html
|
||||
@@ -56,4 +56,10 @@ test(t => {
|
||||
assert_style_value_array_equals(result, [CSS.s(5), CSS.s(10), CSS.s(1), CSS.s(2)]);
|
||||
}, 'StylePropertyMap.append is case-insensitive');
|
||||
|
||||
+// https://crbug.com/1417176
|
||||
+test(t => {
|
||||
+ let styleMap = createInlineStyleMap(t, 'transition-duration: inherit');
|
||||
+ assert_throws_js(TypeError, () => styleMap.append('transition-duration', '1s'));
|
||||
+}, 'StylePropertyMap.append rejects appending to CSS-wide keywords');
|
||||
+
|
||||
</script>
|
||||
91
patches/chromium/cherry-pick-2b30a50d0e62.patch
Normal file
91
patches/chromium/cherry-pick-2b30a50d0e62.patch
Normal file
@@ -0,0 +1,91 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
|
||||
Date: Mon, 10 Apr 2023 05:32:06 +0000
|
||||
Subject: Use ScriptState::Scope instead of setting HandleScope.
|
||||
|
||||
Since `GetEffectiveFunction` may call `Get` if the given v8 listener is
|
||||
an object, we need to prepare `v8::Context::Scope` before calling it.
|
||||
Blink already have a helper class to prepare the environment for the
|
||||
script execution, which has already been used used in other
|
||||
ServiceWorkerGlobalScope member functions. It is `ScriptState::Scope`
|
||||
This CL also use it instead.
|
||||
|
||||
(cherry picked from commit 299385e09d41d5ce3abd434879b5f9b0a8880cd7)
|
||||
|
||||
Bug: 1429197
|
||||
Change-Id: Idbcfdfa9c06160a18b57155a9540f72eed4ec0b8
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4387655
|
||||
Commit-Queue: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
|
||||
Commit-Queue: Kouhei Ueno <kouhei@chromium.org>
|
||||
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
|
||||
Auto-Submit: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
|
||||
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1125148}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4411454
|
||||
Reviewed-by: Shunya Shishido <sisidovski@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5615@{#1191}
|
||||
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
|
||||
|
||||
diff --git a/content/browser/service_worker/service_worker_version_browsertest.cc b/content/browser/service_worker/service_worker_version_browsertest.cc
|
||||
index 5e1aeaa11cc99e9ac4c89be082e0b4254f6df000..0435c5a1850dd3ed16197bbc40c1e276e4613a60 100644
|
||||
--- a/content/browser/service_worker/service_worker_version_browsertest.cc
|
||||
+++ b/content/browser/service_worker/service_worker_version_browsertest.cc
|
||||
@@ -976,6 +976,18 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
|
||||
version_->fetch_handler_type());
|
||||
}
|
||||
|
||||
+IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
|
||||
+ NonFunctionFetchHandlerWithHandleEventProperty) {
|
||||
+ StartServerAndNavigateToSetup();
|
||||
+ ASSERT_EQ(
|
||||
+ Install("/service_worker/fetch_event_with_handle_event_property.js"),
|
||||
+ blink::ServiceWorkerStatusCode::kOk);
|
||||
+ EXPECT_EQ(ServiceWorkerVersion::FetchHandlerExistence::EXISTS,
|
||||
+ version_->fetch_handler_existence());
|
||||
+ EXPECT_EQ(ServiceWorkerVersion::FetchHandlerType::kNotSkippable,
|
||||
+ version_->fetch_handler_type());
|
||||
+}
|
||||
+
|
||||
// Check that fetch event handler added in the install event should result in a
|
||||
// service worker that doesn't count as having a fetch event handler.
|
||||
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
|
||||
diff --git a/content/test/data/service_worker/fetch_event_with_handle_event_property.js b/content/test/data/service_worker/fetch_event_with_handle_event_property.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2fe6153af242a10162f7ecb8eaab93c17d840211
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/service_worker/fetch_event_with_handle_event_property.js
|
||||
@@ -0,0 +1,11 @@
|
||||
+// Copyright 2023 The Chromium Authors
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+let obj = {};
|
||||
+Object.defineProperty(obj, "handleEvent", {
|
||||
+ get: () => {},
|
||||
+ configurable: true,
|
||||
+ enumerable: true,
|
||||
+});
|
||||
+self.addEventListener('fetch', obj);
|
||||
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
|
||||
index c66d232a65535bf1c66d47c6d51bc56418e57f26..b3a9f691a0fabf14bf6f319173f400c31c664c12 100644
|
||||
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
|
||||
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
|
||||
@@ -2602,12 +2602,15 @@ ServiceWorkerGlobalScope::FetchHandlerType() {
|
||||
if (!elv) {
|
||||
return mojom::blink::ServiceWorkerFetchHandlerType::kNoHandler;
|
||||
}
|
||||
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
- v8::HandleScope handle_scope(isolate);
|
||||
+
|
||||
+ ScriptState* script_state = ScriptController()->GetScriptState();
|
||||
+ // Do not remove this, |scope| is needed by `GetEffectiveFunction`.
|
||||
+ ScriptState::Scope scope(script_state);
|
||||
+
|
||||
// TODO(crbug.com/1349613): revisit the way to implement this.
|
||||
// The following code returns kEmptyFetchHandler if all handlers are nop.
|
||||
for (RegisteredEventListener& e : *elv) {
|
||||
- EventTarget* et = EventTarget::Create(ScriptController()->GetScriptState());
|
||||
+ EventTarget* et = EventTarget::Create(script_state);
|
||||
v8::Local<v8::Value> v =
|
||||
To<JSBasedEventListener>(e.Callback())->GetEffectiveFunction(*et);
|
||||
if (!v->IsFunction() ||
|
||||
37
patches/chromium/cherry-pick-38de42d2bbc3.patch
Normal file
37
patches/chromium/cherry-pick-38de42d2bbc3.patch
Normal file
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Will Harris <wfh@chromium.org>
|
||||
Date: Thu, 2 Mar 2023 10:23:28 +0000
|
||||
Subject: Fix potential out of bounds write in base::SampleVectorBase
|
||||
|
||||
BUG=1417185
|
||||
|
||||
(cherry picked from commit 552939b035e724e022fedb90fd80cd008e441fcf)
|
||||
|
||||
Change-Id: I70719d0f9afb81dda373f88ab3a1c177397659ec
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4265437
|
||||
Commit-Queue: Will Harris <wfh@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1106984}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4289351
|
||||
Commit-Queue: Zakhar Voit <voit@google.com>
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1397}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/base/metrics/sample_vector.cc b/base/metrics/sample_vector.cc
|
||||
index cec7687eeeb3daea85f5bec24765bb5aed5f1c6a..a6995578515a292631dca6044e5ee23c14803e5a 100644
|
||||
--- a/base/metrics/sample_vector.cc
|
||||
+++ b/base/metrics/sample_vector.cc
|
||||
@@ -274,6 +274,12 @@ void SampleVectorBase::MoveSingleSampleToCounts() {
|
||||
if (sample.count == 0)
|
||||
return;
|
||||
|
||||
+ // Stop here if the sample bucket would be out of range for the AtomicCount
|
||||
+ // array.
|
||||
+ if (sample.bucket >= counts_size()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
// Move the value into storage. Sum and redundant-count already account
|
||||
// for this entry so no need to call IncreaseSumAndCount().
|
||||
subtle::NoBarrier_AtomicIncrement(&counts()[sample.bucket], sample.count);
|
||||
107
patches/chromium/cherry-pick-48785f698b1c.patch
Normal file
107
patches/chromium/cherry-pick-48785f698b1c.patch
Normal file
@@ -0,0 +1,107 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Arthur Sonzogni <arthursonzogni@chromium.org>
|
||||
Date: Tue, 2 May 2023 09:40:37 +0000
|
||||
Subject: Avoid buffer overflow read in HFSReadNextNonIgnorableCodePoint
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Unicode codepoints goes beyond 0xFFFF.
|
||||
|
||||
It exists upper and lower case characters there: `𞤡 `vs `𞥃`.
|
||||
|
||||
The buffer overflow occurred when using the lookup table:
|
||||
```
|
||||
lower_case_table[codepoint >> 8]
|
||||
```
|
||||
|
||||
Bug: 1425115
|
||||
Fixed: 1425115
|
||||
Change-Id: I679da02dbe570283a68176fbd3c0c620caa4f9ce
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4481260
|
||||
Reviewed-by: Alexander Timin <altimin@chromium.org>
|
||||
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1138234}
|
||||
|
||||
diff --git a/base/files/file_path.cc b/base/files/file_path.cc
|
||||
index a43c09317da96332584286fdb67284b2bedd753f..3a7cca6fad051816d6d018857c8039594c51ec65 100644
|
||||
--- a/base/files/file_path.cc
|
||||
+++ b/base/files/file_path.cc
|
||||
@@ -775,7 +775,7 @@ int FilePath::CompareIgnoreCase(StringPieceType string1,
|
||||
#elif BUILDFLAG(IS_APPLE)
|
||||
// Mac OS X specific implementation of file string comparisons.
|
||||
|
||||
-// cf. http://developer.apple.com/mac/library/technotes/tn/tn1150.html#UnicodeSubtleties
|
||||
+// cf. https://developer.apple.com/library/archive/technotes/tn/tn1150.html#UnicodeSubtleties
|
||||
//
|
||||
// "When using CreateTextEncoding to create a text encoding, you should set
|
||||
// the TextEncodingBase to kTextEncodingUnicodeV2_0, set the
|
||||
@@ -801,11 +801,12 @@ int FilePath::CompareIgnoreCase(StringPieceType string1,
|
||||
// Ignored characters are mapped to zero.
|
||||
//
|
||||
// cf. downloadable file linked in
|
||||
-// http://developer.apple.com/mac/library/technotes/tn/tn1150.html#StringComparisonAlgorithm
|
||||
+// https://developer.apple.com/library/archive/technotes/tn/tn1150.html#Downloads
|
||||
|
||||
namespace {
|
||||
|
||||
-const UInt16 lower_case_table[] = {
|
||||
+// clang-format off
|
||||
+const UInt16 lower_case_table[11 * 256] = {
|
||||
// High-byte indices ( == 0 iff no case mapping and no ignorables )
|
||||
|
||||
/* 0 */ 0x0100, 0x0200, 0x0000, 0x0300, 0x0400, 0x0500, 0x0000, 0x0000,
|
||||
@@ -1191,11 +1192,12 @@ const UInt16 lower_case_table[] = {
|
||||
/* F */ 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7,
|
||||
0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF,
|
||||
};
|
||||
+// clang-format on
|
||||
|
||||
-// Returns the next non-ignorable codepoint within string starting from the
|
||||
-// position indicated by index, or zero if there are no more.
|
||||
-// The passed-in index is automatically advanced as the characters in the input
|
||||
-// HFS-decomposed UTF-8 strings are read.
|
||||
+// Returns the next non-ignorable codepoint within `string` starting from the
|
||||
+// position indicated by `index`, or zero if there are no more.
|
||||
+// The passed-in `index` is automatically advanced as the characters in the
|
||||
+// input HFS-decomposed UTF-8 strings are read.
|
||||
inline base_icu::UChar32 HFSReadNextNonIgnorableCodepoint(const char* string,
|
||||
size_t length,
|
||||
size_t* index) {
|
||||
@@ -1206,12 +1208,16 @@ inline base_icu::UChar32 HFSReadNextNonIgnorableCodepoint(const char* string,
|
||||
CBU8_NEXT(reinterpret_cast<const uint8_t*>(string), *index, length,
|
||||
codepoint);
|
||||
DCHECK_GT(codepoint, 0);
|
||||
- if (codepoint > 0) {
|
||||
+
|
||||
+ // Note: Here, there are no lower case conversion implemented in the
|
||||
+ // Supplementary Multilingual Plane (codepoint > 0xFFFF).
|
||||
+
|
||||
+ if (codepoint > 0 && codepoint <= 0xFFFF) {
|
||||
// Check if there is a subtable for this upper byte.
|
||||
int lookup_offset = lower_case_table[codepoint >> 8];
|
||||
if (lookup_offset != 0)
|
||||
codepoint = lower_case_table[lookup_offset + (codepoint & 0x00FF)];
|
||||
- // Note: codepoint1 may be again 0 at this point if the character was
|
||||
+ // Note: `codepoint` may be again 0 at this point if the character was
|
||||
// an ignorable.
|
||||
}
|
||||
}
|
||||
diff --git a/base/files/file_path_unittest.cc b/base/files/file_path_unittest.cc
|
||||
index b9b14c1ebb6a7046f6432531913fd72b045d6cb0..90457a001c2f0d5652ae1394c9d142bfd0003ca6 100644
|
||||
--- a/base/files/file_path_unittest.cc
|
||||
+++ b/base/files/file_path_unittest.cc
|
||||
@@ -1188,6 +1188,13 @@ TEST_F(FilePathTest, CompareIgnoreCase) {
|
||||
{{FPL("K\u0301U\u032DO\u0304\u0301N"), FPL("\u1E31\u1E77\u1E53n")}, 0},
|
||||
{{FPL("k\u0301u\u032Do\u0304\u0301n"), FPL("\u1E30\u1E76\u1E52n")}, 0},
|
||||
{{FPL("k\u0301u\u032Do\u0304\u0302n"), FPL("\u1E30\u1E76\u1E52n")}, 1},
|
||||
+
|
||||
+ // Codepoints > 0xFFFF
|
||||
+ // Here, we compare the `Adlam Letter Shu` in its capital and small version.
|
||||
+ {{FPL("\U0001E921"), FPL("\U0001E943")}, -1},
|
||||
+ {{FPL("\U0001E943"), FPL("\U0001E921")}, 1},
|
||||
+ {{FPL("\U0001E921"), FPL("\U0001E921")}, 0},
|
||||
+ {{FPL("\U0001E943"), FPL("\U0001E943")}, 0},
|
||||
#endif
|
||||
};
|
||||
|
||||
130
patches/chromium/cherry-pick-56bd20b295b4.patch
Normal file
130
patches/chromium/cherry-pick-56bd20b295b4.patch
Normal file
@@ -0,0 +1,130 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Sesek <rsesek@chromium.org>
|
||||
Date: Mon, 27 Feb 2023 21:25:11 +0000
|
||||
Subject: Update Crashpad to 3e8727238bae3c069bd71cfb3b2bbaa98b55f05b
|
||||
|
||||
3e8727238bae win: Only process up to EXCEPTION_MAXIMUM_PARAMETERS in an
|
||||
EXCEPTION_RECORD
|
||||
|
||||
(cherry picked from commit d05bea76b7ce72d66507ebbe00caf5e45afd587a)
|
||||
|
||||
Fixed: 1412658
|
||||
Change-Id: I7461602d1a18d44ea1a11ac19f1487fbdb92acf6
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4285061
|
||||
Commit-Queue: Robert Sesek <rsesek@chromium.org>
|
||||
Commit-Queue: Alex Gough <ajgo@chromium.org>
|
||||
Reviewed-by: Alex Gough <ajgo@chromium.org>
|
||||
Auto-Submit: Robert Sesek <rsesek@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1108722}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4295200
|
||||
Cr-Commit-Position: refs/branch-heads/5481@{#1298}
|
||||
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
|
||||
|
||||
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
|
||||
index 29ad402c3558b7c75b68339e0f07ad004170fe76..2be0ee4d29e445b5531fc3fddcc3efa28ef968f1 100644
|
||||
--- a/third_party/crashpad/README.chromium
|
||||
+++ b/third_party/crashpad/README.chromium
|
||||
@@ -2,7 +2,7 @@ Name: Crashpad
|
||||
Short Name: crashpad
|
||||
URL: https://crashpad.chromium.org/
|
||||
Version: unknown
|
||||
-Revision: 9f472e5a18d7611adaeb5df727b51102f35e109e
|
||||
+Revision: 9f472e5a18d7611adaeb5df727b51102f35e109e with 3e8727238bae3c069bd71cfb3b2bbaa98b55f05b cherry-picked
|
||||
License: Apache 2.0
|
||||
License File: crashpad/LICENSE
|
||||
Security Critical: yes
|
||||
diff --git a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc
|
||||
index 2a70c5c0cea234ee1d81262738d7c4e48736b78e..b8931444ac8b11044a6fa7ce2a5ccf34aa4409c8 100644
|
||||
--- a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc
|
||||
+++ b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "snapshot/win/exception_snapshot_win.h"
|
||||
|
||||
+#include <algorithm>
|
||||
+
|
||||
#include "base/logging.h"
|
||||
#include "snapshot/capture_memory.h"
|
||||
#include "snapshot/memory_snapshot.h"
|
||||
@@ -261,8 +263,12 @@ bool ExceptionSnapshotWin::InitializeFromExceptionPointers(
|
||||
exception_code_ = first_record.ExceptionCode;
|
||||
exception_flags_ = first_record.ExceptionFlags;
|
||||
exception_address_ = first_record.ExceptionAddress;
|
||||
- for (DWORD i = 0; i < first_record.NumberParameters; ++i)
|
||||
+
|
||||
+ const DWORD number_parameters = std::min<DWORD>(
|
||||
+ first_record.NumberParameters, EXCEPTION_MAXIMUM_PARAMETERS);
|
||||
+ for (DWORD i = 0; i < number_parameters; ++i) {
|
||||
codes_.push_back(first_record.ExceptionInformation[i]);
|
||||
+ }
|
||||
if (first_record.ExceptionRecord) {
|
||||
// https://crashpad.chromium.org/bug/43
|
||||
LOG(WARNING) << "dropping chained ExceptionRecord";
|
||||
diff --git a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc
|
||||
index dcdc3cf4d6f4c1298905e5fba6580e73fca014e0..aa78e5579319341c08a6866fb7ae1272d403d23c 100644
|
||||
--- a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc
|
||||
+++ b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc
|
||||
@@ -14,11 +14,14 @@
|
||||
|
||||
#include "snapshot/win/exception_snapshot_win.h"
|
||||
|
||||
+#include <windows.h>
|
||||
+
|
||||
#include <string>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "gtest/gtest.h"
|
||||
+#include "snapshot/win/exception_snapshot_win.h"
|
||||
#include "snapshot/win/process_snapshot_win.h"
|
||||
#include "test/errors.h"
|
||||
#include "test/test_paths.h"
|
||||
@@ -315,6 +318,48 @@ TEST(SimulateCrash, ChildDumpWithoutCrashingWOW64) {
|
||||
}
|
||||
#endif // ARCH_CPU_64_BITS
|
||||
|
||||
+TEST(ExceptionSnapshot, TooManyExceptionParameters) {
|
||||
+ ProcessReaderWin process_reader;
|
||||
+ ASSERT_TRUE(process_reader.Initialize(GetCurrentProcess(),
|
||||
+ ProcessSuspensionState::kRunning));
|
||||
+
|
||||
+ // Construct a fake exception record and CPU context.
|
||||
+ auto exception_record = std::make_unique<EXCEPTION_RECORD>();
|
||||
+ exception_record->ExceptionCode = STATUS_FATAL_APP_EXIT;
|
||||
+ exception_record->ExceptionFlags = EXCEPTION_NONCONTINUABLE;
|
||||
+ exception_record->ExceptionAddress = reinterpret_cast<PVOID>(0xFA15E);
|
||||
+ // One more than is permitted in the struct.
|
||||
+ exception_record->NumberParameters = EXCEPTION_MAXIMUM_PARAMETERS + 1;
|
||||
+ for (int i = 0; i < EXCEPTION_MAXIMUM_PARAMETERS; ++i) {
|
||||
+ exception_record->ExceptionInformation[i] = 1000 + i;
|
||||
+ }
|
||||
+
|
||||
+ auto cpu_context = std::make_unique<internal::CPUContextUnion>();
|
||||
+
|
||||
+ auto exception_pointers = std::make_unique<EXCEPTION_POINTERS>();
|
||||
+ exception_pointers->ExceptionRecord =
|
||||
+ reinterpret_cast<PEXCEPTION_RECORD>(exception_record.get());
|
||||
+ exception_pointers->ContextRecord =
|
||||
+ reinterpret_cast<PCONTEXT>(cpu_context.get());
|
||||
+
|
||||
+ internal::ExceptionSnapshotWin snapshot;
|
||||
+ ASSERT_TRUE(snapshot.Initialize(
|
||||
+ &process_reader,
|
||||
+ GetCurrentThreadId(),
|
||||
+ reinterpret_cast<WinVMAddress>(exception_pointers.get()),
|
||||
+ nullptr));
|
||||
+
|
||||
+ EXPECT_EQ(STATUS_FATAL_APP_EXIT, snapshot.Exception());
|
||||
+ EXPECT_EQ(static_cast<uint32_t>(EXCEPTION_NONCONTINUABLE),
|
||||
+ snapshot.ExceptionInfo());
|
||||
+ EXPECT_EQ(0xFA15Eu, snapshot.ExceptionAddress());
|
||||
+ EXPECT_EQ(static_cast<size_t>(EXCEPTION_MAXIMUM_PARAMETERS),
|
||||
+ snapshot.Codes().size());
|
||||
+ for (size_t i = 0; i < EXCEPTION_MAXIMUM_PARAMETERS; ++i) {
|
||||
+ EXPECT_EQ(1000 + i, snapshot.Codes()[i]);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
124
patches/chromium/cherry-pick-63686953dc22.patch
Normal file
124
patches/chromium/cherry-pick-63686953dc22.patch
Normal file
@@ -0,0 +1,124 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Leimgruber <fleimgruber@google.com>
|
||||
Date: Thu, 6 Apr 2023 09:21:41 +0000
|
||||
Subject: Add lock to AlternativeStateNameMap.
|
||||
|
||||
To prevent the class from accessing its localized_state_names_map_ and
|
||||
localized_state_names_reverse_lookup_map_ members, a lock is added. It
|
||||
locks all reads/write from the aforementioned members.
|
||||
|
||||
(cherry picked from commit dd848883aa0d7d88520846bbf6735eaae9f2b60e)
|
||||
|
||||
Bug: 1360571, 1414241, 1425951
|
||||
Change-Id: Ic01b0cba3878748617863274deb04ec9e13645d4
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4352658
|
||||
Reviewed-by: Christoph Schwering <schwering@google.com>
|
||||
Commit-Queue: Florian Leimgruber <fleimgruber@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1119411}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4402262
|
||||
Auto-Submit: Florian Leimgruber <fleimgruber@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5615@{#1147}
|
||||
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
|
||||
|
||||
diff --git a/components/autofill/core/browser/geo/alternative_state_name_map.cc b/components/autofill/core/browser/geo/alternative_state_name_map.cc
|
||||
index d217082a0faf23d2fd74dce8eec1043d83b5e509..ed22752c50f15e1f45e48b9ef561b0cb7134fba8 100644
|
||||
--- a/components/autofill/core/browser/geo/alternative_state_name_map.cc
|
||||
+++ b/components/autofill/core/browser/geo/alternative_state_name_map.cc
|
||||
@@ -53,7 +53,6 @@ AlternativeStateNameMap::GetCanonicalStateName(
|
||||
const CountryCode& country_code,
|
||||
const StateName& state_name,
|
||||
bool is_state_name_normalized) const {
|
||||
- DCHECK_CALLED_ON_VALID_SEQUENCE(alternative_state_name_map_sequence_checker_);
|
||||
// Example:
|
||||
// Entries in |localized_state_names_map_| are:
|
||||
// ("DE", "Bavaria") -> {
|
||||
@@ -73,6 +72,7 @@ AlternativeStateNameMap::GetCanonicalStateName(
|
||||
if (!is_state_name_normalized)
|
||||
normalized_state_name = NormalizeStateName(state_name);
|
||||
|
||||
+ base::AutoLock lock(lock_);
|
||||
auto it = localized_state_names_reverse_lookup_map_.find(
|
||||
{country_code, normalized_state_name});
|
||||
if (it != localized_state_names_reverse_lookup_map_.end())
|
||||
@@ -84,8 +84,6 @@ AlternativeStateNameMap::GetCanonicalStateName(
|
||||
absl::optional<StateEntry> AlternativeStateNameMap::GetEntry(
|
||||
const CountryCode& country_code,
|
||||
const StateName& state_string_from_profile) const {
|
||||
- DCHECK_CALLED_ON_VALID_SEQUENCE(alternative_state_name_map_sequence_checker_);
|
||||
-
|
||||
StateName normalized_state_string_from_profile =
|
||||
NormalizeStateName(state_string_from_profile);
|
||||
absl::optional<CanonicalStateName> canonical_state_name =
|
||||
@@ -93,6 +91,7 @@ absl::optional<StateEntry> AlternativeStateNameMap::GetEntry(
|
||||
/*is_state_name_normalized=*/true);
|
||||
|
||||
if (canonical_state_name) {
|
||||
+ base::AutoLock lock(lock_);
|
||||
auto it = localized_state_names_map_.find(
|
||||
{country_code, canonical_state_name.value()});
|
||||
if (it != localized_state_names_map_.end())
|
||||
@@ -108,8 +107,6 @@ void AlternativeStateNameMap::AddEntry(
|
||||
const StateEntry& state_entry,
|
||||
const std::vector<StateName>& normalized_alternative_state_names,
|
||||
const CanonicalStateName& normalized_canonical_state_name) {
|
||||
- DCHECK_CALLED_ON_VALID_SEQUENCE(alternative_state_name_map_sequence_checker_);
|
||||
-
|
||||
// Example:
|
||||
// AddEntry("DE", "Bavaria", {
|
||||
// "canonical_name": "Bayern",
|
||||
@@ -126,12 +123,15 @@ void AlternativeStateNameMap::AddEntry(
|
||||
// ("DE", "Bayern") -> "Bayern"
|
||||
// ("DE", "BY") -> "Bayern"
|
||||
// ("DE", "Bavaria") -> "Bayern"
|
||||
- if (localized_state_names_map_.size() == kMaxMapSize ||
|
||||
- GetCanonicalStateName(country_code, normalized_state_value_from_profile,
|
||||
+ if (GetCanonicalStateName(country_code, normalized_state_value_from_profile,
|
||||
/*is_state_name_normalized=*/true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
+ base::AutoLock lock(lock_);
|
||||
+ if (localized_state_names_map_.size() == kMaxMapSize) {
|
||||
+ return;
|
||||
+ }
|
||||
localized_state_names_map_[{country_code, normalized_canonical_state_name}] =
|
||||
state_entry;
|
||||
for (const auto& alternative_name : normalized_alternative_state_names) {
|
||||
@@ -141,12 +141,12 @@ void AlternativeStateNameMap::AddEntry(
|
||||
}
|
||||
|
||||
bool AlternativeStateNameMap::IsLocalisedStateNamesMapEmpty() const {
|
||||
- DCHECK_CALLED_ON_VALID_SEQUENCE(alternative_state_name_map_sequence_checker_);
|
||||
+ base::AutoLock lock(lock_);
|
||||
return localized_state_names_map_.empty();
|
||||
}
|
||||
|
||||
void AlternativeStateNameMap::ClearAlternativeStateNameMap() {
|
||||
- DCHECK_CALLED_ON_VALID_SEQUENCE(alternative_state_name_map_sequence_checker_);
|
||||
+ base::AutoLock lock(lock_);
|
||||
localized_state_names_map_.clear();
|
||||
localized_state_names_reverse_lookup_map_.clear();
|
||||
}
|
||||
diff --git a/components/autofill/core/browser/geo/alternative_state_name_map.h b/components/autofill/core/browser/geo/alternative_state_name_map.h
|
||||
index d20cdf8a02fff5d3c3ea91ef3aa67c6522804692..58dd754bfbf39fd24c82e6d46ccb566008a4cd73 100644
|
||||
--- a/components/autofill/core/browser/geo/alternative_state_name_map.h
|
||||
+++ b/components/autofill/core/browser/geo/alternative_state_name_map.h
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "base/i18n/case_conversion.h"
|
||||
#include "base/no_destructor.h"
|
||||
-#include "base/sequence_checker.h"
|
||||
+#include "base/synchronization/lock.h"
|
||||
#include "base/types/strong_alias.h"
|
||||
#include "components/autofill/core/browser/proto/states.pb.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
@@ -177,7 +177,8 @@ class AlternativeStateNameMap {
|
||||
CaseInsensitiveLessComparator>
|
||||
localized_state_names_reverse_lookup_map_;
|
||||
|
||||
- SEQUENCE_CHECKER(alternative_state_name_map_sequence_checker_);
|
||||
+ // TODO(crbug.com/1425951): Remove lock.
|
||||
+ mutable base::Lock lock_;
|
||||
};
|
||||
|
||||
} // namespace autofill
|
||||
215
patches/chromium/cherry-pick-85beff6fd302.patch
Normal file
215
patches/chromium/cherry-pick-85beff6fd302.patch
Normal file
@@ -0,0 +1,215 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin McNee <mcnee@chromium.org>
|
||||
Date: Wed, 14 Jun 2023 01:10:19 +0000
|
||||
Subject: M114: Don't recursively destroy guests when clearing unattached
|
||||
guests
|
||||
|
||||
Don't recursively destroy guests when clearing unattached guests
|
||||
|
||||
When an embedder process is destroyed, we also destroy any unattached
|
||||
guests associated with that process. This is currently done with a
|
||||
single call to `owned_guests_.erase`. However, it's possible that two
|
||||
unattached guests could have an opener relationship, which causes the
|
||||
destruction of the opener guest to also destroy the other guest, during
|
||||
the call to `erase`, which is unsafe.
|
||||
|
||||
We now separate the steps of erasing `owned_guests_` and destroying the
|
||||
guests, to avoid this recursive guest destruction.
|
||||
|
||||
This also fixes the WaitForNumGuestsCreated test method to not
|
||||
return prematurely.
|
||||
|
||||
(cherry picked from commit 6345e7871e8197af92f9c6158b06c6e197f87945)
|
||||
|
||||
Bug: 1450397
|
||||
Change-Id: Ifef5ec9ff3a1e6952ff56ec279e29e8522625ac0
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4589949
|
||||
Commit-Queue: Kevin McNee <mcnee@chromium.org>
|
||||
Auto-Submit: Kevin McNee <mcnee@chromium.org>
|
||||
Reviewed-by: James Maclean <wjmaclean@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1153396}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4611152
|
||||
Commit-Queue: James Maclean <wjmaclean@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5735@{#1292}
|
||||
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
|
||||
|
||||
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
|
||||
index 7159cf6af5cfd0ad5b9e5ba526043a4407a5399d..e43966f43f7ae551b3ea335a3f4222887071a75e 100644
|
||||
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
|
||||
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
|
||||
@@ -2731,6 +2731,22 @@ IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest,
|
||||
EXPECT_TRUE(content::NavigateToURLFromRenderer(guest2, coop_url));
|
||||
}
|
||||
|
||||
+// This test creates a situation where we have two unattached webviews which
|
||||
+// have an opener relationship, and ensures that we can shutdown safely. See
|
||||
+// https://crbug.com/1450397.
|
||||
+IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest, DestroyOpenerBeforeAttachment) {
|
||||
+ TestHelper("testDestroyOpenerBeforeAttachment", "web_view/newwindow",
|
||||
+ NEEDS_TEST_SERVER);
|
||||
+ GetGuestViewManager()->WaitForNumGuestsCreated(2);
|
||||
+
|
||||
+ content::RenderProcessHost* embedder_rph =
|
||||
+ GetEmbedderWebContents()->GetPrimaryMainFrame()->GetProcess();
|
||||
+ content::RenderProcessHostWatcher kill_observer(
|
||||
+ embedder_rph, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
|
||||
+ EXPECT_TRUE(embedder_rph->Shutdown(content::RESULT_CODE_KILLED));
|
||||
+ kill_observer.Wait();
|
||||
+}
|
||||
+
|
||||
IN_PROC_BROWSER_TEST_P(WebViewTest, ContextMenuInspectElement) {
|
||||
LoadAppWithGuest("web_view/context_menus/basic");
|
||||
content::RenderFrameHost* guest_rfh = GetGuestRenderFrameHost();
|
||||
diff --git a/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js b/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
|
||||
index 900911f4963d23d74225868dce01326ba533f63a..4dd25d8849b0b13957ab7fa2912c0a158d3cd244 100644
|
||||
--- a/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
|
||||
+++ b/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
|
||||
@@ -34,6 +34,9 @@ embedder.setUp_ = function(config) {
|
||||
embedder.guestWithLinkURL = embedder.baseGuestURL +
|
||||
'/extensions/platform_apps/web_view/newwindow' +
|
||||
'/guest_with_link.html';
|
||||
+ embedder.guestOpenOnLoadURL = embedder.baseGuestURL +
|
||||
+ '/extensions/platform_apps/web_view/newwindow' +
|
||||
+ '/guest_opener_open_on_load.html';
|
||||
};
|
||||
|
||||
/** @private */
|
||||
@@ -652,6 +655,24 @@ function testNewWindowDeferredAttachmentIndefinitely() {
|
||||
embedder.setUpNewWindowRequest_(webview, 'guest.html', '', testName);
|
||||
}
|
||||
|
||||
+// This is not a test in and of itself, but a means of creating a webview that
|
||||
+// is left in an unattached state while its opener webview is also in an
|
||||
+// unattached state, so that the C++ side can test it in that state.
|
||||
+function testDestroyOpenerBeforeAttachment() {
|
||||
+ embedder.test.succeed();
|
||||
+
|
||||
+ let webview = new WebView();
|
||||
+ webview.src = embedder.guestOpenOnLoadURL;
|
||||
+ document.body.appendChild(webview);
|
||||
+
|
||||
+ // By spinning forever here, we prevent `webview` from completing the
|
||||
+ // attachment process. But since the guest is still created and it calls
|
||||
+ // window.open, we have a situation where two unattached webviews have an
|
||||
+ // opener relationship. The C++ side will test that we can shutdown safely in
|
||||
+ // this case.
|
||||
+ while (true) {}
|
||||
+}
|
||||
+
|
||||
embedder.test.testList = {
|
||||
'testNewWindowAttachAfterOpenerDestroyed':
|
||||
testNewWindowAttachAfterOpenerDestroyed,
|
||||
@@ -675,7 +696,9 @@ embedder.test.testList = {
|
||||
testNewWindowWebViewNameTakesPrecedence,
|
||||
'testNewWindowAndUpdateOpener': testNewWindowAndUpdateOpener,
|
||||
'testNewWindowDeferredAttachmentIndefinitely':
|
||||
- testNewWindowDeferredAttachmentIndefinitely
|
||||
+ testNewWindowDeferredAttachmentIndefinitely,
|
||||
+ 'testDestroyOpenerBeforeAttachment':
|
||||
+ testDestroyOpenerBeforeAttachment
|
||||
};
|
||||
|
||||
onload = function() {
|
||||
diff --git a/chrome/test/data/extensions/platform_apps/web_view/newwindow/guest_opener_open_on_load.html b/chrome/test/data/extensions/platform_apps/web_view/newwindow/guest_opener_open_on_load.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e961feb3c6487066801adf414bf4a2746c50a3f6
|
||||
--- /dev/null
|
||||
+++ b/chrome/test/data/extensions/platform_apps/web_view/newwindow/guest_opener_open_on_load.html
|
||||
@@ -0,0 +1,13 @@
|
||||
+<!--
|
||||
+Copyright 2023 The Chromium Authors
|
||||
+Use of this source code is governed by a BSD-style license that can be
|
||||
+found in the LICENSE file.
|
||||
+-->
|
||||
+<html>
|
||||
+<body>
|
||||
+<script>
|
||||
+ // A guest that opens a new window on load.
|
||||
+ window.open('guest.html');
|
||||
+</script>
|
||||
+</body>
|
||||
+</html>
|
||||
diff --git a/components/guest_view/browser/guest_view_manager.cc b/components/guest_view/browser/guest_view_manager.cc
|
||||
index 38f0f12e65009c660a6dba262617d48c10ff72ea..129443365f474b840e2ddc61868e89af2851a892 100644
|
||||
--- a/components/guest_view/browser/guest_view_manager.cc
|
||||
+++ b/components/guest_view/browser/guest_view_manager.cc
|
||||
@@ -324,7 +324,20 @@ void GuestViewManager::RemoveGuest(int guest_instance_id) {
|
||||
|
||||
void GuestViewManager::EmbedderProcessDestroyed(int embedder_process_id) {
|
||||
embedders_observed_.erase(embedder_process_id);
|
||||
+
|
||||
+ // We can't just call std::multimap::erase here because destroying a guest
|
||||
+ // could trigger the destruction of another guest which is also owned by
|
||||
+ // `owned_guests_`. Recursively calling std::multimap::erase is unsafe (see
|
||||
+ // https://crbug.com/1450397). So we take ownership of all of the guests that
|
||||
+ // will be destroyed before erasing the entries from the map.
|
||||
+ std::vector<std::unique_ptr<GuestViewBase>> guests_to_destroy;
|
||||
+ const auto destroy_range = owned_guests_.equal_range(embedder_process_id);
|
||||
+ for (auto it = destroy_range.first; it != destroy_range.second; ++it) {
|
||||
+ guests_to_destroy.push_back(std::move(it->second));
|
||||
+ }
|
||||
owned_guests_.erase(embedder_process_id);
|
||||
+ guests_to_destroy.clear();
|
||||
+
|
||||
CallViewDestructionCallbacks(embedder_process_id);
|
||||
}
|
||||
|
||||
diff --git a/components/guest_view/browser/test_guest_view_manager.cc b/components/guest_view/browser/test_guest_view_manager.cc
|
||||
index ab703db51b5ecd33e5fabd831ba121a2b5047d93..877f3eea7b440ed0a860253f85108c2442afee2e 100644
|
||||
--- a/components/guest_view/browser/test_guest_view_manager.cc
|
||||
+++ b/components/guest_view/browser/test_guest_view_manager.cc
|
||||
@@ -36,7 +36,6 @@ TestGuestViewManager::TestGuestViewManager(
|
||||
num_guests_created_(0),
|
||||
expected_num_guests_created_(0),
|
||||
num_views_garbage_collected_(0),
|
||||
- waiting_for_guests_created_(false),
|
||||
waiting_for_attach_(nullptr) {}
|
||||
|
||||
TestGuestViewManager::~TestGuestViewManager() = default;
|
||||
@@ -127,14 +126,15 @@ GuestViewBase* TestGuestViewManager::WaitForNextGuestViewCreated() {
|
||||
}
|
||||
|
||||
void TestGuestViewManager::WaitForNumGuestsCreated(size_t count) {
|
||||
- if (count == num_guests_created_)
|
||||
+ if (count == num_guests_created_) {
|
||||
return;
|
||||
+ }
|
||||
|
||||
- waiting_for_guests_created_ = true;
|
||||
expected_num_guests_created_ = count;
|
||||
|
||||
num_created_run_loop_ = std::make_unique<base::RunLoop>();
|
||||
num_created_run_loop_->Run();
|
||||
+ num_created_run_loop_ = nullptr;
|
||||
}
|
||||
|
||||
void TestGuestViewManager::WaitUntilAttached(GuestViewBase* guest_view) {
|
||||
@@ -179,13 +179,11 @@ void TestGuestViewManager::AddGuest(int guest_instance_id,
|
||||
created_run_loop_->Quit();
|
||||
|
||||
++num_guests_created_;
|
||||
- if (!waiting_for_guests_created_ &&
|
||||
- num_guests_created_ != expected_num_guests_created_) {
|
||||
- return;
|
||||
- }
|
||||
|
||||
- if (num_created_run_loop_)
|
||||
+ if (num_created_run_loop_ &&
|
||||
+ num_guests_created_ == expected_num_guests_created_) {
|
||||
num_created_run_loop_->Quit();
|
||||
+ }
|
||||
}
|
||||
|
||||
void TestGuestViewManager::AttachGuest(int embedder_process_id,
|
||||
diff --git a/components/guest_view/browser/test_guest_view_manager.h b/components/guest_view/browser/test_guest_view_manager.h
|
||||
index 75015f30cfaf8f4bb427b360951f01c729f37308..557afdbdcde44062f13dd981aacd56b8c17d35d6 100644
|
||||
--- a/components/guest_view/browser/test_guest_view_manager.h
|
||||
+++ b/components/guest_view/browser/test_guest_view_manager.h
|
||||
@@ -121,7 +121,6 @@ class TestGuestViewManager : public GuestViewManager {
|
||||
size_t num_guests_created_;
|
||||
size_t expected_num_guests_created_;
|
||||
int num_views_garbage_collected_;
|
||||
- bool waiting_for_guests_created_;
|
||||
|
||||
// Tracks the life time of the GuestView's main FrameTreeNode. The main FTN
|
||||
// has the same lifesspan as the GuestView.
|
||||
595
patches/chromium/cherry-pick-8731bd8a30f6.patch
Normal file
595
patches/chromium/cherry-pick-8731bd8a30f6.patch
Normal file
@@ -0,0 +1,595 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Moshchuk <alexmos@chromium.org>
|
||||
Date: Fri, 3 Mar 2023 22:17:24 +0000
|
||||
Subject: Use optional SafeRef to save RenderFrameHost in NavigationRequest
|
||||
|
||||
This prevents use-after-free if NavigationRequests somehow still
|
||||
points to an already-deleted RFH, which is currently possible (see bug).
|
||||
|
||||
Also converts usages of `render_frame_host_` to use the
|
||||
GetRenderFrameHost() function to ensure that they are all called after
|
||||
the final RenderFrameHost is picked for the navigation.
|
||||
|
||||
(cherry picked from commit 7b75ae34df6d15acf4e5a45f12c9dca4ce7f2586)
|
||||
|
||||
Bug: 1416916
|
||||
Change-Id: I45569e7bb1f160158dc3139fc9e49d7d6bb56738
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4278923
|
||||
Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org>
|
||||
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
|
||||
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1112656}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4308070
|
||||
Reviewed-by: Charlie Reis <creis@chromium.org>
|
||||
Commit-Queue: Alex Moshchuk <alexmos@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5481@{#1322}
|
||||
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
|
||||
|
||||
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
|
||||
index 1496adf92d0e0c7868869263eba5c7786bed6bd8..f6f25544bd36fceb60ada013178cc8fb67e7b10a 100644
|
||||
--- a/content/browser/renderer_host/navigation_request.cc
|
||||
+++ b/content/browser/renderer_host/navigation_request.cc
|
||||
@@ -1450,7 +1450,7 @@ NavigationRequest::CreateForSynchronousRendererCommit(
|
||||
subresource_web_bundle_navigation_info->token(),
|
||||
subresource_web_bundle_navigation_info->render_process_id()));
|
||||
}
|
||||
- navigation_request->render_frame_host_ = render_frame_host;
|
||||
+ navigation_request->render_frame_host_ = render_frame_host->GetSafeRef();
|
||||
navigation_request->coep_reporter_ = std::move(coep_reporter);
|
||||
navigation_request->isolation_info_for_subresources_ =
|
||||
isolation_info_for_subresources;
|
||||
@@ -1964,7 +1964,7 @@ NavigationRequest::GetCommitDeferringConditionForTesting() {
|
||||
void NavigationRequest::BeginNavigation() {
|
||||
EnterChildTraceEvent("BeginNavigation", this);
|
||||
DCHECK(!loader_);
|
||||
- DCHECK(!render_frame_host_);
|
||||
+ DCHECK(!HasRenderFrameHost());
|
||||
ScopedCrashKeys crash_keys(*this);
|
||||
|
||||
if (begin_navigation_callback_for_testing_) {
|
||||
@@ -2342,7 +2342,7 @@ void NavigationRequest::BeginNavigationImpl() {
|
||||
// expect us to use the current RenderFrameHost for this NavigationRequest,
|
||||
// and https://crbug.com/1125106.
|
||||
if (IsSameDocument()) {
|
||||
- render_frame_host_ = frame_tree_node_->current_frame_host();
|
||||
+ render_frame_host_ = frame_tree_node_->current_frame_host()->GetSafeRef();
|
||||
} else {
|
||||
// [spec]: https://html.spec.whatwg.org/C/#process-a-navigate-response
|
||||
// 4. if [...] the result of checking a navigation response's adherence to
|
||||
@@ -2368,11 +2368,12 @@ void NavigationRequest::BeginNavigationImpl() {
|
||||
origin, net::NetworkAnonymizationKey(site, site));
|
||||
|
||||
// Select an appropriate RenderFrameHost.
|
||||
- render_frame_host_ =
|
||||
- frame_tree_node_->render_manager()->GetFrameHostForNavigation(this);
|
||||
+ render_frame_host_ = frame_tree_node_->render_manager()
|
||||
+ ->GetFrameHostForNavigation(this)
|
||||
+ ->GetSafeRef();
|
||||
|
||||
CHECK(Navigator::CheckWebUIRendererDoesNotDisplayNormalURL(
|
||||
- render_frame_host_, GetUrlInfo(),
|
||||
+ &*render_frame_host_.value(), GetUrlInfo(),
|
||||
/*is_renderer_initiated_check=*/false));
|
||||
}
|
||||
|
||||
@@ -2601,8 +2602,8 @@ void NavigationRequest::ResetForCrossDocumentRestart() {
|
||||
|
||||
// Reset the previously selected RenderFrameHost. This is expected to be null
|
||||
// at the beginning of a new navigation. See https://crbug.com/936962.
|
||||
- DCHECK(render_frame_host_);
|
||||
- render_frame_host_ = nullptr;
|
||||
+ DCHECK(HasRenderFrameHost());
|
||||
+ render_frame_host_ = absl::nullopt;
|
||||
|
||||
// Convert the navigation type to the appropriate cross-document one.
|
||||
common_params_->navigation_type =
|
||||
@@ -2660,7 +2661,7 @@ mojom::NavigationClient* NavigationRequest::GetCommitNavigationClient() {
|
||||
|
||||
// Instantiate a new NavigationClient interface.
|
||||
commit_navigation_client_ =
|
||||
- render_frame_host_->GetNavigationClientFromInterfaceProvider();
|
||||
+ GetRenderFrameHost()->GetNavigationClientFromInterfaceProvider();
|
||||
HandleInterfaceDisconnection(
|
||||
&commit_navigation_client_,
|
||||
base::BindOnce(
|
||||
@@ -2731,7 +2732,7 @@ void NavigationRequest::CreateCoepReporter(
|
||||
common_params_->url,
|
||||
policies.cross_origin_embedder_policy.reporting_endpoint,
|
||||
policies.cross_origin_embedder_policy.report_only_reporting_endpoint,
|
||||
- render_frame_host_->GetFrameToken().value(),
|
||||
+ GetRenderFrameHost()->GetFrameToken().value(),
|
||||
isolation_info_for_subresources_.network_anonymization_key());
|
||||
}
|
||||
|
||||
@@ -3133,7 +3134,7 @@ void NavigationRequest::DetermineOriginAgentClusterEndResult() {
|
||||
? url::Origin::Create(common_params_->base_url_for_data_url)
|
||||
: url::Origin::Create(common_params_->url);
|
||||
const IsolationContext& isolation_context =
|
||||
- render_frame_host_->GetSiteInstance()->GetIsolationContext();
|
||||
+ GetRenderFrameHost()->GetSiteInstance()->GetIsolationContext();
|
||||
|
||||
bool is_requested = IsOriginAgentClusterOptInRequested();
|
||||
bool expects_origin_agent_cluster = is_requested || IsIsolationImplied();
|
||||
@@ -3241,7 +3242,7 @@ void NavigationRequest::ProcessOriginAgentClusterEndResult() {
|
||||
origin_agent_cluster_end_result_ ==
|
||||
OriginAgentClusterEndResult::kExplicitlyRequestedButNotOriginKeyed) {
|
||||
GetContentClient()->browser()->LogWebFeatureForCurrentPage(
|
||||
- render_frame_host_,
|
||||
+ GetRenderFrameHost(),
|
||||
blink::mojom::WebFeature::kOriginAgentClusterHeader);
|
||||
}
|
||||
|
||||
@@ -3251,7 +3252,7 @@ void NavigationRequest::ProcessOriginAgentClusterEndResult() {
|
||||
OriginAgentClusterEndResult::kRequestedButNotOriginKeyed ||
|
||||
origin_agent_cluster_end_result_ ==
|
||||
OriginAgentClusterEndResult::kExplicitlyRequestedButNotOriginKeyed) {
|
||||
- render_frame_host_->AddMessageToConsole(
|
||||
+ GetRenderFrameHost()->AddMessageToConsole(
|
||||
blink::mojom::ConsoleMessageLevel::kWarning,
|
||||
base::StringPrintf(
|
||||
"The page requested an origin-keyed agent cluster using the "
|
||||
@@ -3266,7 +3267,7 @@ void NavigationRequest::ProcessOriginAgentClusterEndResult() {
|
||||
OriginAgentClusterEndResult::kNotRequestedButOriginKeyed ||
|
||||
origin_agent_cluster_end_result_ ==
|
||||
OriginAgentClusterEndResult::kExplicitlyNotRequestedButOriginKeyed) {
|
||||
- render_frame_host_->AddMessageToConsole(
|
||||
+ GetRenderFrameHost()->AddMessageToConsole(
|
||||
blink::mojom::ConsoleMessageLevel::kWarning,
|
||||
base::StringPrintf(
|
||||
"The page did not request an origin-keyed agent cluster, but was "
|
||||
@@ -3281,7 +3282,7 @@ void NavigationRequest::PopulateDocumentTokenForCrossDocumentNavigation() {
|
||||
DCHECK(!IsSameDocument());
|
||||
DCHECK_GE(state_, READY_TO_COMMIT);
|
||||
const auto* token_to_reuse =
|
||||
- render_frame_host_->GetDocumentTokenForCrossDocumentNavigationReuse(
|
||||
+ GetRenderFrameHost()->GetDocumentTokenForCrossDocumentNavigationReuse(
|
||||
/* passkey */ {});
|
||||
document_token_.emplace(token_to_reuse ? *token_to_reuse
|
||||
: blink::DocumentToken());
|
||||
@@ -3805,45 +3806,47 @@ void NavigationRequest::OnResponseStarted(
|
||||
BackForwardCacheImpl::Entry* entry =
|
||||
controller->GetBackForwardCache().GetEntry(nav_entry_id_);
|
||||
CHECK(entry);
|
||||
- render_frame_host_ = entry->render_frame_host();
|
||||
- CHECK(render_frame_host_);
|
||||
+ CHECK(entry->render_frame_host());
|
||||
+ render_frame_host_ = entry->render_frame_host()->GetSafeRef();
|
||||
} else if (IsPrerenderedPageActivation()) {
|
||||
// Prerendering requires changing pages starting at the root node.
|
||||
DCHECK(IsInMainFrame());
|
||||
|
||||
- render_frame_host_ =
|
||||
- GetPrerenderHostRegistry().GetRenderFrameHostForReservedHost(
|
||||
- prerender_frame_tree_node_id_.value());
|
||||
- // TODO(https://crbug.com/1181712): Handle the cases when the prerender is
|
||||
- // cancelled and RFH is destroyed while NavigationRequest is alive.
|
||||
+ render_frame_host_ = GetPrerenderHostRegistry()
|
||||
+ .GetRenderFrameHostForReservedHost(
|
||||
+ prerender_frame_tree_node_id_.value())
|
||||
+ ->GetSafeRef();
|
||||
} else if (response_should_be_rendered_) {
|
||||
- render_frame_host_ =
|
||||
- frame_tree_node_->render_manager()->GetFrameHostForNavigation(this);
|
||||
+ render_frame_host_ = frame_tree_node_->render_manager()
|
||||
+ ->GetFrameHostForNavigation(this)
|
||||
+ ->GetSafeRef();
|
||||
|
||||
// Update the associated RenderFrameHost type, which could have changed
|
||||
// due to redirects during navigation.
|
||||
set_associated_rfh_type(
|
||||
- render_frame_host_ ==
|
||||
+ GetRenderFrameHost() ==
|
||||
frame_tree_node_->render_manager()->current_frame_host()
|
||||
? AssociatedRenderFrameHostType::CURRENT
|
||||
: AssociatedRenderFrameHostType::SPECULATIVE);
|
||||
|
||||
if (!Navigator::CheckWebUIRendererDoesNotDisplayNormalURL(
|
||||
- render_frame_host_, GetUrlInfo(),
|
||||
+ GetRenderFrameHost(), GetUrlInfo(),
|
||||
/* is_renderer_initiated_check */ false)) {
|
||||
CHECK(false);
|
||||
}
|
||||
} else {
|
||||
- render_frame_host_ = nullptr;
|
||||
+ render_frame_host_ = absl::nullopt;
|
||||
}
|
||||
- if (!render_frame_host_)
|
||||
+ if (!HasRenderFrameHost()) {
|
||||
DCHECK(!response_should_be_rendered_);
|
||||
+ }
|
||||
|
||||
- if (render_frame_host_)
|
||||
+ if (HasRenderFrameHost()) {
|
||||
DetermineOriginAgentClusterEndResult();
|
||||
+ }
|
||||
|
||||
- if (!commit_params_->is_browser_initiated && render_frame_host_ &&
|
||||
- render_frame_host_->GetProcess() !=
|
||||
+ if (!commit_params_->is_browser_initiated && HasRenderFrameHost() &&
|
||||
+ GetRenderFrameHost()->GetProcess() !=
|
||||
frame_tree_node_->current_frame_host()->GetProcess()) {
|
||||
// Allow the embedder to cancel the cross-process commit if needed.
|
||||
if (!frame_tree_node_->navigator()
|
||||
@@ -3864,12 +3867,12 @@ void NavigationRequest::OnResponseStarted(
|
||||
|
||||
subresource_loader_params_ = std::move(subresource_loader_params);
|
||||
|
||||
- if (render_frame_host_) {
|
||||
+ if (HasRenderFrameHost()) {
|
||||
// Set the site URL now if it hasn't been set already. If the site requires
|
||||
// a dedicated process, this will lock the process to that site, which will
|
||||
// prevent other sites from incorrectly reusing this process. See
|
||||
// https://crbug.com/738634.
|
||||
- SiteInstanceImpl* instance = render_frame_host_->GetSiteInstance();
|
||||
+ SiteInstanceImpl* instance = GetRenderFrameHost()->GetSiteInstance();
|
||||
if (!instance->HasSite() &&
|
||||
SiteInstanceImpl::ShouldAssignSiteForURL(common_params_->url)) {
|
||||
instance->ConvertToDefaultOrSetSite(GetUrlInfo());
|
||||
@@ -3891,7 +3894,7 @@ void NavigationRequest::OnResponseStarted(
|
||||
// navigation, and in the meantime another navigation reads the incorrect
|
||||
// IsUnused() value from the same process when making a process reuse
|
||||
// decision.
|
||||
- render_frame_host_->GetProcess()->SetIsUsed();
|
||||
+ GetRenderFrameHost()->GetProcess()->SetIsUsed();
|
||||
|
||||
// Now that we know the IsolationContext for the assigned SiteInstance, we
|
||||
// opt the origin into OAC here if needed. Note that this doesn't need to
|
||||
@@ -4005,7 +4008,7 @@ void NavigationRequest::OnResponseStarted(
|
||||
return;
|
||||
}
|
||||
|
||||
- if (render_frame_host_ &&
|
||||
+ if (HasRenderFrameHost() &&
|
||||
!CheckPermissionsPoliciesForFencedFrames(GetOriginToCommit())) {
|
||||
OnRequestFailedInternal(
|
||||
network::URLLoaderCompletionStatus(net::ERR_ABORTED),
|
||||
@@ -4035,7 +4038,7 @@ NavigationRequest::CreateNavigationEarlyHintsManagerParams(
|
||||
const network::mojom::EarlyHints& early_hints) {
|
||||
// Early Hints preloads should happen only before the final response is
|
||||
// received, and limited only in the main frame for now.
|
||||
- CHECK(!render_frame_host_);
|
||||
+ CHECK(!HasRenderFrameHost());
|
||||
CHECK(loader_);
|
||||
CHECK_LT(state_, WILL_PROCESS_RESPONSE);
|
||||
CHECK(!IsSameDocument());
|
||||
@@ -4178,12 +4181,12 @@ void NavigationRequest::OnRequestFailedInternal(
|
||||
// Sanity check that we haven't changed the RenderFrameHost picked for the
|
||||
// error page in OnRequestFailedInternal when running the WillFailRequest
|
||||
// checks.
|
||||
- CHECK(!render_frame_host_ || render_frame_host_ == render_frame_host);
|
||||
- render_frame_host_ = render_frame_host;
|
||||
+ CHECK(!HasRenderFrameHost() || GetRenderFrameHost() == render_frame_host);
|
||||
+ render_frame_host_ = render_frame_host->GetSafeRef();
|
||||
|
||||
// Update the associated RenderFrameHost type.
|
||||
set_associated_rfh_type(
|
||||
- render_frame_host_ ==
|
||||
+ GetRenderFrameHost() ==
|
||||
frame_tree_node_->render_manager()->current_frame_host()
|
||||
? AssociatedRenderFrameHostType::CURRENT
|
||||
: AssociatedRenderFrameHostType::SPECULATIVE);
|
||||
@@ -4191,17 +4194,17 @@ void NavigationRequest::OnRequestFailedInternal(
|
||||
// Set the site URL now if it hasn't been set already. It's possible to get
|
||||
// here if we navigate to an error out of an initial "blank" SiteInstance.
|
||||
// Also mark the process as used, since it will be hosting an error page.
|
||||
- SiteInstanceImpl* instance = render_frame_host_->GetSiteInstance();
|
||||
+ SiteInstanceImpl* instance = GetRenderFrameHost()->GetSiteInstance();
|
||||
if (!instance->HasSite())
|
||||
instance->ConvertToDefaultOrSetSite(GetUrlInfo());
|
||||
- render_frame_host_->GetProcess()->SetIsUsed();
|
||||
+ GetRenderFrameHost()->GetProcess()->SetIsUsed();
|
||||
|
||||
// The check for WebUI should be performed only if error page isolation is
|
||||
// enabled for this failed navigation. It is possible for subframe error page
|
||||
// to be committed in a WebUI process as shown in https://crbug.com/944086.
|
||||
if (frame_tree_node_->IsErrorPageIsolationEnabled()) {
|
||||
if (!Navigator::CheckWebUIRendererDoesNotDisplayNormalURL(
|
||||
- render_frame_host_, GetUrlInfo(),
|
||||
+ GetRenderFrameHost(), GetUrlInfo(),
|
||||
/* is_renderer_initiated_check */ false)) {
|
||||
CHECK(false);
|
||||
}
|
||||
@@ -4520,7 +4523,7 @@ void NavigationRequest::OnStartChecksComplete(
|
||||
->CreateURLLoaderNetworkObserverForNavigationRequest(*this),
|
||||
NetworkServiceDevToolsObserver::MakeSelfOwned(frame_tree_node_),
|
||||
std::move(cached_response_head), std::move(interceptor));
|
||||
- DCHECK(!render_frame_host_);
|
||||
+ DCHECK(!HasRenderFrameHost());
|
||||
|
||||
base::UmaHistogramTimes(
|
||||
base::StrCat({"Navigation.WillStartRequestToLoaderStart.",
|
||||
@@ -4792,7 +4795,10 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
|
||||
!response_should_be_rendered_) {
|
||||
// Reset the RenderFrameHost that had been computed for the commit of the
|
||||
// navigation.
|
||||
- render_frame_host_ = nullptr;
|
||||
+ // TODO(https://crbug.com/1416916): Reconsider if we really need to unset
|
||||
+ // the `render_frame_host_` here, as the NavigationRequest might stay alive
|
||||
+ // for a bit longer to commit an error page.
|
||||
+ render_frame_host_ = absl::nullopt;
|
||||
|
||||
// TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE.
|
||||
if (!response_should_be_rendered_) {
|
||||
@@ -4821,7 +4827,10 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
|
||||
DCHECK_EQ(net::ERR_BLOCKED_BY_RESPONSE, result.net_error_code());
|
||||
// Reset the RenderFrameHost that had been computed for the commit of the
|
||||
// navigation.
|
||||
- render_frame_host_ = nullptr;
|
||||
+ // TODO(https://crbug.com/1416916): Reconsider if we really need to unset
|
||||
+ // the `render_frame_host_` here, as the NavigationRequest might stay alive
|
||||
+ // for a bit longer to commit an error page.
|
||||
+ render_frame_host_ = absl::nullopt;
|
||||
OnRequestFailedInternal(
|
||||
network::URLLoaderCompletionStatus(result.net_error_code()),
|
||||
true /* skip_throttles */, result.error_page_content(),
|
||||
@@ -4894,7 +4903,7 @@ void NavigationRequest::CommitErrorPage(
|
||||
commit_params_->origin_to_commit =
|
||||
url::Origin::Create(common_params_->url).DeriveNewOpaqueOrigin();
|
||||
if (request_navigation_client_.is_bound()) {
|
||||
- if (render_frame_host_ == frame_tree_node()->current_frame_host()) {
|
||||
+ if (GetRenderFrameHost() == frame_tree_node()->current_frame_host()) {
|
||||
// Reuse the request NavigationClient for commit.
|
||||
commit_navigation_client_ = std::move(request_navigation_client_);
|
||||
} else {
|
||||
@@ -4909,7 +4918,7 @@ void NavigationRequest::CommitErrorPage(
|
||||
PopulateDocumentTokenForCrossDocumentNavigation();
|
||||
// Use a separate cache shard, and no cookies, for error pages.
|
||||
isolation_info_for_subresources_ = net::IsolationInfo::CreateTransient();
|
||||
- render_frame_host_->FailedNavigation(
|
||||
+ GetRenderFrameHost()->FailedNavigation(
|
||||
this, *common_params_, *commit_params_, has_stale_copy_in_cache_,
|
||||
net_error_, extended_error_code_, error_page_content, *document_token_);
|
||||
|
||||
@@ -4976,7 +4985,7 @@ void NavigationRequest::CommitNavigation() {
|
||||
// TODO(crbug.com/979296): Consider changing this code to copy an origin
|
||||
// instead of creating one from a URL which lacks opacity information.
|
||||
isolation_info_for_subresources_ =
|
||||
- render_frame_host_->ComputeIsolationInfoForSubresourcesForPendingCommit(
|
||||
+ GetRenderFrameHost()->ComputeIsolationInfoForSubresourcesForPendingCommit(
|
||||
origin, is_anonymous(), ComputeFencedFrameNonce());
|
||||
DCHECK(!isolation_info_for_subresources_.IsEmpty());
|
||||
|
||||
@@ -4984,9 +4993,9 @@ void NavigationRequest::CommitNavigation() {
|
||||
// moment. We will be able to use it once the browser can compute the origin
|
||||
// to commit.
|
||||
absl::optional<base::UnguessableToken> nonce =
|
||||
- render_frame_host_->ComputeNonce(is_anonymous(),
|
||||
+ GetRenderFrameHost()->ComputeNonce(is_anonymous(),
|
||||
ComputeFencedFrameNonce());
|
||||
- commit_params_->storage_key = render_frame_host_->CalculateStorageKey(
|
||||
+ commit_params_->storage_key = GetRenderFrameHost()->CalculateStorageKey(
|
||||
GetOriginToCommit(), base::OptionalToPtr(nonce));
|
||||
|
||||
if (IsServedFromBackForwardCache() || IsPrerenderedPageActivation()) {
|
||||
@@ -5007,13 +5016,13 @@ void NavigationRequest::CommitNavigation() {
|
||||
if (!weak_self)
|
||||
return;
|
||||
|
||||
- DCHECK(render_frame_host_ ==
|
||||
+ DCHECK(GetRenderFrameHost() ==
|
||||
frame_tree_node_->render_manager()->current_frame_host() ||
|
||||
- render_frame_host_ ==
|
||||
+ GetRenderFrameHost() ==
|
||||
frame_tree_node_->render_manager()->speculative_frame_host());
|
||||
|
||||
if (request_navigation_client_.is_bound()) {
|
||||
- if (render_frame_host_ == frame_tree_node()->current_frame_host()) {
|
||||
+ if (GetRenderFrameHost() == frame_tree_node()->current_frame_host()) {
|
||||
// Reuse the request NavigationClient for commit.
|
||||
commit_navigation_client_ = std::move(request_navigation_client_);
|
||||
} else {
|
||||
@@ -5023,9 +5032,9 @@ void NavigationRequest::CommitNavigation() {
|
||||
}
|
||||
}
|
||||
|
||||
- CreateCoepReporter(render_frame_host_->GetProcess()->GetStoragePartition());
|
||||
+ CreateCoepReporter(GetRenderFrameHost()->GetProcess()->GetStoragePartition());
|
||||
coop_status_.UpdateReporterStoragePartition(
|
||||
- render_frame_host_->GetProcess()->GetStoragePartition());
|
||||
+ GetRenderFrameHost()->GetProcess()->GetStoragePartition());
|
||||
|
||||
BrowserContext* browser_context =
|
||||
frame_tree_node_->navigator().controller().GetBrowserContext();
|
||||
@@ -5070,7 +5079,7 @@ void NavigationRequest::CommitNavigation() {
|
||||
// Notify the service worker navigation handle that navigation commit is
|
||||
// about to go.
|
||||
service_worker_handle_->OnBeginNavigationCommit(
|
||||
- render_frame_host_->GetGlobalId(),
|
||||
+ GetRenderFrameHost()->GetGlobalId(),
|
||||
policy_container_builder_->FinalPolicies(), std::move(reporter_remote),
|
||||
&service_worker_container_info, commit_params_->document_ukm_source_id);
|
||||
}
|
||||
@@ -5141,7 +5150,7 @@ void NavigationRequest::CommitNavigation() {
|
||||
std::move(subresource_loader_params_->prefetched_signed_exchanges);
|
||||
}
|
||||
|
||||
- render_frame_host_->CommitNavigation(
|
||||
+ GetRenderFrameHost()->CommitNavigation(
|
||||
this, std::move(common_params), std::move(commit_params),
|
||||
std::move(response_head), std::move(response_body_),
|
||||
std::move(url_loader_client_endpoints_),
|
||||
@@ -5154,7 +5163,7 @@ void NavigationRequest::CommitNavigation() {
|
||||
// BrowserContext. This is mostly needed to make sure the spare is warmed-up
|
||||
// if it wasn't done in RenderProcessHostImpl::GetProcessHostForSiteInstance.
|
||||
RenderProcessHostImpl::NotifySpareManagerAboutRecentlyUsedBrowserContext(
|
||||
- render_frame_host_->GetSiteInstance()->GetBrowserContext());
|
||||
+ GetRenderFrameHost()->GetSiteInstance()->GetBrowserContext());
|
||||
|
||||
SendDeferredConsoleMessages();
|
||||
}
|
||||
@@ -5831,14 +5840,14 @@ void NavigationRequest::OnRendererRequestedNavigationCancellation() {
|
||||
// The cancellation happens before READY_TO_COMMIT.
|
||||
frame_tree_node_->navigator().CancelNavigation(
|
||||
frame_tree_node_, NavigationDiscardReason::kCancelled);
|
||||
- } else if (render_frame_host_ ==
|
||||
+ } else if (GetRenderFrameHost() ==
|
||||
frame_tree_node_->render_manager()->current_frame_host() ||
|
||||
- !render_frame_host_->IsRenderFrameLive()) {
|
||||
+ !GetRenderFrameHost()->IsRenderFrameLive()) {
|
||||
// If the NavigationRequest has already reached READY_TO_COMMIT,
|
||||
// `render_frame_host_` owns `this`. Cache any needed state in stack
|
||||
// variables to avoid a use-after-free.
|
||||
FrameTreeNode* frame_tree_node = frame_tree_node_;
|
||||
- render_frame_host_->NavigationRequestCancelled(this);
|
||||
+ GetRenderFrameHost()->NavigationRequestCancelled(this);
|
||||
// Ensure that the speculative RFH, if any, is also cleaned up. In theory,
|
||||
// `ResetNavigationRequest()` should handle this; however, it early-returns
|
||||
// if there is no navigation request associated with the FrameTreeNode.
|
||||
@@ -6267,7 +6276,7 @@ void NavigationRequest::DidCommitNavigation(
|
||||
// Navigations in non-primary frame trees or portals don't appear in history.
|
||||
if ((should_update_history_ && IsSameDocument() && !HasUserGesture() &&
|
||||
params.url == previous_main_frame_url) ||
|
||||
- !render_frame_host_->GetPage().IsPrimary() ||
|
||||
+ !GetRenderFrameHost()->GetPage().IsPrimary() ||
|
||||
frame_tree_node()->frame_tree()->IsPortal()) {
|
||||
should_update_history_ = false;
|
||||
}
|
||||
@@ -6322,7 +6331,7 @@ void NavigationRequest::DidCommitNavigation(
|
||||
ui::PageTransition transition =
|
||||
ui::PageTransitionFromInt(common_params_->transition);
|
||||
absl::optional<bool> is_background =
|
||||
- render_frame_host_->GetProcess()->IsProcessBackgrounded();
|
||||
+ GetRenderFrameHost()->GetProcess()->IsProcessBackgrounded();
|
||||
|
||||
RecordStartToCommitMetrics(
|
||||
common_params_->navigation_start, transition, ready_to_commit_time_,
|
||||
@@ -6483,7 +6492,7 @@ void NavigationRequest::ReadyToCommitNavigation(bool is_error) {
|
||||
// disconnection from the renderer NavigationClient; but browser-initiated
|
||||
// navigations do not, so we must look explicitly. We should not proceed and
|
||||
// claim "ReadyToCommitNavigation" to the delegate if the renderer is gone.
|
||||
- if (!render_frame_host_->IsRenderFrameLive()) {
|
||||
+ if (!GetRenderFrameHost()->IsRenderFrameLive()) {
|
||||
OnRendererRequestedNavigationCancellation();
|
||||
// DO NOT ADD CODE AFTER THIS, as the NavigationHandle has been deleted
|
||||
// by the previous call.
|
||||
@@ -6496,20 +6505,20 @@ void NavigationRequest::ReadyToCommitNavigation(bool is_error) {
|
||||
// where the FrameTreeNode has no NavigationRequest, yet the
|
||||
// RenderFrameHostImpl is not marked as loading yet, causing
|
||||
// FrameTreeNode::IsLoading() to incorrectly return false.
|
||||
- frame_tree_node_->TransferNavigationRequestOwnership(render_frame_host_);
|
||||
+ frame_tree_node_->TransferNavigationRequestOwnership(GetRenderFrameHost());
|
||||
|
||||
// When a speculative RenderFrameHost reaches ReadyToCommitNavigation, the
|
||||
// browser process has asked the renderer to commit the navigation and is
|
||||
// waiting for confirmation of the commit. Update the LifecycleStateImpl to
|
||||
// kPendingCommit as RenderFrameHost isn't considered speculative anymore and
|
||||
// was chosen to commit as this navigation's final RenderFrameHost.
|
||||
- if (render_frame_host_->lifecycle_state() ==
|
||||
+ if (GetRenderFrameHost()->lifecycle_state() ==
|
||||
RenderFrameHostImpl::LifecycleStateImpl::kSpeculative) {
|
||||
// Only cross-RenderFrameHost navigations create speculative
|
||||
// RenderFrameHosts whereas SameDocument, BackForwardCache and
|
||||
// PrerenderedActivation navigations don't.
|
||||
DCHECK(!IsSameDocument() && !IsPageActivation());
|
||||
- render_frame_host_->SetLifecycleState(
|
||||
+ GetRenderFrameHost()->SetLifecycleState(
|
||||
RenderFrameHostImpl::LifecycleStateImpl::kPendingCommit);
|
||||
}
|
||||
|
||||
@@ -6531,11 +6540,11 @@ void NavigationRequest::ReadyToCommitNavigation(bool is_error) {
|
||||
// Record metrics for the time it takes to get to this state from the
|
||||
// beginning of the navigation.
|
||||
if (!IsSameDocument() && !is_error) {
|
||||
- is_same_process_ = render_frame_host_->GetProcess()->GetID() ==
|
||||
+ is_same_process_ = GetRenderFrameHost()->GetProcess()->GetID() ==
|
||||
previous_render_frame_host->GetProcess()->GetID();
|
||||
|
||||
RecordReadyToCommitMetrics(
|
||||
- previous_render_frame_host, render_frame_host_, *common_params_.get(),
|
||||
+ previous_render_frame_host, GetRenderFrameHost(), *common_params_.get(),
|
||||
ready_to_commit_time_, origin_agent_cluster_end_result_,
|
||||
did_receive_early_hints_before_cross_origin_redirect_);
|
||||
}
|
||||
@@ -6544,7 +6553,7 @@ void NavigationRequest::ReadyToCommitNavigation(bool is_error) {
|
||||
same_origin_ = (previous_render_frame_host->GetLastCommittedOrigin() ==
|
||||
GetOriginToCommit());
|
||||
|
||||
- SetExpectedProcess(render_frame_host_->GetProcess());
|
||||
+ SetExpectedProcess(GetRenderFrameHost()->GetProcess());
|
||||
|
||||
commit_params_->is_load_data_with_base_url = IsLoadDataWithBaseURL();
|
||||
|
||||
@@ -6568,7 +6577,7 @@ void NavigationRequest::ReadyToCommitNavigation(bool is_error) {
|
||||
NavigationEntry* entry = GetNavigationEntry();
|
||||
if (entry && entry->IsViewSourceMode()) {
|
||||
// Put the renderer in view source mode.
|
||||
- render_frame_host_->GetAssociatedLocalFrame()->EnableViewSourceMode();
|
||||
+ GetRenderFrameHost()->GetAssociatedLocalFrame()->EnableViewSourceMode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6892,7 +6901,7 @@ NavigationRequest::MakeDidCommitProvisionalLoadParamsForActivation() {
|
||||
// Use the DidCommitProvisionalLoadParams last used to commit the frame being
|
||||
// restored as a starting point.
|
||||
mojom::DidCommitProvisionalLoadParamsPtr params =
|
||||
- render_frame_host_->TakeLastCommitParams();
|
||||
+ GetRenderFrameHost()->TakeLastCommitParams();
|
||||
|
||||
// Params must have been set when the RFH being restored from the cache last
|
||||
// navigated.
|
||||
@@ -7159,7 +7168,10 @@ RenderFrameHostImpl* NavigationRequest::GetRenderFrameHost() const {
|
||||
}
|
||||
static_assert(WILL_FAIL_REQUEST > WILL_PROCESS_RESPONSE,
|
||||
"WillFailRequest state should come after WillProcessResponse");
|
||||
- return render_frame_host_;
|
||||
+ if (HasRenderFrameHost()) {
|
||||
+ return &*render_frame_host_.value();
|
||||
+ }
|
||||
+ return nullptr;
|
||||
}
|
||||
|
||||
const net::HttpRequestHeaders& NavigationRequest::GetRequestHeaders() {
|
||||
@@ -7619,7 +7631,8 @@ bool NavigationRequest::CoopCoepSanityCheck() {
|
||||
// TODO(https://crbug.com/1278207) add other embedded cases if needed.
|
||||
network::mojom::CrossOriginOpenerPolicyValue coop_value =
|
||||
GetParentFrameOrOuterDocument()
|
||||
- ? render_frame_host_->GetOutermostMainFrame()
|
||||
+ ? GetRenderFrameHost()
|
||||
+ ->GetOutermostMainFrame()
|
||||
->cross_origin_opener_policy()
|
||||
.value
|
||||
: policies.cross_origin_opener_policy.value;
|
||||
@@ -8182,8 +8195,8 @@ void NavigationRequest::SendDeferredConsoleMessages() {
|
||||
for (auto& message : console_messages_) {
|
||||
// TODO(https://crbug.com/721329): We should have a way of sending console
|
||||
// messaged to devtools without going through the renderer.
|
||||
- render_frame_host_->AddMessageToConsole(message.level,
|
||||
- std::move(message.message));
|
||||
+ GetRenderFrameHost()->AddMessageToConsole(message.level,
|
||||
+ std::move(message.message));
|
||||
}
|
||||
console_messages_.clear();
|
||||
}
|
||||
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h
|
||||
index 8d6debbd09392d954d05c06c5e0b2d7a7be29bd3..6c715d5e85f2dc90dc17f9a237c69ede69c533e6 100644
|
||||
--- a/content/browser/renderer_host/navigation_request.h
|
||||
+++ b/content/browser/renderer_host/navigation_request.h
|
||||
@@ -459,6 +459,8 @@ class CONTENT_EXPORT NavigationRequest
|
||||
associated_rfh_type_ = type;
|
||||
}
|
||||
|
||||
+ bool HasRenderFrameHost() const { return render_frame_host_.has_value(); }
|
||||
+
|
||||
void set_was_discarded() { commit_params_->was_discarded = true; }
|
||||
|
||||
void set_net_error(net::Error net_error) { net_error_ = net_error; }
|
||||
@@ -1632,8 +1634,17 @@ class CONTENT_EXPORT NavigationRequest
|
||||
// - the synchronous about:blank navigation.
|
||||
const bool is_synchronous_renderer_commit_;
|
||||
|
||||
- // Invariant: At least one of |loader_| or |render_frame_host_| is null.
|
||||
- raw_ptr<RenderFrameHostImpl> render_frame_host_ = nullptr;
|
||||
+ // The RenderFrameHost that this navigation intends to commit in. The value
|
||||
+ // will be set when we know the final RenderFrameHost that the navigation will
|
||||
+ // commit in (i.e. when we receive the final network response for most
|
||||
+ // navigations). Note that currently this can be reset to absl::nullopt for
|
||||
+ // cross-document restarts and some failed navigations.
|
||||
+ // TODO(https://crbug.com/1416916): Don't reset this on failed navigations,
|
||||
+ // and ensure the NavigationRequest doesn't outlive the `render_frame_host_`
|
||||
+ // picked for failed Back/Forward Cache restores.
|
||||
+ // Invariant: At least one of |loader_| or |render_frame_host_| is
|
||||
+ // null/absl::nullopt.
|
||||
+ absl::optional<base::SafeRef<RenderFrameHostImpl>> render_frame_host_;
|
||||
|
||||
// Initialized on creation of the NavigationRequest. Sent to the renderer when
|
||||
// the navigation is ready to commit.
|
||||
88
patches/chromium/cherry-pick-9aa4c45f21b1.patch
Normal file
88
patches/chromium/cherry-pick-9aa4c45f21b1.patch
Normal file
@@ -0,0 +1,88 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Henrik=20Bostr=C3=B6m?= <hbos@chromium.org>
|
||||
Date: Tue, 14 Mar 2023 13:07:19 +0000
|
||||
Subject: Shutdown RtpContributingSourceCache in Dispose().
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The cache is an off-heap object, but it is owned by an on-heap object
|
||||
(RTCPeerConnection). Dispoing the owning object poisons memory owned by
|
||||
it, but the cache may have in-flight tasks (cache doing ClearCache in a
|
||||
delayed microtask). This CL adds a Shutdown() method to ensure the
|
||||
cache isn't doing anything in the next microtask after disposal.
|
||||
|
||||
No reliable way to repro this has been found but the change should be
|
||||
safe so hoping we can land without tests.
|
||||
|
||||
(cherry picked from commit 4d450ecd6ec7776c7505dcf7d2f04157ff3ba0eb)
|
||||
|
||||
Bug: 1413628
|
||||
Change-Id: I479aace9859f4c10cd75d4aa5a34808b4726299d
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4247023
|
||||
Commit-Queue: Henrik Boström <hbos@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1105653}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4291513
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Reviewed-by: Henrik Boström <hbos@chromium.org>
|
||||
Commit-Queue: Zakhar Voit <voit@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1404}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
|
||||
index e951bf3faa35a8634ae2c8b90446843d77e509a9..8aeb3497e7b036904a25e807bc2a6ca654cd3752 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
|
||||
@@ -643,12 +643,18 @@ RTCPeerConnection::~RTCPeerConnection() {
|
||||
}
|
||||
|
||||
void RTCPeerConnection::Dispose() {
|
||||
- // Promptly clears the handler
|
||||
- // so that content/ doesn't access it in a lazy sweeping phase.
|
||||
- // Other references to the handler use a weak pointer, preventing access.
|
||||
+ // Promptly clears the handler so that content doesn't access it in a lazy
|
||||
+ // sweeping phase. Other references to the handler use a weak pointer,
|
||||
+ // preventing access.
|
||||
if (peer_handler_) {
|
||||
peer_handler_.reset();
|
||||
}
|
||||
+ // Memory owned by RTCPeerConnection must not be touched after Dispose().
|
||||
+ // Shut down the cache to cancel any in-flight tasks that may otherwise have
|
||||
+ // used the cache.
|
||||
+ if (rtp_contributing_source_cache_.has_value()) {
|
||||
+ rtp_contributing_source_cache_.value().Shutdown();
|
||||
+ }
|
||||
}
|
||||
|
||||
ScriptPromise RTCPeerConnection::createOffer(ScriptState* script_state,
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.cc b/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.cc
|
||||
index 1f91cf9c128a1bb19fb0a63ea9d869a5c4e6d07d..5ad457fae9bc62a252ca94297fc4231a886b62b9 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.cc
|
||||
@@ -102,6 +102,10 @@ RtpContributingSourceCache::RtpContributingSourceCache(
|
||||
DCHECK(worker_thread_runner_);
|
||||
}
|
||||
|
||||
+void RtpContributingSourceCache::Shutdown() {
|
||||
+ weak_factory_.InvalidateWeakPtrs();
|
||||
+}
|
||||
+
|
||||
HeapVector<Member<RTCRtpSynchronizationSource>>
|
||||
RtpContributingSourceCache::getSynchronizationSources(
|
||||
ScriptState* script_state,
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.h b/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.h
|
||||
index 0d0ef9d1c59328e04217d9fca3f4e59b01ecca96..3a42751ab02f5680758c2b3ebce8a599f751c1ca 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.h
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtp_contributing_source_cache.h
|
||||
@@ -43,6 +43,10 @@ class RtpContributingSourceCache {
|
||||
RTCPeerConnection* pc,
|
||||
scoped_refptr<base::SingleThreadTaskRunner> worker_thread_runner);
|
||||
|
||||
+ // When the owner of this object is Disposed(), this method must be called to
|
||||
+ // cancel any in-flight tasks.
|
||||
+ void Shutdown();
|
||||
+
|
||||
HeapVector<Member<RTCRtpSynchronizationSource>> getSynchronizationSources(
|
||||
ScriptState* script_state,
|
||||
ExceptionState& exception_state,
|
||||
89
patches/chromium/cherry-pick-aeec1ba5893d.patch
Normal file
89
patches/chromium/cherry-pick-aeec1ba5893d.patch
Normal file
@@ -0,0 +1,89 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Huang <penghuang@chromium.org>
|
||||
Date: Mon, 13 Feb 2023 22:10:44 +0000
|
||||
Subject: Fix UAF problem in AngleVulkanImageBacking
|
||||
|
||||
Right now, we use vulkan fence helper to release the backing.
|
||||
It is right, if the last usage of the backing is by skia.
|
||||
If the last usage is by gl, the fence helper(skia) isn't aware of
|
||||
the submitted work from ANGLE, skia may call flush finish callback
|
||||
to release the backing while the backing is still being referenced
|
||||
by works in ANGLE. Fix the problem by calling glFinish() if the last
|
||||
usage is GL.
|
||||
|
||||
Know issue: the finish callback of skia flush() is not always called
|
||||
in order. So in edge cases, the UAF problem can still happen.
|
||||
|
||||
(cherry picked from commit d5143b14a00807b40eada4dfb0bce610ffc1477a)
|
||||
|
||||
Bug: 1309035
|
||||
Change-Id: I3562043650dd2b27bde3a370bef45b1226cdd48c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4232858
|
||||
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
|
||||
Commit-Queue: Peng Huang <penghuang@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1102905}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4245959
|
||||
Cr-Commit-Position: refs/branch-heads/5481@{#1119}
|
||||
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
|
||||
|
||||
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
|
||||
index a2239f19b8d1002bbf511ba53a9eab6b39b84653..c8b53477a7e7dd5685be1b4aef725911e605825b 100644
|
||||
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
|
||||
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
|
||||
@@ -161,6 +161,11 @@ AngleVulkanImageBacking::~AngleVulkanImageBacking() {
|
||||
|
||||
passthrough_texture_.reset();
|
||||
egl_image_.reset();
|
||||
+
|
||||
+ if (need_gl_finish_before_destroy_ && have_context()) {
|
||||
+ gl::GLApi* api = gl::g_current_gl_context;
|
||||
+ api->glFinishFn();
|
||||
+ }
|
||||
}
|
||||
|
||||
if (vulkan_image_) {
|
||||
@@ -325,8 +330,9 @@ void AngleVulkanImageBacking::GLTextureImageRepresentationEndAccess(
|
||||
--gl_reads_in_process_;
|
||||
|
||||
// For the last GL read access, release texture from ANGLE.
|
||||
- if (gl_reads_in_process_ == 0)
|
||||
+ if (gl_reads_in_process_ == 0) {
|
||||
ReleaseTextureANGLE();
|
||||
+ }
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -356,6 +362,9 @@ void AngleVulkanImageBacking::ReleaseTextureANGLE() {
|
||||
GLuint texture = passthrough_texture_->service_id();
|
||||
// Release the texture from ANGLE, so it can be used elsewhere.
|
||||
api->glReleaseTexturesANGLEFn(1, &texture, &layout_);
|
||||
+ // Releasing the texture will submit all related works to queue, so to be
|
||||
+ // safe, glFinish() should be called before releasing the VkImage.
|
||||
+ need_gl_finish_before_destroy_ = true;
|
||||
}
|
||||
|
||||
void AngleVulkanImageBacking::PrepareBackendTexture() {
|
||||
@@ -435,6 +444,11 @@ void AngleVulkanImageBacking::EndAccessSkia() {
|
||||
return;
|
||||
}
|
||||
|
||||
+ // The backing is used by skia, so skia should submit related work to the
|
||||
+ // queue, and we can use vulkan fence helper to release the VkImage.
|
||||
+ // glFinish() is not necessary anymore.
|
||||
+ need_gl_finish_before_destroy_ = false;
|
||||
+
|
||||
SyncImageLayoutFromBackendTexture();
|
||||
|
||||
if (gl_reads_in_process_ > 0) {
|
||||
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
|
||||
index e773aed4b20db46d7a12a10961d88ff643f9c8ec..9306868802d81af87b8a3d6a0e5ea69d57ac6685 100644
|
||||
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
|
||||
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
|
||||
@@ -80,6 +80,7 @@ class AngleVulkanImageBacking : public ClearTrackingSharedImageBacking,
|
||||
bool is_gl_write_in_process_ = false;
|
||||
int skia_reads_in_process_ = 0;
|
||||
int gl_reads_in_process_ = 0;
|
||||
+ bool need_gl_finish_before_destroy_ = false;
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
506
patches/chromium/cherry-pick-b041159d06ad.patch
Normal file
506
patches/chromium/cherry-pick-b041159d06ad.patch
Normal file
@@ -0,0 +1,506 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Reynolds <mattreynolds@google.com>
|
||||
Date: Wed, 8 Mar 2023 23:55:10 +0000
|
||||
Subject: hid: Handle empty input reports
|
||||
|
||||
It's possible for a HID device to define its report descriptor such that
|
||||
one or more reports have no data fields within the report. When receiving these reports, the report buffer should contain only the
|
||||
report ID byte and no other data.
|
||||
|
||||
Ensure that we do not read past the end of the buffer when handling
|
||||
zero-length input reports.
|
||||
|
||||
(cherry picked from commit c9d77da78bc66c135520ac77873d67b89cdcaee6)
|
||||
|
||||
Bug: 1419718
|
||||
Change-Id: I51d32c20f6b16f0d2b0172e0a165469b6b79748c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4296562
|
||||
Reviewed-by: Reilly Grant <reillyg@chromium.org>
|
||||
Commit-Queue: Matt Reynolds <mattreynolds@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1112009}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4320692
|
||||
Commit-Queue: Reilly Grant <reillyg@chromium.org>
|
||||
Auto-Submit: Matt Reynolds <mattreynolds@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5481@{#1341}
|
||||
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
|
||||
|
||||
diff --git a/services/device/hid/hid_connection_impl.cc b/services/device/hid/hid_connection_impl.cc
|
||||
index c413123e12191c413ae327732c9e95caa696e0ff..adfaa66b7601dce4a267e0113c3e14cdc9445f3e 100644
|
||||
--- a/services/device/hid/hid_connection_impl.cc
|
||||
+++ b/services/device/hid/hid_connection_impl.cc
|
||||
@@ -54,11 +54,12 @@ void HidConnectionImpl::OnInputReport(
|
||||
scoped_refptr<base::RefCountedBytes> buffer,
|
||||
size_t size) {
|
||||
DCHECK(client_);
|
||||
- uint8_t report_id = buffer->data()[0];
|
||||
- uint8_t* begin = &buffer->data()[1];
|
||||
- uint8_t* end = buffer->data().data() + size;
|
||||
- std::vector<uint8_t> data(begin, end);
|
||||
- client_->OnInputReport(report_id, data);
|
||||
+ DCHECK_GE(size, 1u);
|
||||
+ std::vector<uint8_t> data;
|
||||
+ if (size > 1) {
|
||||
+ data = std::vector<uint8_t>(buffer->front() + 1, buffer->front() + size);
|
||||
+ }
|
||||
+ client_->OnInputReport(/*report_id=*/buffer->data()[0], data);
|
||||
}
|
||||
|
||||
void HidConnectionImpl::Read(ReadCallback callback) {
|
||||
diff --git a/services/device/hid/hid_connection_impl_unittest.cc b/services/device/hid/hid_connection_impl_unittest.cc
|
||||
index 25f715fa5bd0584228b5d6dd7c27103ce5a61885..3d2e74aeaa6676af88719d56fd9c889a296eccd3 100644
|
||||
--- a/services/device/hid/hid_connection_impl_unittest.cc
|
||||
+++ b/services/device/hid/hid_connection_impl_unittest.cc
|
||||
@@ -8,17 +8,28 @@
|
||||
#include "base/callback_helpers.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/ref_counted_memory.h"
|
||||
+#include "base/test/repeating_test_future.h"
|
||||
+#include "base/test/test_future.h"
|
||||
#include "build/build_config.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
|
||||
#include "services/device/device_service_test_base.h"
|
||||
+#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace device {
|
||||
|
||||
namespace {
|
||||
|
||||
+using ::testing::ElementsAre;
|
||||
+
|
||||
+using ReadFuture = base::test::
|
||||
+ TestFuture<bool, uint8_t, const absl::optional<std::vector<uint8_t>>&>;
|
||||
+using WriteFuture = base::test::TestFuture<bool>;
|
||||
+using GetFeatureFuture =
|
||||
+ base::test::TestFuture<bool, const absl::optional<std::vector<uint8_t>>&>;
|
||||
+
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
const uint64_t kTestDeviceId = 123;
|
||||
#elif BUILDFLAG(IS_WIN)
|
||||
@@ -30,46 +41,37 @@ const char* kTestDeviceId = "123";
|
||||
// The report ID to use for reports sent to or received from the test device.
|
||||
const uint8_t kTestReportId = 0x42;
|
||||
|
||||
-// The max size of input and output reports for the test device. Feature reports
|
||||
-// are not used in this test.
|
||||
+// The max size of reports for the test device.
|
||||
const uint64_t kMaxReportSizeBytes = 10;
|
||||
|
||||
-// A fake HidConnection implementation that allows the test to simulate an
|
||||
-// input report.
|
||||
-class FakeHidConnection : public HidConnection {
|
||||
+// A mock HidConnection implementation that allows the test to simulate reports.
|
||||
+class MockHidConnection : public HidConnection {
|
||||
public:
|
||||
- explicit FakeHidConnection(scoped_refptr<HidDeviceInfo> device)
|
||||
+ explicit MockHidConnection(scoped_refptr<HidDeviceInfo> device)
|
||||
: HidConnection(device,
|
||||
/*allow_protected_reports=*/false,
|
||||
/*allow_fido_reports=*/false) {}
|
||||
- FakeHidConnection(const FakeHidConnection&) = delete;
|
||||
- FakeHidConnection& operator=(const FakeHidConnection&) = delete;
|
||||
+ MockHidConnection(const MockHidConnection&) = delete;
|
||||
+ MockHidConnection& operator=(const MockHidConnection&) = delete;
|
||||
|
||||
// HidConnection implementation.
|
||||
void PlatformClose() override {}
|
||||
- void PlatformWrite(scoped_refptr<base::RefCountedBytes> buffer,
|
||||
- WriteCallback callback) override {
|
||||
- std::move(callback).Run(true);
|
||||
- }
|
||||
- void PlatformGetFeatureReport(uint8_t report_id,
|
||||
- ReadCallback callback) override {
|
||||
- NOTIMPLEMENTED();
|
||||
- }
|
||||
- void PlatformSendFeatureReport(scoped_refptr<base::RefCountedBytes> buffer,
|
||||
- WriteCallback callback) override {
|
||||
- NOTIMPLEMENTED();
|
||||
- }
|
||||
+ MOCK_METHOD2(PlatformWrite,
|
||||
+ void(scoped_refptr<base::RefCountedBytes>, WriteCallback));
|
||||
+ MOCK_METHOD2(PlatformGetFeatureReport, void(uint8_t, ReadCallback));
|
||||
+ MOCK_METHOD2(PlatformSendFeatureReport,
|
||||
+ void(scoped_refptr<base::RefCountedBytes>, WriteCallback));
|
||||
|
||||
void SimulateInputReport(scoped_refptr<base::RefCountedBytes> buffer) {
|
||||
ProcessInputReport(buffer, buffer->size());
|
||||
}
|
||||
|
||||
private:
|
||||
- ~FakeHidConnection() override = default;
|
||||
+ ~MockHidConnection() override = default;
|
||||
};
|
||||
|
||||
-// A test implementation of HidConnectionClient that signals once an input
|
||||
-// report has been received. The contents of the input report are saved.
|
||||
+// An implementation of HidConnectionClient that enables the test to wait until
|
||||
+// an input report is received.
|
||||
class TestHidConnectionClient : public mojom::HidConnectionClient {
|
||||
public:
|
||||
TestHidConnectionClient() = default;
|
||||
@@ -81,76 +83,18 @@ class TestHidConnectionClient : public mojom::HidConnectionClient {
|
||||
receiver_.Bind(std::move(receiver));
|
||||
}
|
||||
|
||||
- // mojom::HidConnectionClient implementation.
|
||||
void OnInputReport(uint8_t report_id,
|
||||
const std::vector<uint8_t>& buffer) override {
|
||||
- report_id_ = report_id;
|
||||
- buffer_ = buffer;
|
||||
- run_loop_.Quit();
|
||||
- }
|
||||
-
|
||||
- void WaitForInputReport() { run_loop_.Run(); }
|
||||
-
|
||||
- uint8_t report_id() { return report_id_; }
|
||||
- const std::vector<uint8_t>& buffer() { return buffer_; }
|
||||
-
|
||||
- private:
|
||||
- base::RunLoop run_loop_;
|
||||
- mojo::Receiver<mojom::HidConnectionClient> receiver_{this};
|
||||
- uint8_t report_id_ = 0;
|
||||
- std::vector<uint8_t> buffer_;
|
||||
-};
|
||||
-
|
||||
-// A utility for capturing the state returned by mojom::HidConnection I/O
|
||||
-// callbacks.
|
||||
-class TestIoCallback {
|
||||
- public:
|
||||
- TestIoCallback() = default;
|
||||
- TestIoCallback(const TestIoCallback&) = delete;
|
||||
- TestIoCallback& operator=(const TestIoCallback&) = delete;
|
||||
- ~TestIoCallback() = default;
|
||||
-
|
||||
- void SetReadResult(bool result,
|
||||
- uint8_t report_id,
|
||||
- const absl::optional<std::vector<uint8_t>>& buffer) {
|
||||
- result_ = result;
|
||||
- report_id_ = report_id;
|
||||
- has_buffer_ = buffer.has_value();
|
||||
- if (has_buffer_)
|
||||
- buffer_ = *buffer;
|
||||
- run_loop_.Quit();
|
||||
- }
|
||||
-
|
||||
- void SetWriteResult(bool result) {
|
||||
- result_ = result;
|
||||
- run_loop_.Quit();
|
||||
- }
|
||||
-
|
||||
- bool WaitForResult() {
|
||||
- run_loop_.Run();
|
||||
- return result_;
|
||||
- }
|
||||
-
|
||||
- mojom::HidConnection::ReadCallback GetReadCallback() {
|
||||
- return base::BindOnce(&TestIoCallback::SetReadResult,
|
||||
- base::Unretained(this));
|
||||
+ future_.AddValue(report_id, buffer);
|
||||
}
|
||||
|
||||
- mojom::HidConnection::WriteCallback GetWriteCallback() {
|
||||
- return base::BindOnce(&TestIoCallback::SetWriteResult,
|
||||
- base::Unretained(this));
|
||||
+ std::pair<uint8_t, std::vector<uint8_t>> GetNextInputReport() {
|
||||
+ return future_.Take();
|
||||
}
|
||||
|
||||
- uint8_t report_id() { return report_id_; }
|
||||
- bool has_buffer() { return has_buffer_; }
|
||||
- const std::vector<uint8_t>& buffer() { return buffer_; }
|
||||
-
|
||||
private:
|
||||
- base::RunLoop run_loop_;
|
||||
- bool result_ = false;
|
||||
- uint8_t report_id_ = 0;
|
||||
- bool has_buffer_ = false;
|
||||
- std::vector<uint8_t> buffer_;
|
||||
+ mojo::Receiver<mojom::HidConnectionClient> receiver_{this};
|
||||
+ base::test::RepeatingTestFuture<uint8_t, std::vector<uint8_t>> future_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -158,8 +102,8 @@ class TestIoCallback {
|
||||
class HidConnectionImplTest : public DeviceServiceTestBase {
|
||||
public:
|
||||
HidConnectionImplTest() = default;
|
||||
- HidConnectionImplTest(HidConnectionImplTest&) = delete;
|
||||
- HidConnectionImplTest& operator=(HidConnectionImplTest&) = delete;
|
||||
+ HidConnectionImplTest(const HidConnectionImplTest&) = delete;
|
||||
+ HidConnectionImplTest& operator=(const HidConnectionImplTest&) = delete;
|
||||
|
||||
protected:
|
||||
void SetUp() override {
|
||||
@@ -167,18 +111,28 @@ class HidConnectionImplTest : public DeviceServiceTestBase {
|
||||
base::RunLoop().RunUntilIdle();
|
||||
}
|
||||
|
||||
- void CreateHidConnection(bool with_connection_client) {
|
||||
+ void TearDown() override {
|
||||
+ // HidConnectionImpl is self-owned and will self-destruct when its mojo pipe
|
||||
+ // is disconnected. Allow disconnect handlers to run so HidConnectionImpl
|
||||
+ // can self-destruct before the end of the test.
|
||||
+ base::RunLoop().RunUntilIdle();
|
||||
+ }
|
||||
+
|
||||
+ mojo::Remote<mojom::HidConnection> CreateHidConnection(
|
||||
+ bool with_connection_client) {
|
||||
mojo::PendingRemote<mojom::HidConnectionClient> hid_connection_client;
|
||||
if (with_connection_client) {
|
||||
connection_client_ = std::make_unique<TestHidConnectionClient>();
|
||||
connection_client_->Bind(
|
||||
hid_connection_client.InitWithNewPipeAndPassReceiver());
|
||||
}
|
||||
- fake_connection_ = new FakeHidConnection(CreateTestDevice());
|
||||
- hid_connection_impl_ = new HidConnectionImpl(
|
||||
- fake_connection_, hid_connection_.InitWithNewPipeAndPassReceiver(),
|
||||
- std::move(hid_connection_client),
|
||||
- /*watcher=*/mojo::NullRemote());
|
||||
+ mock_connection_ = new MockHidConnection(CreateTestDevice());
|
||||
+ mojo::Remote<mojom::HidConnection> hid_connection;
|
||||
+ HidConnectionImpl::Create(mock_connection_,
|
||||
+ hid_connection.BindNewPipeAndPassReceiver(),
|
||||
+ std::move(hid_connection_client),
|
||||
+ /*watcher=*/mojo::NullRemote());
|
||||
+ return hid_connection;
|
||||
}
|
||||
|
||||
scoped_refptr<HidDeviceInfo> CreateTestDevice() {
|
||||
@@ -190,7 +144,7 @@ class HidConnectionImplTest : public DeviceServiceTestBase {
|
||||
/*vendor_id=*/0x1234, /*product_id=*/0xabcd, "product name",
|
||||
"serial number", mojom::HidBusType::kHIDBusTypeUSB,
|
||||
std::move(collection), kMaxReportSizeBytes, kMaxReportSizeBytes,
|
||||
- /*max_feature_report_size=*/0);
|
||||
+ kMaxReportSizeBytes);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> CreateTestReportBuffer(uint8_t report_id, size_t size) {
|
||||
@@ -201,37 +155,42 @@ class HidConnectionImplTest : public DeviceServiceTestBase {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
- mojo::PendingRemote<mojom::HidConnection> hid_connection_;
|
||||
- raw_ptr<HidConnectionImpl>
|
||||
- hid_connection_impl_; // Owned by |hid_connection_|.
|
||||
- scoped_refptr<FakeHidConnection> fake_connection_;
|
||||
+ MockHidConnection& mock_connection() { return *mock_connection_.get(); }
|
||||
+ TestHidConnectionClient& connection_client() { return *connection_client_; }
|
||||
+
|
||||
+ private:
|
||||
+ scoped_refptr<MockHidConnection> mock_connection_;
|
||||
std::unique_ptr<TestHidConnectionClient> connection_client_;
|
||||
};
|
||||
|
||||
TEST_F(HidConnectionImplTest, ReadWrite) {
|
||||
- CreateHidConnection(/*with_connection_client=*/false);
|
||||
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
|
||||
const size_t kTestBufferSize = kMaxReportSizeBytes;
|
||||
std::vector<uint8_t> buffer_vec =
|
||||
CreateTestReportBuffer(kTestReportId, kTestBufferSize);
|
||||
|
||||
// Simulate an output report (host to device).
|
||||
- TestIoCallback write_callback;
|
||||
- hid_connection_impl_->Write(kTestReportId, buffer_vec,
|
||||
- write_callback.GetWriteCallback());
|
||||
- ASSERT_TRUE(write_callback.WaitForResult());
|
||||
+ EXPECT_CALL(mock_connection(), PlatformWrite)
|
||||
+ .WillOnce([](scoped_refptr<base::RefCountedBytes> buffer,
|
||||
+ HidConnectionImpl::WriteCallback callback) {
|
||||
+ std::move(callback).Run(/*success=*/true);
|
||||
+ });
|
||||
+ WriteFuture write_future;
|
||||
+ hid_connection->Write(kTestReportId, buffer_vec, write_future.GetCallback());
|
||||
+ EXPECT_TRUE(write_future.Get());
|
||||
|
||||
// Simulate an input report (device to host).
|
||||
auto buffer = base::MakeRefCounted<base::RefCountedBytes>(buffer_vec);
|
||||
ASSERT_EQ(buffer->size(), kTestBufferSize);
|
||||
- fake_connection_->SimulateInputReport(buffer);
|
||||
+ mock_connection().SimulateInputReport(buffer);
|
||||
|
||||
// Simulate reading the input report.
|
||||
- TestIoCallback read_callback;
|
||||
- hid_connection_impl_->Read(read_callback.GetReadCallback());
|
||||
- ASSERT_TRUE(read_callback.WaitForResult());
|
||||
- EXPECT_EQ(read_callback.report_id(), kTestReportId);
|
||||
- ASSERT_TRUE(read_callback.has_buffer());
|
||||
- const auto& read_buffer = read_callback.buffer();
|
||||
+ ReadFuture read_future;
|
||||
+ hid_connection->Read(read_future.GetCallback());
|
||||
+ EXPECT_TRUE(read_future.Get<0>());
|
||||
+ EXPECT_EQ(read_future.Get<1>(), kTestReportId);
|
||||
+ ASSERT_TRUE(read_future.Get<2>().has_value());
|
||||
+ const auto& read_buffer = read_future.Get<2>().value();
|
||||
ASSERT_EQ(read_buffer.size(), kTestBufferSize - 1);
|
||||
for (size_t i = 1; i < kTestBufferSize; ++i) {
|
||||
EXPECT_EQ(read_buffer[i - 1], buffer_vec[i])
|
||||
@@ -240,26 +199,29 @@ TEST_F(HidConnectionImplTest, ReadWrite) {
|
||||
}
|
||||
|
||||
TEST_F(HidConnectionImplTest, ReadWriteWithConnectionClient) {
|
||||
- CreateHidConnection(/*with_connection_client=*/true);
|
||||
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/true);
|
||||
const size_t kTestBufferSize = kMaxReportSizeBytes;
|
||||
std::vector<uint8_t> buffer_vec =
|
||||
CreateTestReportBuffer(kTestReportId, kTestBufferSize);
|
||||
|
||||
// Simulate an output report (host to device).
|
||||
- TestIoCallback write_callback;
|
||||
- hid_connection_impl_->Write(kTestReportId, buffer_vec,
|
||||
- write_callback.GetWriteCallback());
|
||||
- ASSERT_TRUE(write_callback.WaitForResult());
|
||||
+ EXPECT_CALL(mock_connection(), PlatformWrite)
|
||||
+ .WillOnce([](scoped_refptr<base::RefCountedBytes> buffer,
|
||||
+ HidConnectionImpl::WriteCallback callback) {
|
||||
+ std::move(callback).Run(/*success=*/true);
|
||||
+ });
|
||||
+ WriteFuture write_future;
|
||||
+ hid_connection->Write(kTestReportId, buffer_vec, write_future.GetCallback());
|
||||
+ EXPECT_TRUE(write_future.Get());
|
||||
|
||||
// Simulate an input report (device to host).
|
||||
auto buffer = base::MakeRefCounted<base::RefCountedBytes>(buffer_vec);
|
||||
ASSERT_EQ(buffer->size(), kTestBufferSize);
|
||||
- fake_connection_->SimulateInputReport(buffer);
|
||||
- connection_client_->WaitForInputReport();
|
||||
+ mock_connection().SimulateInputReport(buffer);
|
||||
+ auto [report_id, in_buffer] = connection_client().GetNextInputReport();
|
||||
|
||||
// The connection client should have been notified.
|
||||
- EXPECT_EQ(connection_client_->report_id(), kTestReportId);
|
||||
- const std::vector<uint8_t>& in_buffer = connection_client_->buffer();
|
||||
+ EXPECT_EQ(report_id, kTestReportId);
|
||||
ASSERT_EQ(in_buffer.size(), kTestBufferSize - 1);
|
||||
for (size_t i = 1; i < kTestBufferSize; ++i) {
|
||||
EXPECT_EQ(in_buffer[i - 1], buffer_vec[i])
|
||||
@@ -268,7 +230,7 @@ TEST_F(HidConnectionImplTest, ReadWriteWithConnectionClient) {
|
||||
}
|
||||
|
||||
TEST_F(HidConnectionImplTest, DestroyWithPendingInputReport) {
|
||||
- CreateHidConnection(/*with_connection_client=*/false);
|
||||
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
|
||||
const size_t kTestBufferSize = kMaxReportSizeBytes;
|
||||
std::vector<uint8_t> buffer_vec =
|
||||
CreateTestReportBuffer(kTestReportId, kTestBufferSize);
|
||||
@@ -276,21 +238,20 @@ TEST_F(HidConnectionImplTest, DestroyWithPendingInputReport) {
|
||||
// Simulate an input report (device to host).
|
||||
auto buffer = base::MakeRefCounted<base::RefCountedBytes>(buffer_vec);
|
||||
ASSERT_EQ(buffer->size(), kTestBufferSize);
|
||||
- fake_connection_->SimulateInputReport(buffer);
|
||||
+ mock_connection().SimulateInputReport(buffer);
|
||||
|
||||
// Destroy the connection without reading the report.
|
||||
- hid_connection_.reset();
|
||||
+ hid_connection.reset();
|
||||
}
|
||||
|
||||
TEST_F(HidConnectionImplTest, DestroyWithPendingRead) {
|
||||
- CreateHidConnection(/*with_connection_client=*/false);
|
||||
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
|
||||
|
||||
// Simulate reading an input report.
|
||||
- TestIoCallback read_callback;
|
||||
- hid_connection_impl_->Read(read_callback.GetReadCallback());
|
||||
+ hid_connection->Read(base::DoNothing());
|
||||
|
||||
// Destroy the connection without receiving an input report.
|
||||
- hid_connection_.reset();
|
||||
+ hid_connection.reset();
|
||||
}
|
||||
|
||||
TEST_F(HidConnectionImplTest, WatcherClosedWhenHidConnectionClosed) {
|
||||
@@ -301,7 +262,7 @@ TEST_F(HidConnectionImplTest, WatcherClosedWhenHidConnectionClosed) {
|
||||
|
||||
mojo::Remote<mojom::HidConnection> hid_connection;
|
||||
HidConnectionImpl::Create(
|
||||
- base::MakeRefCounted<FakeHidConnection>(CreateTestDevice()),
|
||||
+ base::MakeRefCounted<MockHidConnection>(CreateTestDevice()),
|
||||
hid_connection.BindNewPipeAndPassReceiver(),
|
||||
/*connection_client=*/mojo::NullRemote(), std::move(watcher));
|
||||
|
||||
@@ -326,7 +287,7 @@ TEST_F(HidConnectionImplTest, HidConnectionClosedWhenWatcherClosed) {
|
||||
|
||||
mojo::Remote<mojom::HidConnection> hid_connection;
|
||||
HidConnectionImpl::Create(
|
||||
- base::MakeRefCounted<FakeHidConnection>(CreateTestDevice()),
|
||||
+ base::MakeRefCounted<MockHidConnection>(CreateTestDevice()),
|
||||
hid_connection.BindNewPipeAndPassReceiver(),
|
||||
/*connection_client=*/mojo::NullRemote(), std::move(watcher));
|
||||
|
||||
@@ -344,4 +305,74 @@ TEST_F(HidConnectionImplTest, HidConnectionClosedWhenWatcherClosed) {
|
||||
EXPECT_FALSE(hid_connection.is_connected());
|
||||
}
|
||||
|
||||
+TEST_F(HidConnectionImplTest, ReadZeroLengthInputReport) {
|
||||
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
|
||||
+ mock_connection().SimulateInputReport(
|
||||
+ base::MakeRefCounted<base::RefCountedBytes>(
|
||||
+ CreateTestReportBuffer(kTestReportId, /*size=*/1u)));
|
||||
+ ReadFuture read_future;
|
||||
+ hid_connection->Read(read_future.GetCallback());
|
||||
+ EXPECT_TRUE(read_future.Get<0>());
|
||||
+ EXPECT_EQ(read_future.Get<1>(), kTestReportId);
|
||||
+ ASSERT_TRUE(read_future.Get<2>().has_value());
|
||||
+ EXPECT_EQ(read_future.Get<2>().value().size(), 0u);
|
||||
+}
|
||||
+
|
||||
+TEST_F(HidConnectionImplTest, ReadZeroLengthInputReportWithClient) {
|
||||
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/true);
|
||||
+ mock_connection().SimulateInputReport(
|
||||
+ base::MakeRefCounted<base::RefCountedBytes>(
|
||||
+ CreateTestReportBuffer(kTestReportId, /*size=*/1u)));
|
||||
+ auto [report_id, in_buffer] = connection_client().GetNextInputReport();
|
||||
+ EXPECT_EQ(report_id, kTestReportId);
|
||||
+ EXPECT_EQ(in_buffer.size(), 0u);
|
||||
+}
|
||||
+
|
||||
+TEST_F(HidConnectionImplTest, WriteZeroLengthOutputReport) {
|
||||
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
|
||||
+ EXPECT_CALL(mock_connection(), PlatformWrite)
|
||||
+ .WillOnce([](scoped_refptr<base::RefCountedBytes> buffer,
|
||||
+ HidConnectionImpl::WriteCallback callback) {
|
||||
+ std::move(callback).Run(/*success=*/true);
|
||||
+ });
|
||||
+ WriteFuture write_future;
|
||||
+ hid_connection->Write(kTestReportId, /*buffer=*/{},
|
||||
+ write_future.GetCallback());
|
||||
+ EXPECT_TRUE(write_future.Get());
|
||||
+}
|
||||
+
|
||||
+TEST_F(HidConnectionImplTest, ReadZeroLengthFeatureReport) {
|
||||
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
|
||||
+ EXPECT_CALL(mock_connection(), PlatformGetFeatureReport)
|
||||
+ .WillOnce([](uint8_t report_id, HidConnection::ReadCallback callback) {
|
||||
+ std::move(callback).Run(/*success=*/true,
|
||||
+ base::MakeRefCounted<base::RefCountedBytes>(
|
||||
+ std::vector<uint8_t>{report_id}),
|
||||
+ /*size=*/1u);
|
||||
+ });
|
||||
+ GetFeatureFuture get_feature_future;
|
||||
+ hid_connection->GetFeatureReport(kTestReportId,
|
||||
+ get_feature_future.GetCallback());
|
||||
+ EXPECT_TRUE(get_feature_future.Get<0>());
|
||||
+ ASSERT_TRUE(get_feature_future.Get<1>().has_value());
|
||||
+ EXPECT_EQ(get_feature_future.Get<1>().value().size(), 1u);
|
||||
+}
|
||||
+
|
||||
+TEST_F(HidConnectionImplTest, WriteZeroLengthFeatureReport) {
|
||||
+ auto hid_connection = CreateHidConnection(/*with_connection_client=*/false);
|
||||
+ scoped_refptr<base::RefCountedBytes> feature_buffer;
|
||||
+ EXPECT_CALL(mock_connection(), PlatformSendFeatureReport)
|
||||
+ .WillOnce([&feature_buffer](scoped_refptr<base::RefCountedBytes> buffer,
|
||||
+ HidConnectionImpl::WriteCallback callback) {
|
||||
+ feature_buffer = buffer;
|
||||
+ std::move(callback).Run(/*success=*/true);
|
||||
+ });
|
||||
+ WriteFuture write_future;
|
||||
+ hid_connection->SendFeatureReport(kTestReportId, /*buffer=*/{},
|
||||
+ write_future.GetCallback());
|
||||
+ EXPECT_TRUE(write_future.Get());
|
||||
+ ASSERT_TRUE(feature_buffer);
|
||||
+ EXPECT_THAT(feature_buffer->data(), ElementsAre(kTestReportId));
|
||||
+}
|
||||
+
|
||||
} // namespace device
|
||||
257
patches/chromium/cherry-pick-b5c9e5efe5dd.patch
Normal file
257
patches/chromium/cherry-pick-b5c9e5efe5dd.patch
Normal file
@@ -0,0 +1,257 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dale Curtis <dalecurtis@chromium.org>
|
||||
Date: Wed, 15 Mar 2023 22:55:57 +0000
|
||||
Subject: Merge M110: "Improve checks for VideoFrame layouts."
|
||||
|
||||
Adds a `VideoFrameLayout::IsValidForSize(size)` method which clients can
|
||||
use to verify a VideoFrameLayout for their purpose. Updates a few call
|
||||
sites to use the new verifier and adds tests.
|
||||
|
||||
(cherry picked from commit 17f73200c066158330542c19d521c517586533a2)
|
||||
|
||||
Fixed: 1421268
|
||||
Change-Id: I51049ada6119eddb31cdd9b7edfe77ee65b1da7a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4307674
|
||||
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
|
||||
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
|
||||
Reviewed-by: Dominick Ng <dominickn@chromium.org>
|
||||
Commit-Queue: Dominick Ng <dominickn@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1116233}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4342492
|
||||
Cr-Commit-Position: refs/branch-heads/5481@{#1361}
|
||||
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
|
||||
|
||||
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
|
||||
index 4aa077a567840545b59645ee5ae84194517226b4..4ec81d5c1fc9b26559914b56f48f3eea1fca6bad 100644
|
||||
--- a/media/base/video_frame.cc
|
||||
+++ b/media/base/video_frame.cc
|
||||
@@ -427,20 +427,9 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalDataWithLayout(
|
||||
StorageType storage_type = STORAGE_UNOWNED_MEMORY;
|
||||
|
||||
if (!IsValidConfig(layout.format(), storage_type, layout.coded_size(),
|
||||
- visible_rect, natural_size)) {
|
||||
- DLOG(ERROR) << __func__ << " Invalid config."
|
||||
- << ConfigToString(layout.format(), storage_type,
|
||||
- layout.coded_size(), visible_rect,
|
||||
- natural_size);
|
||||
- return nullptr;
|
||||
- }
|
||||
-
|
||||
- const auto& last_plane = layout.planes()[layout.planes().size() - 1];
|
||||
- const size_t required_size = last_plane.offset + last_plane.size;
|
||||
- if (data_size < required_size) {
|
||||
- DLOG(ERROR) << __func__ << " Provided data size is too small. Provided "
|
||||
- << data_size << " bytes, but " << required_size
|
||||
- << " bytes are required."
|
||||
+ visible_rect, natural_size) ||
|
||||
+ !layout.FitsInContiguousBufferOfSize(data_size)) {
|
||||
+ DLOG(ERROR) << "Invalid config: "
|
||||
<< ConfigToString(layout.format(), storage_type,
|
||||
layout.coded_size(), visible_rect,
|
||||
natural_size);
|
||||
diff --git a/media/base/video_frame_layout.cc b/media/base/video_frame_layout.cc
|
||||
index b3307c302bfd678caf3c90c639d32659dd2cad21..1426adb193d92c4aeb658321a6d40cdaa34461ad 100644
|
||||
--- a/media/base/video_frame_layout.cc
|
||||
+++ b/media/base/video_frame_layout.cc
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "base/notreached.h"
|
||||
+#include "base/numerics/checked_math.h"
|
||||
|
||||
namespace media {
|
||||
|
||||
@@ -173,6 +174,34 @@ bool VideoFrameLayout::operator!=(const VideoFrameLayout& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
+bool VideoFrameLayout::FitsInContiguousBufferOfSize(size_t data_size) const {
|
||||
+ if (is_multi_planar_) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ base::CheckedNumeric<size_t> required_size = 0;
|
||||
+ for (const auto& plane : planes_) {
|
||||
+ if (plane.offset > data_size || plane.size > data_size) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // No individual plane should have a size + offset > data_size.
|
||||
+ base::CheckedNumeric<size_t> plane_end = plane.size;
|
||||
+ plane_end += plane.offset;
|
||||
+ if (!plane_end.IsValid() || plane_end.ValueOrDie() > data_size) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ required_size += plane.size;
|
||||
+ }
|
||||
+
|
||||
+ if (!required_size.IsValid() || required_size.ValueOrDie() > data_size) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
std::ostream& operator<<(std::ostream& ostream,
|
||||
const VideoFrameLayout& layout) {
|
||||
ostream << "VideoFrameLayout(format: " << layout.format()
|
||||
diff --git a/media/base/video_frame_layout.h b/media/base/video_frame_layout.h
|
||||
index d899c15d2d3f31bfac022d2900b62a53eccc1665..ae68bcfe5ab3669932344a6489fce76d8d9ccefa 100644
|
||||
--- a/media/base/video_frame_layout.h
|
||||
+++ b/media/base/video_frame_layout.h
|
||||
@@ -112,6 +112,13 @@ class MEDIA_EXPORT VideoFrameLayout {
|
||||
// Return the modifier of buffers.
|
||||
uint64_t modifier() const { return modifier_; }
|
||||
|
||||
+ // Any constructible layout is valid in and of itself, it can only be invalid
|
||||
+ // if the backing memory is too small to contain it.
|
||||
+ //
|
||||
+ // Returns true if this VideoFrameLayout can fit in a contiguous buffer of
|
||||
+ // size `data_size` -- always false for multi-planar layouts.
|
||||
+ bool FitsInContiguousBufferOfSize(size_t data_size) const;
|
||||
+
|
||||
private:
|
||||
VideoFrameLayout(VideoPixelFormat format,
|
||||
const gfx::Size& coded_size,
|
||||
diff --git a/media/base/video_frame_layout_unittest.cc b/media/base/video_frame_layout_unittest.cc
|
||||
index 71ef5d11d75de5693aa255b5d2400301ad3488c4..c11136eaee78b2cd35154d1a9cc10ec19835ac88 100644
|
||||
--- a/media/base/video_frame_layout_unittest.cc
|
||||
+++ b/media/base/video_frame_layout_unittest.cc
|
||||
@@ -308,4 +308,50 @@ TEST(VideoFrameLayout, EqualOperator) {
|
||||
EXPECT_NE(*layout, *different_layout);
|
||||
}
|
||||
|
||||
+TEST(VideoFrameLayout, FitsInContiguousBufferOfSize) {
|
||||
+ auto coded_size = gfx::Size(320, 180);
|
||||
+
|
||||
+ std::vector<int32_t> strides = {384, 192, 192};
|
||||
+ std::vector<size_t> offsets = {0, 200, 300};
|
||||
+ std::vector<size_t> sizes = {200, 100, 100};
|
||||
+ std::vector<ColorPlaneLayout> planes(strides.size());
|
||||
+ for (size_t i = 0; i < strides.size(); i++) {
|
||||
+ planes[i].stride = strides[i];
|
||||
+ planes[i].offset = offsets[i];
|
||||
+ planes[i].size = sizes[i];
|
||||
+ }
|
||||
+
|
||||
+ auto layout =
|
||||
+ VideoFrameLayout::CreateWithPlanes(PIXEL_FORMAT_I420, coded_size, planes);
|
||||
+ ASSERT_TRUE(layout.has_value());
|
||||
+
|
||||
+ EXPECT_TRUE(
|
||||
+ layout->FitsInContiguousBufferOfSize(sizes[0] + sizes[1] + sizes[2]));
|
||||
+
|
||||
+ // Validate single plane size exceeds data size.
|
||||
+ EXPECT_FALSE(layout->FitsInContiguousBufferOfSize(1));
|
||||
+
|
||||
+ // Validate sum of planes exceeds data size.
|
||||
+ EXPECT_FALSE(layout->FitsInContiguousBufferOfSize(sizes[0] + sizes[1]));
|
||||
+
|
||||
+ // Validate offset exceeds plane size.
|
||||
+ planes[2].offset = 301;
|
||||
+ layout =
|
||||
+ VideoFrameLayout::CreateWithPlanes(PIXEL_FORMAT_I420, coded_size, planes);
|
||||
+ ASSERT_TRUE(layout.has_value());
|
||||
+ EXPECT_TRUE(
|
||||
+ layout->FitsInContiguousBufferOfSize(sizes[0] + sizes[1] + sizes[2] + 1));
|
||||
+ EXPECT_FALSE(layout->FitsInContiguousBufferOfSize(sizes[0]));
|
||||
+
|
||||
+ // Validate overflow.
|
||||
+ planes[0].offset = 0;
|
||||
+ planes[0].size = planes[1].size = planes[2].size =
|
||||
+ std::numeric_limits<size_t>::max() / 2;
|
||||
+ layout =
|
||||
+ VideoFrameLayout::CreateWithPlanes(PIXEL_FORMAT_I420, coded_size, planes);
|
||||
+ ASSERT_TRUE(layout.has_value());
|
||||
+ EXPECT_FALSE(
|
||||
+ layout->FitsInContiguousBufferOfSize(std::numeric_limits<size_t>::max()));
|
||||
+}
|
||||
+
|
||||
} // namespace media
|
||||
diff --git a/media/base/video_frame_unittest.cc b/media/base/video_frame_unittest.cc
|
||||
index 2fb254e8315b57cad3ac743d7ecf4f7c11371823..9e2cd0878362ff4b6315338cc1a39816ffadf49c 100644
|
||||
--- a/media/base/video_frame_unittest.cc
|
||||
+++ b/media/base/video_frame_unittest.cc
|
||||
@@ -770,6 +770,46 @@ TEST(VideoFrame, AllocationSize_OddSize) {
|
||||
}
|
||||
}
|
||||
|
||||
+TEST(VideoFrame, WrapExternalDataWithInvalidLayout) {
|
||||
+ auto coded_size = gfx::Size(320, 180);
|
||||
+
|
||||
+ std::vector<int32_t> strides = {384, 192, 192};
|
||||
+ std::vector<size_t> offsets = {0, 200, 300};
|
||||
+ std::vector<size_t> sizes = {200, 100, 100};
|
||||
+ std::vector<ColorPlaneLayout> planes(strides.size());
|
||||
+ for (size_t i = 0; i < strides.size(); i++) {
|
||||
+ planes[i].stride = strides[i];
|
||||
+ planes[i].offset = offsets[i];
|
||||
+ planes[i].size = sizes[i];
|
||||
+ }
|
||||
+
|
||||
+ auto layout =
|
||||
+ VideoFrameLayout::CreateWithPlanes(PIXEL_FORMAT_I420, coded_size, planes);
|
||||
+ ASSERT_TRUE(layout.has_value());
|
||||
+
|
||||
+ // Validate single plane size exceeds data size.
|
||||
+ uint8_t data = 0;
|
||||
+ auto frame = VideoFrame::WrapExternalDataWithLayout(
|
||||
+ *layout, gfx::Rect(coded_size), coded_size, &data, sizeof(data),
|
||||
+ base::TimeDelta());
|
||||
+ ASSERT_FALSE(frame);
|
||||
+
|
||||
+ // Validate sum of planes exceeds data size.
|
||||
+ frame = VideoFrame::WrapExternalDataWithLayout(
|
||||
+ *layout, gfx::Rect(coded_size), coded_size, &data, sizes[0] + sizes[1],
|
||||
+ base::TimeDelta());
|
||||
+ ASSERT_FALSE(frame);
|
||||
+
|
||||
+ // Validate offset exceeds plane size.
|
||||
+ planes[0].offset = 201;
|
||||
+ layout =
|
||||
+ VideoFrameLayout::CreateWithPlanes(PIXEL_FORMAT_I420, coded_size, planes);
|
||||
+ frame = VideoFrame::WrapExternalDataWithLayout(*layout, gfx::Rect(coded_size),
|
||||
+ coded_size, &data, sizes[0],
|
||||
+ base::TimeDelta());
|
||||
+ ASSERT_FALSE(frame);
|
||||
+}
|
||||
+
|
||||
TEST(VideoFrameMetadata, MergeMetadata) {
|
||||
VideoFrameMetadata reference_metadata = GetFullVideoFrameMetadata();
|
||||
VideoFrameMetadata full_metadata = reference_metadata;
|
||||
diff --git a/media/mojo/mojom/video_frame_mojom_traits.cc b/media/mojo/mojom/video_frame_mojom_traits.cc
|
||||
index cdc4498f52873a6ba68271e4b373c5ace27f43c9..3a07ab5e7e877c9230df7f1a3bcd0df51a8940b6 100644
|
||||
--- a/media/mojo/mojom/video_frame_mojom_traits.cc
|
||||
+++ b/media/mojo/mojom/video_frame_mojom_traits.cc
|
||||
@@ -231,14 +231,17 @@ bool StructTraits<media::mojom::VideoFrameDataView,
|
||||
|
||||
auto layout = media::VideoFrameLayout::CreateWithPlanes(format, coded_size,
|
||||
std::move(planes));
|
||||
- if (!layout) {
|
||||
+ if (!layout || !layout->FitsInContiguousBufferOfSize(mapping.size())) {
|
||||
DLOG(ERROR) << "Invalid layout";
|
||||
return false;
|
||||
}
|
||||
+
|
||||
frame = media::VideoFrame::WrapExternalYuvDataWithLayout(
|
||||
*layout, visible_rect, natural_size, addr[0], addr[1], addr[2],
|
||||
timestamp);
|
||||
- frame->BackWithOwnedSharedMemory(std::move(region), std::move(mapping));
|
||||
+ if (frame) {
|
||||
+ frame->BackWithOwnedSharedMemory(std::move(region), std::move(mapping));
|
||||
+ }
|
||||
} else if (data.is_gpu_memory_buffer_data()) {
|
||||
media::mojom::GpuMemoryBufferVideoFrameDataDataView gpu_memory_buffer_data;
|
||||
data.GetGpuMemoryBufferDataDataView(&gpu_memory_buffer_data);
|
||||
@@ -313,8 +316,9 @@ bool StructTraits<media::mojom::VideoFrameDataView,
|
||||
return false;
|
||||
}
|
||||
|
||||
- if (!frame)
|
||||
+ if (!frame) {
|
||||
return false;
|
||||
+ }
|
||||
|
||||
media::VideoFrameMetadata metadata;
|
||||
if (!input.ReadMetadata(&metadata))
|
||||
134
patches/chromium/cherry-pick-bfd926be8178.patch
Normal file
134
patches/chromium/cherry-pick-bfd926be8178.patch
Normal file
@@ -0,0 +1,134 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eugene Zemtsov <eugene@chromium.org>
|
||||
Date: Thu, 23 Feb 2023 23:29:10 +0000
|
||||
Subject: webcodecs: Fix VP9 p2 encoding of NV12 frames
|
||||
|
||||
(cherry picked from commit 503831d1bdfdbe20c096f04cefc2231efd9ca4c0)
|
||||
|
||||
Bug: 1412991
|
||||
Change-Id: I2e596f65170c1fc98c122bfb0ecff4b241feee15
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4250421
|
||||
Commit-Queue: Eugene Zemtsov <eugene@chromium.org>
|
||||
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1105528}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4288113
|
||||
Cr-Commit-Position: refs/branch-heads/5481@{#1271}
|
||||
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
|
||||
|
||||
diff --git a/media/video/BUILD.gn b/media/video/BUILD.gn
|
||||
index ce155164c821ddf60f73f7b0af0dce6e3d399af4..da517ef08a4cd1094f8e1660dfb5e4b7d847c979 100644
|
||||
--- a/media/video/BUILD.gn
|
||||
+++ b/media/video/BUILD.gn
|
||||
@@ -169,6 +169,7 @@ source_set("unit_tests") {
|
||||
"//media:test_support",
|
||||
"//testing/gmock",
|
||||
"//testing/gtest",
|
||||
+ "//third_party/libvpx:libvpx",
|
||||
"//third_party/libyuv:libyuv",
|
||||
"//ui/gfx",
|
||||
]
|
||||
diff --git a/media/video/software_video_encoder_test.cc b/media/video/software_video_encoder_test.cc
|
||||
index 2059f4e076ff9fa1720683ac5dfb90312df2183e..318c743bddcf9bec3a994f125ea329d45f8c4376 100644
|
||||
--- a/media/video/software_video_encoder_test.cc
|
||||
+++ b/media/video/software_video_encoder_test.cc
|
||||
@@ -40,6 +40,8 @@
|
||||
#if BUILDFLAG(ENABLE_LIBVPX)
|
||||
#include "media/filters/vpx_video_decoder.h"
|
||||
#include "media/video/vpx_video_encoder.h"
|
||||
+#include "third_party/libvpx/source/libvpx/vpx/vp8cx.h"
|
||||
+#include "third_party/libvpx/source/libvpx/vpx/vpx_codec.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_LIBAOM)
|
||||
@@ -74,6 +76,9 @@ class SoftwareVideoEncoderTest
|
||||
pixel_format_ = args.pixel_format;
|
||||
codec_ = args.codec;
|
||||
encoder_ = CreateEncoder(codec_);
|
||||
+ if (!encoder_) {
|
||||
+ GTEST_SKIP() << "Encoder is not supported on the platform";
|
||||
+ }
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
@@ -200,6 +205,12 @@ class SoftwareVideoEncoderTest
|
||||
case media::VideoCodec::kVP8:
|
||||
case media::VideoCodec::kVP9:
|
||||
#if BUILDFLAG(ENABLE_LIBVPX)
|
||||
+ if (profile_ == VP9PROFILE_PROFILE2) {
|
||||
+ vpx_codec_caps_t codec_caps = vpx_codec_get_caps(vpx_codec_vp9_cx());
|
||||
+ if ((codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) == 0) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ }
|
||||
return std::make_unique<media::VpxVideoEncoder>();
|
||||
#else
|
||||
return nullptr;
|
||||
@@ -303,6 +314,11 @@ class SoftwareVideoEncoderTest
|
||||
return diff_cnt;
|
||||
}
|
||||
|
||||
+ VideoPixelFormat GetExpectedOutputPixelFormat(VideoCodecProfile profile) {
|
||||
+ return profile == VP9PROFILE_PROFILE2 ? PIXEL_FORMAT_YUV420P10
|
||||
+ : PIXEL_FORMAT_I420;
|
||||
+ }
|
||||
+
|
||||
protected:
|
||||
VideoCodec codec_;
|
||||
VideoCodecProfile profile_;
|
||||
@@ -488,7 +504,7 @@ TEST_P(SoftwareVideoEncoderTest, EncodeAndDecode) {
|
||||
EXPECT_EQ(decoded_frame->timestamp(), original_frame->timestamp());
|
||||
EXPECT_EQ(decoded_frame->visible_rect().size(),
|
||||
original_frame->visible_rect().size());
|
||||
- EXPECT_EQ(decoded_frame->format(), PIXEL_FORMAT_I420);
|
||||
+ EXPECT_EQ(decoded_frame->format(), GetExpectedOutputPixelFormat(profile_));
|
||||
if (decoded_frame->format() == original_frame->format()) {
|
||||
EXPECT_LE(CountDifferentPixels(*decoded_frame, *original_frame),
|
||||
original_frame->visible_rect().width());
|
||||
@@ -890,6 +906,9 @@ SwVideoTestParams kVpxParams[] = {
|
||||
{VideoCodec::kVP9, VP9PROFILE_PROFILE0, PIXEL_FORMAT_I420},
|
||||
{VideoCodec::kVP9, VP9PROFILE_PROFILE0, PIXEL_FORMAT_NV12},
|
||||
{VideoCodec::kVP9, VP9PROFILE_PROFILE0, PIXEL_FORMAT_XRGB},
|
||||
+ {VideoCodec::kVP9, VP9PROFILE_PROFILE2, PIXEL_FORMAT_I420},
|
||||
+ {VideoCodec::kVP9, VP9PROFILE_PROFILE2, PIXEL_FORMAT_NV12},
|
||||
+ {VideoCodec::kVP9, VP9PROFILE_PROFILE2, PIXEL_FORMAT_XRGB},
|
||||
{VideoCodec::kVP8, VP8PROFILE_ANY, PIXEL_FORMAT_I420},
|
||||
{VideoCodec::kVP8, VP8PROFILE_ANY, PIXEL_FORMAT_XRGB}};
|
||||
|
||||
diff --git a/media/video/vpx_video_encoder.cc b/media/video/vpx_video_encoder.cc
|
||||
index 7787b765899bc57395fea1a06d5c9c5a925b8910..c4ad642e453c9582b9ada11ad99c6b1c969b27b5 100644
|
||||
--- a/media/video/vpx_video_encoder.cc
|
||||
+++ b/media/video/vpx_video_encoder.cc
|
||||
@@ -427,12 +427,20 @@ void VpxVideoEncoder::Encode(scoped_refptr<VideoFrame> frame,
|
||||
}
|
||||
}
|
||||
|
||||
- const bool is_yuv = IsYuvPlanar(frame->format());
|
||||
- if (frame->visible_rect().size() != options_.frame_size || !is_yuv) {
|
||||
+ // Unfortunately libyuv lacks direct NV12 to I010 conversion, and we
|
||||
+ // have to do an extra conversion to I420.
|
||||
+ // TODO(https://crbug.com/libyuv/954) Use NV12ToI010() when implemented
|
||||
+ const bool vp9_p2_needs_nv12_to_i420 =
|
||||
+ frame->format() == PIXEL_FORMAT_NV12 && profile_ == VP9PROFILE_PROFILE2;
|
||||
+ const bool needs_conversion_to_i420 =
|
||||
+ !IsYuvPlanar(frame->format()) || vp9_p2_needs_nv12_to_i420;
|
||||
+ if (frame->visible_rect().size() != options_.frame_size ||
|
||||
+ needs_conversion_to_i420) {
|
||||
+ auto new_pixel_format =
|
||||
+ needs_conversion_to_i420 ? PIXEL_FORMAT_I420 : frame->format();
|
||||
auto resized_frame = frame_pool_.CreateFrame(
|
||||
- is_yuv ? frame->format() : PIXEL_FORMAT_I420, options_.frame_size,
|
||||
- gfx::Rect(options_.frame_size), options_.frame_size,
|
||||
- frame->timestamp());
|
||||
+ new_pixel_format, options_.frame_size, gfx::Rect(options_.frame_size),
|
||||
+ options_.frame_size, frame->timestamp());
|
||||
|
||||
if (!resized_frame) {
|
||||
std::move(done_cb).Run(
|
||||
@@ -454,6 +462,7 @@ void VpxVideoEncoder::Encode(scoped_refptr<VideoFrame> frame,
|
||||
|
||||
switch (profile_) {
|
||||
case VP9PROFILE_PROFILE2:
|
||||
+ DCHECK_EQ(frame->format(), PIXEL_FORMAT_I420);
|
||||
// Profile 2 uses 10bit color,
|
||||
libyuv::I420ToI010(
|
||||
frame->visible_data(VideoFrame::kYPlane),
|
||||
47
patches/chromium/cherry-pick-d6946b70b431.patch
Normal file
47
patches/chromium/cherry-pick-d6946b70b431.patch
Normal file
@@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dave Tapuska <dtapuska@chromium.org>
|
||||
Date: Fri, 24 Mar 2023 19:32:54 +0000
|
||||
Subject: Move the edit commands to an on stack variable
|
||||
|
||||
DevTools uses nested event loops and the usage of the class member can
|
||||
be problematic for iteration because the nested loop can change the
|
||||
variable's storage causing a UAF.
|
||||
|
||||
(cherry picked from commit d9b34f0f3a2d0dd73648eca3ef940fb66806227b)
|
||||
|
||||
Bug: 1420510
|
||||
Change-Id: Ie08a71b60401fa4322cca0cc31062ba64672126a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4355811
|
||||
Reviewed-by: David Bokan <bokan@chromium.org>
|
||||
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1120123}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4369603
|
||||
Cr-Commit-Position: refs/branch-heads/5615@{#809}
|
||||
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
|
||||
index 2779b0a23477d33e747cb0d97079b463b1060652..b4ca94c7b39a090b7d9700cd86f04a71ebdfcf1f 100644
|
||||
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
|
||||
@@ -3182,11 +3182,18 @@ void WebFrameWidgetImpl::AddEditCommandForNextKeyEvent(const WebString& name,
|
||||
}
|
||||
|
||||
bool WebFrameWidgetImpl::HandleCurrentKeyboardEvent() {
|
||||
- bool did_execute_command = false;
|
||||
+ if (edit_commands_.empty()) {
|
||||
+ return false;
|
||||
+ }
|
||||
WebLocalFrame* frame = FocusedWebLocalFrameInWidget();
|
||||
if (!frame)
|
||||
frame = local_root_;
|
||||
- for (const auto& command : edit_commands_) {
|
||||
+ bool did_execute_command = false;
|
||||
+ // Executing an edit command can run JS and we can end up reassigning
|
||||
+ // `edit_commands_` so move it to a stack variable before iterating on it.
|
||||
+ Vector<mojom::blink::EditCommandPtr> edit_commands =
|
||||
+ std::move(edit_commands_);
|
||||
+ for (const auto& command : edit_commands) {
|
||||
// In gtk and cocoa, it's possible to bind multiple edit commands to one
|
||||
// key (but it's the exception). Once one edit command is not executed, it
|
||||
// seems safest to not execute the rest.
|
||||
90
patches/chromium/cherry-pick-d9081493c4b2.patch
Normal file
90
patches/chromium/cherry-pick-d9081493c4b2.patch
Normal file
@@ -0,0 +1,90 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kylechar <kylechar@chromium.org>
|
||||
Date: Tue, 28 Feb 2023 21:02:51 +0000
|
||||
Subject: Add CHECKs in HostFrameSinkManager
|
||||
|
||||
It looks like it's possible for a compromised renderer to get multiple
|
||||
things to register the same FrameSinkId with HostFrameSinkManager. This
|
||||
violates assumptions around ownership so turn DCHECKs here into CHECKs.
|
||||
Also convert DCHECKs into CHECKs for registering/unregistering frame
|
||||
sink hierarchy just in case.
|
||||
|
||||
(cherry picked from commit a707ac2d95e4726f4cf0267c9b0c038926c2a691)
|
||||
|
||||
Bug: 1414018
|
||||
Change-Id: If948e758a8484024666f4066360620bc3a9cb493
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4283141
|
||||
Reviewed-by: Martin Kreichgauer <martinkr@google.com>
|
||||
Reviewed-by: Jonathan Ross <jonross@chromium.org>
|
||||
Commit-Queue: Kyle Charbonneau <kylechar@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1109533}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4298330
|
||||
Cr-Commit-Position: refs/branch-heads/5615@{#69}
|
||||
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
|
||||
|
||||
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc
|
||||
index 8d724edf1624b83f896a9d2200542fc981e4005e..3ac8a9c13b6655591bf737578d7f9b5aa5874e57 100644
|
||||
--- a/components/viz/host/host_frame_sink_manager.cc
|
||||
+++ b/components/viz/host/host_frame_sink_manager.cc
|
||||
@@ -68,7 +68,7 @@ void HostFrameSinkManager::RegisterFrameSinkId(
|
||||
DCHECK(client);
|
||||
|
||||
FrameSinkData& data = frame_sink_data_map_[frame_sink_id];
|
||||
- DCHECK(!data.IsFrameSinkRegistered());
|
||||
+ CHECK(!data.IsFrameSinkRegistered());
|
||||
DCHECK(!data.has_created_compositor_frame_sink);
|
||||
data.client = client;
|
||||
data.report_activation = report_activation;
|
||||
@@ -87,7 +87,7 @@ void HostFrameSinkManager::InvalidateFrameSinkId(
|
||||
DCHECK(frame_sink_id.is_valid());
|
||||
|
||||
FrameSinkData& data = frame_sink_data_map_[frame_sink_id];
|
||||
- DCHECK(data.IsFrameSinkRegistered());
|
||||
+ CHECK(data.IsFrameSinkRegistered());
|
||||
|
||||
const bool destroy_synchronously =
|
||||
data.has_created_compositor_frame_sink && data.wait_on_destruction;
|
||||
@@ -227,14 +227,14 @@ bool HostFrameSinkManager::RegisterFrameSinkHierarchy(
|
||||
return false;
|
||||
}
|
||||
|
||||
+ FrameSinkData& parent_data = iter->second;
|
||||
+ CHECK(!base::Contains(parent_data.children, child_frame_sink_id));
|
||||
+ parent_data.children.push_back(child_frame_sink_id);
|
||||
+
|
||||
// Register and store the parent.
|
||||
frame_sink_manager_->RegisterFrameSinkHierarchy(parent_frame_sink_id,
|
||||
child_frame_sink_id);
|
||||
|
||||
- FrameSinkData& parent_data = iter->second;
|
||||
- DCHECK(!base::Contains(parent_data.children, child_frame_sink_id));
|
||||
- parent_data.children.push_back(child_frame_sink_id);
|
||||
-
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -243,8 +243,9 @@ void HostFrameSinkManager::UnregisterFrameSinkHierarchy(
|
||||
const FrameSinkId& child_frame_sink_id) {
|
||||
// Unregister and clear the stored parent.
|
||||
FrameSinkData& parent_data = frame_sink_data_map_[parent_frame_sink_id];
|
||||
- DCHECK(base::Contains(parent_data.children, child_frame_sink_id));
|
||||
- base::Erase(parent_data.children, child_frame_sink_id);
|
||||
+ size_t num_erased = base::Erase(parent_data.children, child_frame_sink_id);
|
||||
+ CHECK_EQ(num_erased, 1u);
|
||||
+
|
||||
if (parent_data.IsEmpty())
|
||||
frame_sink_data_map_.erase(parent_frame_sink_id);
|
||||
|
||||
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
|
||||
index 7c25edc433792408a7a285f9cc976289f6500398..20fa10b1e812b97337bfd57c2e4e18d03888c2f3 100644
|
||||
--- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
|
||||
+++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
|
||||
@@ -284,7 +284,7 @@ void FrameSinkManagerImpl::UnregisterFrameSinkHierarchy(
|
||||
}
|
||||
|
||||
auto iter = frame_sink_source_map_.find(parent_frame_sink_id);
|
||||
- DCHECK(iter != frame_sink_source_map_.end());
|
||||
+ CHECK(iter != frame_sink_source_map_.end());
|
||||
|
||||
// Remove |child_frame_sink_id| from parents list of children.
|
||||
auto& mapping = iter->second;
|
||||
58
patches/chromium/cherry-pick-e79b89b47dac.patch
Normal file
58
patches/chromium/cherry-pick-e79b89b47dac.patch
Normal file
@@ -0,0 +1,58 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Vasiliy Telezhnikov <vasilyt@chromium.org>
|
||||
Date: Fri, 10 Feb 2023 17:36:57 +0000
|
||||
Subject: CHECK that YUV readback finished synchronously
|
||||
|
||||
DoReadbackYUVImagePixelsINTERNAL is implemented using skia asynchronous
|
||||
readback and to make it synchronous we use sync cpu and gpu. In some
|
||||
edge cases on linux we saw that doesn't happen if readback triggered
|
||||
vulkan device lost.
|
||||
|
||||
To avoid use after free, CHECK that callback was actually called. In
|
||||
case of device-lost gpu process will restart anyway, so while this is
|
||||
not proper fix of the problem, it doesn't result in worse user visible
|
||||
behaviour.
|
||||
|
||||
(cherry picked from commit 081df1e7d3712131bcaa575bda2e37ec7f6aa83d)
|
||||
|
||||
Bug: 1399742
|
||||
Change-Id: Ie2172539bb907b9696ef62c70d398aca3967177c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4143606
|
||||
Reviewed-by: Peng Huang <penghuang@chromium.org>
|
||||
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1093064}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4239960
|
||||
Cr-Commit-Position: refs/branch-heads/5481@{#1084}
|
||||
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
|
||||
|
||||
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc
|
||||
index d2ac0ac70902d68b95417d2a95da153a7fc38128..ef79b5cbcc83d5ed12a9627ce76692476ace10a0 100644
|
||||
--- a/gpu/command_buffer/service/raster_decoder.cc
|
||||
+++ b/gpu/command_buffer/service/raster_decoder.cc
|
||||
@@ -2485,6 +2485,7 @@ void RasterDecoderImpl::DoReadbackARGBImagePixelsINTERNAL(
|
||||
namespace {
|
||||
struct YUVReadbackResult {
|
||||
std::unique_ptr<const SkImage::AsyncReadResult> async_result;
|
||||
+ bool finished = false;
|
||||
};
|
||||
|
||||
void OnReadYUVImagePixelsDone(
|
||||
@@ -2492,6 +2493,7 @@ void OnReadYUVImagePixelsDone(
|
||||
std::unique_ptr<const SkImage::AsyncReadResult> async_result) {
|
||||
YUVReadbackResult* context = reinterpret_cast<YUVReadbackResult*>(raw_ctx);
|
||||
context->async_result = std::move(async_result);
|
||||
+ context->finished = true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -2689,6 +2691,10 @@ void RasterDecoderImpl::DoReadbackYUVImagePixelsINTERNAL(
|
||||
// asynchronous by removing this flush and implementing a query that can
|
||||
// signal back to client process.
|
||||
gr_context()->flushAndSubmit(true);
|
||||
+
|
||||
+ // The call above will sync up gpu and CPU, resulting in callback being run
|
||||
+ // during flushAndSubmit. To prevent UAF make sure it indeed happened.
|
||||
+ CHECK(yuv_result.finished);
|
||||
if (!yuv_result.async_result) {
|
||||
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glReadbackYUVImagePixels",
|
||||
"Failed to read pixels from SkImage");
|
||||
200
patches/chromium/cherry-pick-ea1cd76358e0.patch
Normal file
200
patches/chromium/cherry-pick-ea1cd76358e0.patch
Normal file
@@ -0,0 +1,200 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin McNee <mcnee@chromium.org>
|
||||
Date: Tue, 23 May 2023 15:46:16 +0000
|
||||
Subject: M114: Compute all webview find options before cloning them
|
||||
|
||||
Compute all webview find options before cloning them
|
||||
|
||||
In WebViewFindHelper::Find, we're cloning the find options before we've
|
||||
set the value for `new_session`. For requests that are part of the same
|
||||
session, in WebViewFindHelper::FindReply, we're using the incorrect
|
||||
value for `new_session` and we're destroying the FindInfo for what we
|
||||
think is a previous session but is actually for the request we're
|
||||
currently processing.
|
||||
|
||||
We now fully compute the options before cloning them.
|
||||
|
||||
(cherry picked from commit bb8e17b942b8b1de0a58b2dce34197e00a3b6525)
|
||||
|
||||
Bug: 1443401
|
||||
Change-Id: Ife6747aedabaf74f9a4855a173349ffe612b6f95
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4533923
|
||||
Reviewed-by: James Maclean <wjmaclean@chromium.org>
|
||||
Commit-Queue: James Maclean <wjmaclean@chromium.org>
|
||||
Auto-Submit: Kevin McNee <mcnee@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1145265}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4556646
|
||||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5735@{#941}
|
||||
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
|
||||
|
||||
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
|
||||
index 4e6212397a183fdf494f271a255eaf2d536587e6..7159cf6af5cfd0ad5b9e5ba526043a4407a5399d 100644
|
||||
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
|
||||
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
|
||||
@@ -3851,6 +3851,11 @@ IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_testFindInMultipleWebViews) {
|
||||
TestHelper("testFindInMultipleWebViews", "web_view/shim", NO_TEST_SERVER);
|
||||
}
|
||||
|
||||
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestFindAfterTerminate) {
|
||||
+ content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
|
||||
+ TestHelper("testFindAfterTerminate", "web_view/shim", NO_TEST_SERVER);
|
||||
+}
|
||||
+
|
||||
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadDataAPI) {
|
||||
TestHelper("testLoadDataAPI", "web_view/shim", NEEDS_TEST_SERVER);
|
||||
|
||||
diff --git a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
|
||||
index 5ed4f0223346b01d83cc04c8cda6c0e92e1a72e3..4a1543d1751cc817a511594d0123deacc0e61ebb 100644
|
||||
--- a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
|
||||
+++ b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
|
||||
@@ -2859,6 +2859,20 @@ function testFindInMultipleWebViews() {
|
||||
});
|
||||
}
|
||||
|
||||
+function testFindAfterTerminate() {
|
||||
+ let webview = new WebView();
|
||||
+ webview.src = 'data:text/html,<body><iframe></iframe></body>';
|
||||
+ webview.addEventListener('loadstop', () => {
|
||||
+ webview.find('A');
|
||||
+ webview.terminate();
|
||||
+ webview.find('B', {'backward': true});
|
||||
+ webview.find('B', {'backward': true}, (results) => {
|
||||
+ embedder.test.succeed();
|
||||
+ });
|
||||
+ });
|
||||
+ document.body.appendChild(webview);
|
||||
+}
|
||||
+
|
||||
function testLoadDataAPI() {
|
||||
var webview = new WebView();
|
||||
webview.src = 'about:blank';
|
||||
@@ -3600,6 +3614,7 @@ embedder.test.testList = {
|
||||
'testFindAPI': testFindAPI,
|
||||
'testFindAPI_findupdate': testFindAPI_findupdate,
|
||||
'testFindInMultipleWebViews': testFindInMultipleWebViews,
|
||||
+ 'testFindAfterTerminate': testFindAfterTerminate,
|
||||
'testLoadDataAPI': testLoadDataAPI,
|
||||
'testLoadDataAPIAccessibleResources': testLoadDataAPIAccessibleResources,
|
||||
'testResizeEvents': testResizeEvents,
|
||||
diff --git a/extensions/browser/guest_view/web_view/web_view_find_helper.cc b/extensions/browser/guest_view/web_view/web_view_find_helper.cc
|
||||
index 07b8a6975907190741267e3f92c2e9bde5d9c5d6..f7e5c7c6ece05fa59374735cb1757d1918d1597c 100644
|
||||
--- a/extensions/browser/guest_view/web_view/web_view_find_helper.cc
|
||||
+++ b/extensions/browser/guest_view/web_view/web_view_find_helper.cc
|
||||
@@ -36,12 +36,12 @@ void WebViewFindHelper::CancelAllFindSessions() {
|
||||
|
||||
void WebViewFindHelper::DispatchFindUpdateEvent(bool canceled,
|
||||
bool final_update) {
|
||||
- DCHECK(find_update_event_.get());
|
||||
+ CHECK(find_update_event_);
|
||||
std::unique_ptr<base::DictionaryValue> args(new base::DictionaryValue());
|
||||
find_update_event_->PrepareResults(args.get());
|
||||
args->SetBoolKey(webview::kFindCanceled, canceled);
|
||||
args->SetBoolKey(webview::kFindFinalUpdate, final_update);
|
||||
- DCHECK(webview_guest_);
|
||||
+ CHECK(webview_guest_);
|
||||
webview_guest_->DispatchEventToView(std::make_unique<GuestViewEvent>(
|
||||
webview::kEventFindReply, std::move(args)));
|
||||
}
|
||||
@@ -94,6 +94,17 @@ void WebViewFindHelper::Find(
|
||||
// Need a new request_id for each new find request.
|
||||
++current_find_request_id_;
|
||||
|
||||
+ if (current_find_session_) {
|
||||
+ const std::u16string& current_search_text =
|
||||
+ current_find_session_->search_text();
|
||||
+ bool current_match_case = current_find_session_->options()->match_case;
|
||||
+ options->new_session = current_search_text.empty() ||
|
||||
+ current_search_text != search_text ||
|
||||
+ current_match_case != options->match_case;
|
||||
+ } else {
|
||||
+ options->new_session = true;
|
||||
+ }
|
||||
+
|
||||
// Stores the find request information by request_id so that its callback
|
||||
// function can be called when the find results are available.
|
||||
std::pair<FindInfoMap::iterator, bool> insert_result =
|
||||
@@ -102,32 +113,19 @@ void WebViewFindHelper::Find(
|
||||
base::MakeRefCounted<FindInfo>(current_find_request_id_, search_text,
|
||||
options.Clone(), find_function)));
|
||||
// No duplicate insertions.
|
||||
- DCHECK(insert_result.second);
|
||||
-
|
||||
- blink::mojom::FindOptionsPtr full_options =
|
||||
- insert_result.first->second->options().Clone();
|
||||
-
|
||||
- if (current_find_session_) {
|
||||
- const std::u16string& current_search_text =
|
||||
- current_find_session_->search_text();
|
||||
- bool current_match_case = current_find_session_->options()->match_case;
|
||||
- full_options->new_session = current_search_text.empty() ||
|
||||
- current_search_text != search_text ||
|
||||
- current_match_case != options->match_case;
|
||||
- } else {
|
||||
- full_options->new_session = true;
|
||||
- }
|
||||
+ CHECK(insert_result.second);
|
||||
|
||||
// Link find requests that are a part of the same find session.
|
||||
- if (!full_options->new_session && current_find_session_) {
|
||||
- DCHECK(current_find_request_id_ != current_find_session_->request_id());
|
||||
+ if (!options->new_session && current_find_session_) {
|
||||
+ CHECK(current_find_request_id_ != current_find_session_->request_id());
|
||||
current_find_session_->AddFindNextRequest(
|
||||
insert_result.first->second->AsWeakPtr());
|
||||
}
|
||||
|
||||
// Update the current find session, if necessary.
|
||||
- if (full_options->new_session)
|
||||
+ if (options->new_session) {
|
||||
current_find_session_ = insert_result.first->second;
|
||||
+ }
|
||||
|
||||
// Handle the empty |search_text| case internally.
|
||||
if (search_text.empty()) {
|
||||
@@ -137,7 +135,7 @@ void WebViewFindHelper::Find(
|
||||
}
|
||||
|
||||
guest_web_contents->Find(current_find_request_id_, search_text,
|
||||
- std::move(full_options), /*skip_delay=*/true);
|
||||
+ std::move(options), /*skip_delay=*/true);
|
||||
}
|
||||
|
||||
void WebViewFindHelper::FindReply(int request_id,
|
||||
@@ -152,14 +150,14 @@ void WebViewFindHelper::FindReply(int request_id,
|
||||
return;
|
||||
|
||||
// This find request must be a part of an existing find session.
|
||||
- DCHECK(current_find_session_);
|
||||
+ CHECK(current_find_session_);
|
||||
|
||||
WebViewFindHelper::FindInfo* find_info = find_iterator->second.get();
|
||||
// Handle canceled find requests.
|
||||
if (find_info->options()->new_session &&
|
||||
find_info_map_.begin()->first < request_id) {
|
||||
- DCHECK_NE(current_find_session_->request_id(),
|
||||
- find_info_map_.begin()->first);
|
||||
+ CHECK_NE(current_find_session_->request_id(),
|
||||
+ find_info_map_.begin()->first);
|
||||
if (find_update_event_)
|
||||
DispatchFindUpdateEvent(true /* canceled */, true /* final_update */);
|
||||
EndFindSession(find_info_map_.begin()->first, true /* canceled */);
|
||||
@@ -174,11 +172,12 @@ void WebViewFindHelper::FindReply(int request_id,
|
||||
// Aggregate the find results.
|
||||
find_info->AggregateResults(number_of_matches, selection_rect,
|
||||
active_match_ordinal, final_update);
|
||||
- find_update_event_->AggregateResults(number_of_matches, selection_rect,
|
||||
- active_match_ordinal, final_update);
|
||||
-
|
||||
- // Propagate incremental results to the |findupdate| event.
|
||||
- DispatchFindUpdateEvent(false /* canceled */, final_update);
|
||||
+ if (find_update_event_) {
|
||||
+ find_update_event_->AggregateResults(number_of_matches, selection_rect,
|
||||
+ active_match_ordinal, final_update);
|
||||
+ // Propagate incremental results to the |findupdate| event.
|
||||
+ DispatchFindUpdateEvent(false /* canceled */, final_update);
|
||||
+ }
|
||||
|
||||
// Call the callback functions of completed find requests.
|
||||
if (final_update)
|
||||
127
patches/chromium/cherry-pick-f098ff0d1230.patch
Normal file
127
patches/chromium/cherry-pick-f098ff0d1230.patch
Normal file
@@ -0,0 +1,127 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Kosyakov <caseq@chromium.org>
|
||||
Date: Thu, 13 Apr 2023 03:55:24 +0000
|
||||
Subject: Retain DevToolsAgentHost after ForceDetachAllSessions()
|
||||
|
||||
(cherry picked from commit 8c4aee2a90d08535cfb1bf0a59e00cae956b1762)
|
||||
|
||||
Bug: 1424337
|
||||
Change-Id: Ie0ebe2a49ffbd2356b896c39446b93e09cd81f5a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4378100
|
||||
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
|
||||
Commit-Queue: Andrey Kosyakov <caseq@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1123772}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4420271
|
||||
Commit-Queue: Srinivas Sista <srinivassista@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5615@{#1244}
|
||||
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
|
||||
|
||||
diff --git a/content/browser/devtools/auction_worklet_devtools_agent_host.cc b/content/browser/devtools/auction_worklet_devtools_agent_host.cc
|
||||
index 20a989999b6da5d269bca3d6c9bf181eea7180e7..34a13a884885926e3985098315fd9121902099e9 100644
|
||||
--- a/content/browser/devtools/auction_worklet_devtools_agent_host.cc
|
||||
+++ b/content/browser/devtools/auction_worklet_devtools_agent_host.cc
|
||||
@@ -96,7 +96,7 @@ AuctionWorkletDevToolsAgentHost::~AuctionWorkletDevToolsAgentHost() = default;
|
||||
|
||||
void AuctionWorkletDevToolsAgentHost::WorkletDestroyed() {
|
||||
worklet_ = nullptr;
|
||||
- ForceDetachAllSessions();
|
||||
+ auto retain_this = ForceDetachAllSessionsImpl();
|
||||
associated_agent_remote_.reset();
|
||||
}
|
||||
|
||||
diff --git a/content/browser/devtools/devtools_agent_host_impl.cc b/content/browser/devtools/devtools_agent_host_impl.cc
|
||||
index 46314287ac23017f597c8f63d41cab7e46e2a53a..33f8676e811f3f5684bbd7dabae392668f34f20b 100644
|
||||
--- a/content/browser/devtools/devtools_agent_host_impl.cc
|
||||
+++ b/content/browser/devtools/devtools_agent_host_impl.cc
|
||||
@@ -350,12 +350,18 @@ bool DevToolsAgentHostImpl::Inspect() {
|
||||
}
|
||||
|
||||
void DevToolsAgentHostImpl::ForceDetachAllSessions() {
|
||||
- scoped_refptr<DevToolsAgentHostImpl> protect(this);
|
||||
+ std::ignore = ForceDetachAllSessionsImpl();
|
||||
+}
|
||||
+
|
||||
+scoped_refptr<DevToolsAgentHost>
|
||||
+DevToolsAgentHostImpl::ForceDetachAllSessionsImpl() {
|
||||
+ scoped_refptr<DevToolsAgentHost> retain_this(this);
|
||||
while (!sessions_.empty()) {
|
||||
DevToolsAgentHostClient* client = (*sessions_.begin())->GetClient();
|
||||
DetachClient(client);
|
||||
client->AgentHostClosed(this);
|
||||
}
|
||||
+ return retain_this;
|
||||
}
|
||||
|
||||
void DevToolsAgentHostImpl::ForceDetachRestrictedSessions(
|
||||
diff --git a/content/browser/devtools/devtools_agent_host_impl.h b/content/browser/devtools/devtools_agent_host_impl.h
|
||||
index 4c54b9100ef287d5ac5c45235d3a93187df2ca14..f29b5323c4555a96c069377df2b7f126abd029af 100644
|
||||
--- a/content/browser/devtools/devtools_agent_host_impl.h
|
||||
+++ b/content/browser/devtools/devtools_agent_host_impl.h
|
||||
@@ -119,15 +119,24 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
|
||||
void NotifyCreated();
|
||||
void NotifyNavigated();
|
||||
void NotifyCrashed(base::TerminationStatus status);
|
||||
- void ForceDetachAllSessions();
|
||||
void ForceDetachRestrictedSessions(
|
||||
const std::vector<DevToolsSession*>& restricted_sessions);
|
||||
DevToolsIOContext* GetIOContext() { return &io_context_; }
|
||||
DevToolsRendererChannel* GetRendererChannel() { return &renderer_channel_; }
|
||||
|
||||
const std::vector<DevToolsSession*>& sessions() const { return sessions_; }
|
||||
+ // Returns refptr retaining `this`. All other references may be removed
|
||||
+ // at this point, so `this` will become invalid as soon as returned refptr
|
||||
+ // gets destroyed.
|
||||
+ [[nodiscard]] scoped_refptr<DevToolsAgentHost> ForceDetachAllSessionsImpl();
|
||||
|
||||
private:
|
||||
+ // Note that calling this may result in the instance being deleted,
|
||||
+ // as instance may be owned by client sessions. This should not be
|
||||
+ // used by methods of derived classes, use `ForceDetachAllSessionsImpl()`
|
||||
+ // above instead.
|
||||
+ void ForceDetachAllSessions();
|
||||
+
|
||||
friend class DevToolsAgentHost; // for static methods
|
||||
friend class DevToolsSession;
|
||||
friend class DevToolsRendererChannel;
|
||||
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
|
||||
index 2441cbcc429b9458af7743f1a2c5040b91163e4f..71607bffebc49b0a9b898e5ef1ac652190e8eb4f 100644
|
||||
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
|
||||
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
|
||||
@@ -541,9 +541,9 @@ void RenderFrameDevToolsAgentHost::RenderFrameDeleted(RenderFrameHost* rfh) {
|
||||
}
|
||||
|
||||
void RenderFrameDevToolsAgentHost::DestroyOnRenderFrameGone() {
|
||||
- scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
|
||||
+ scoped_refptr<DevToolsAgentHost> retain_this;
|
||||
if (IsAttached()) {
|
||||
- ForceDetachAllSessions();
|
||||
+ retain_this = ForceDetachAllSessionsImpl();
|
||||
UpdateRawHeadersAccess(frame_host_);
|
||||
}
|
||||
ChangeFrameHostAndObservedProcess(nullptr);
|
||||
diff --git a/content/browser/devtools/web_contents_devtools_agent_host.cc b/content/browser/devtools/web_contents_devtools_agent_host.cc
|
||||
index 20976a4f189446f0cf3b0a0ab168ceb4a92eebe1..7d12f4f8b030200b49350d379f25d4b64b0d1a06 100644
|
||||
--- a/content/browser/devtools/web_contents_devtools_agent_host.cc
|
||||
+++ b/content/browser/devtools/web_contents_devtools_agent_host.cc
|
||||
@@ -299,7 +299,7 @@ DevToolsAgentHostImpl* WebContentsDevToolsAgentHost::GetPrimaryFrameAgent() {
|
||||
|
||||
void WebContentsDevToolsAgentHost::WebContentsDestroyed() {
|
||||
DCHECK_EQ(this, FindAgentHost(web_contents()));
|
||||
- ForceDetachAllSessions();
|
||||
+ auto retain_this = ForceDetachAllSessionsImpl();
|
||||
auto_attacher_.reset();
|
||||
g_agent_host_instances.Get().erase(web_contents());
|
||||
Observe(nullptr);
|
||||
diff --git a/content/browser/devtools/worker_devtools_agent_host.cc b/content/browser/devtools/worker_devtools_agent_host.cc
|
||||
index db788e7298d6696ec5a354cb387dfdc4030d8ce0..0984b3ae35459d8676b903394577cc6a43601ac8 100644
|
||||
--- a/content/browser/devtools/worker_devtools_agent_host.cc
|
||||
+++ b/content/browser/devtools/worker_devtools_agent_host.cc
|
||||
@@ -87,7 +87,7 @@ void WorkerDevToolsAgentHost::ChildWorkerCreated(
|
||||
}
|
||||
|
||||
void WorkerDevToolsAgentHost::Disconnected() {
|
||||
- ForceDetachAllSessions();
|
||||
+ auto retain_this = ForceDetachAllSessionsImpl();
|
||||
GetRendererChannel()->SetRenderer(mojo::NullRemote(), mojo::NullReceiver(),
|
||||
ChildProcessHost::kInvalidUniqueID);
|
||||
std::move(destroyed_callback_).Run(this);
|
||||
98
patches/chromium/cherry-pick-f58218891f8c.patch
Normal file
98
patches/chromium/cherry-pick-f58218891f8c.patch
Normal file
@@ -0,0 +1,98 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
|
||||
Date: Tue, 11 Apr 2023 07:12:34 +0000
|
||||
Subject: Stop supporting { handleEvent }.
|
||||
|
||||
Make the code aligned with the following specification update:
|
||||
https://github.com/w3c/ServiceWorker/pull/1676
|
||||
|
||||
With the previous specification and code, event listener vector
|
||||
can be modified during the GetEffectiveFunction execution, which may
|
||||
bring unexpected vector state.
|
||||
|
||||
(cherry picked from commit 5105ce37a6853d52ec97894bf6969b3c29a23afd)
|
||||
|
||||
Change-Id: I732c4c9ab2caebc49a7f4ef52640df7b8476d838
|
||||
Bug: 1429201
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4394402
|
||||
Commit-Queue: Yoshisato Yanagisawa <yyanagisawa@chromium.org>
|
||||
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
|
||||
Reviewed-by: Domenic Denicola <domenic@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1126483}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4408837
|
||||
Reviewed-by: Shunya Shishido <sisidovski@chromium.org>
|
||||
Reviewed-by: Minoru Chikamune <chikamune@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5615@{#1203}
|
||||
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
|
||||
|
||||
diff --git a/content/browser/service_worker/service_worker_version_browsertest.cc b/content/browser/service_worker/service_worker_version_browsertest.cc
|
||||
index 0435c5a1850dd3ed16197bbc40c1e276e4613a60..a9ad30764c578d1e6cf15bd114ca46e169012039 100644
|
||||
--- a/content/browser/service_worker/service_worker_version_browsertest.cc
|
||||
+++ b/content/browser/service_worker/service_worker_version_browsertest.cc
|
||||
@@ -988,6 +988,17 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
|
||||
version_->fetch_handler_type());
|
||||
}
|
||||
|
||||
+IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
|
||||
+ RemoveFetchEventListenersInGet) {
|
||||
+ StartServerAndNavigateToSetup();
|
||||
+ ASSERT_EQ(Install("/service_worker/fetch_event_object_removing_itself.js"),
|
||||
+ blink::ServiceWorkerStatusCode::kOk);
|
||||
+ EXPECT_EQ(ServiceWorkerVersion::FetchHandlerExistence::EXISTS,
|
||||
+ version_->fetch_handler_existence());
|
||||
+ EXPECT_EQ(ServiceWorkerVersion::FetchHandlerType::kNotSkippable,
|
||||
+ version_->fetch_handler_type());
|
||||
+}
|
||||
+
|
||||
// Check that fetch event handler added in the install event should result in a
|
||||
// service worker that doesn't count as having a fetch event handler.
|
||||
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
|
||||
diff --git a/content/test/data/service_worker/fetch_event_object_removing_itself.js b/content/test/data/service_worker/fetch_event_object_removing_itself.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..110bc4821fae3a63a374d3dc6ca954d4bd744952
|
||||
--- /dev/null
|
||||
+++ b/content/test/data/service_worker/fetch_event_object_removing_itself.js
|
||||
@@ -0,0 +1,19 @@
|
||||
+// Copyright 2023 The Chromium Authors
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+let obj = {};
|
||||
+function victim() {}
|
||||
+
|
||||
+Object.defineProperty(obj, 'handleEvent', {
|
||||
+ get: () => {
|
||||
+ // Remove the victim function from the listener vector to break the loop.
|
||||
+ self.removeEventListener('fetch', victim);
|
||||
+ return () => {};
|
||||
+ },
|
||||
+ configurable: true,
|
||||
+ enumerable: true,
|
||||
+});
|
||||
+
|
||||
+self.addEventListener('fetch', obj);
|
||||
+self.addEventListener('fetch', victim);
|
||||
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
|
||||
index b3a9f691a0fabf14bf6f319173f400c31c664c12..9523aa1ee53aeabe03281a34b4a290a68f6a7dc4 100644
|
||||
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
|
||||
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
|
||||
@@ -2604,7 +2604,7 @@ ServiceWorkerGlobalScope::FetchHandlerType() {
|
||||
}
|
||||
|
||||
ScriptState* script_state = ScriptController()->GetScriptState();
|
||||
- // Do not remove this, |scope| is needed by `GetEffectiveFunction`.
|
||||
+ // Do not remove this, |scope| is needed by `GetListenerObject`.
|
||||
ScriptState::Scope scope(script_state);
|
||||
|
||||
// TODO(crbug.com/1349613): revisit the way to implement this.
|
||||
@@ -2612,8 +2612,8 @@ ServiceWorkerGlobalScope::FetchHandlerType() {
|
||||
for (RegisteredEventListener& e : *elv) {
|
||||
EventTarget* et = EventTarget::Create(script_state);
|
||||
v8::Local<v8::Value> v =
|
||||
- To<JSBasedEventListener>(e.Callback())->GetEffectiveFunction(*et);
|
||||
- if (!v->IsFunction() ||
|
||||
+ To<JSBasedEventListener>(e.Callback())->GetListenerObject(*et);
|
||||
+ if (v.IsEmpty() || !v->IsFunction() ||
|
||||
!v.As<v8::Function>()->Experimental_IsNopFunction()) {
|
||||
return mojom::blink::ServiceWorkerFetchHandlerType::kNotSkippable;
|
||||
}
|
||||
107
patches/chromium/fix_crash_in_annotationagentimpl.patch
Normal file
107
patches/chromium/fix_crash_in_annotationagentimpl.patch
Normal file
@@ -0,0 +1,107 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Bokan <bokan@chromium.org>
|
||||
Date: Fri, 3 Mar 2023 21:54:38 +0000
|
||||
Subject: Fix crash in AnnotationAgentImpl
|
||||
|
||||
This crash was occurring because the EphemeralRangeInFlatTree didn't
|
||||
produce a Node. This is surprising since the RangeInFlatTree that it
|
||||
comes from is checked for !IsCollapsed().
|
||||
|
||||
It turns out it's possible for RangeInFlatTree to be !IsCollapsed but
|
||||
converting to EphemeralRangeInFlatTree causes IsCollapsed.
|
||||
|
||||
This CL ensures we early-out in the case that's tripping the CHECK. It
|
||||
keeps the early-out exactly matching the CHECK since it must be merged
|
||||
so we want to be extra sure. A followup will change this condition to
|
||||
!EphemeralRangeInFlatTree::IsCollapsed which should be equivalent.
|
||||
|
||||
(cherry picked from commit 92782b6d34b7a5e26d184e217f8f44e97539686e)
|
||||
|
||||
Bug: 1419712
|
||||
Change-Id: Id1d66a7a67711d463780b37c00600183d6c14f32
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4304486
|
||||
Reviewed-by: Khushal Sagar <khushalsagar@chromium.org>
|
||||
Commit-Queue: David Bokan <bokan@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1112568}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4305328
|
||||
Commit-Queue: Krishna Govind <govind@chromium.org>
|
||||
Reviewed-by: David Bokan <bokan@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5481@{#1321}
|
||||
Cr-Branched-From: 130f3e4d850f4bc7387cfb8d08aa993d288a67a9-refs/heads/main@{#1084008}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc b/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc
|
||||
index 9e9181677fb676100ff2a20890e902f298b16644..a5553945fb5923b93dbdf37c6b7b539049018dbb 100644
|
||||
--- a/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/annotation/annotation_agent_impl.cc
|
||||
@@ -117,7 +117,11 @@ void AnnotationAgentImpl::ScrollIntoView() const {
|
||||
|
||||
EphemeralRangeInFlatTree range = attached_range_->ToEphemeralRange();
|
||||
|
||||
- CHECK(range.Nodes().begin() != range.Nodes().end());
|
||||
+ // TODO(bokan): This should be checked in IsAttached.
|
||||
+ bool range_has_nodes = range.Nodes().begin() != range.Nodes().end();
|
||||
+ if (!range_has_nodes) {
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
Node& first_node = *range.Nodes().begin();
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/annotation/annotation_agent_impl_test.cc b/third_party/blink/renderer/core/annotation/annotation_agent_impl_test.cc
|
||||
index 08b6bc177e684c83f51227dc41dc0b894be8a2a7..fbb6f5f1f34b4b26459450ebe35e917e02e47f10 100644
|
||||
--- a/third_party/blink/renderer/core/annotation/annotation_agent_impl_test.cc
|
||||
+++ b/third_party/blink/renderer/core/annotation/annotation_agent_impl_test.cc
|
||||
@@ -643,4 +643,54 @@ TEST_F(AnnotationAgentImplTest, AgentScrollIntoViewZoomed) {
|
||||
EXPECT_TRUE(ExpectInViewport(*element_foo));
|
||||
}
|
||||
|
||||
+// Degenerate case but make sure it doesn't crash. This constructs a
|
||||
+// RangeInFlatTree that isn't collapsed but turns into a collapsed
|
||||
+// EphmemeralRangeInFlatTree.
|
||||
+TEST_F(AnnotationAgentImplTest, ScrollIntoViewCollapsedRange) {
|
||||
+ SimRequest request("https://example.com/test.html", "text/html");
|
||||
+ LoadURL("https://example.com/test.html");
|
||||
+ request.Complete(R"HTML(
|
||||
+ <!DOCTYPE html>
|
||||
+ <style>
|
||||
+ p {
|
||||
+ position: absolute;
|
||||
+ top: 2000px;
|
||||
+ }
|
||||
+ </style>
|
||||
+ <p id='text'>a</p>
|
||||
+
|
||||
+ )HTML");
|
||||
+
|
||||
+ Compositor().BeginFrame();
|
||||
+
|
||||
+ Element* element_text = GetDocument().getElementById("text");
|
||||
+
|
||||
+ const auto& range_start =
|
||||
+ Position(element_text->firstChild(), PositionAnchorType::kBeforeAnchor);
|
||||
+ const auto& range_end = Position(element_text, 0);
|
||||
+
|
||||
+ RangeInFlatTree* range = MakeGarbageCollected<RangeInFlatTree>(
|
||||
+ ToPositionInFlatTree(range_start), ToPositionInFlatTree(range_end));
|
||||
+
|
||||
+ // TODO(bokan): Is this an editing bug?
|
||||
+ ASSERT_FALSE(range->IsCollapsed());
|
||||
+ ASSERT_TRUE(range->ToEphemeralRange().IsCollapsed());
|
||||
+
|
||||
+ auto* agent = CreateAgentForRange(range);
|
||||
+ ASSERT_TRUE(agent);
|
||||
+
|
||||
+ ASSERT_EQ(GetDocument().View()->GetRootFrameViewport()->GetScrollOffset(),
|
||||
+ ScrollOffset());
|
||||
+
|
||||
+ MockAnnotationAgentHost host;
|
||||
+ host.BindToAgent(*agent);
|
||||
+ agent->Attach();
|
||||
+
|
||||
+ // Ensure calling ScrollIntoView doesn't crash.
|
||||
+ host.agent_->ScrollIntoView();
|
||||
+ host.FlushForTesting();
|
||||
+ EXPECT_EQ(GetDocument().View()->GetRootFrameViewport()->GetScrollOffset().y(),
|
||||
+ 0);
|
||||
+}
|
||||
+
|
||||
} // namespace blink
|
||||
@@ -0,0 +1,55 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Wed, 15 Feb 2023 11:30:56 +0900
|
||||
Subject: fix: restoring a X11 window should not remove its previous maximized
|
||||
state
|
||||
|
||||
On Linux after minimizing a maximized window, it will have both the
|
||||
"maximized" and "hidden" states, and restoring the window should only remove
|
||||
the "hidden" state, which makes it back a maximized window.
|
||||
|
||||
However in the implementation of `X11Window::Restore`, both "maximized" and
|
||||
"hidden" states are removed, and a maximized window that was minimized will
|
||||
be resized to its normal size after calling Restore, while the correct
|
||||
behavior should be going back to the maximized state.
|
||||
|
||||
Backported from:
|
||||
https://chromium-review.googlesource.com/c/chromium/src/+/4252946
|
||||
|
||||
diff --git a/ui/ozone/platform/x11/x11_window.cc b/ui/ozone/platform/x11/x11_window.cc
|
||||
index 45e0a75a643c2d7a70af37cbf38dcbde52fdd0cf..b229800eafabb0c810430d615cc165ff1e356491 100644
|
||||
--- a/ui/ozone/platform/x11/x11_window.cc
|
||||
+++ b/ui/ozone/platform/x11/x11_window.cc
|
||||
@@ -729,11 +729,16 @@ void X11Window::Minimize() {
|
||||
}
|
||||
|
||||
void X11Window::Restore() {
|
||||
- should_maximize_after_map_ = false;
|
||||
- restore_in_flight_ = true;
|
||||
- SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
|
||||
- x11::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
|
||||
- SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_HIDDEN"), x11::Atom::None);
|
||||
+ if (IsMinimized()) {
|
||||
+ restore_in_flight_ = true;
|
||||
+ SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_HIDDEN"),
|
||||
+ x11::Atom::None);
|
||||
+ } else if (IsMaximized()) {
|
||||
+ restore_in_flight_ = true;
|
||||
+ should_maximize_after_map_ = false;
|
||||
+ SetWMSpecState(false, x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
|
||||
+ x11::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
|
||||
+ }
|
||||
}
|
||||
|
||||
PlatformWindowState X11Window::GetPlatformWindowState() const {
|
||||
@@ -1884,6 +1889,10 @@ bool X11Window::IsMinimized() const {
|
||||
}
|
||||
|
||||
bool X11Window::IsMaximized() const {
|
||||
+ // In X11, if a maximized window is minimized, it will have both the "hidden"
|
||||
+ // and "maximized" states.
|
||||
+ if (IsMinimized())
|
||||
+ return false;
|
||||
return (HasWMSpecProperty(window_properties_,
|
||||
x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT")) &&
|
||||
HasWMSpecProperty(window_properties_,
|
||||
@@ -0,0 +1,72 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Will Harris <wfh@chromium.org>
|
||||
Date: Thu, 2 Mar 2023 17:01:49 +0000
|
||||
Subject: Do not register browser_watcher activity report with crashpad
|
||||
|
||||
BUG=1415328
|
||||
|
||||
(cherry picked from commit f93c88303ccbb64014a575b8ae093aa166832922)
|
||||
|
||||
Change-Id: I109f6dac083a69a26841ee5e975e02093ca4cbf6
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4257669
|
||||
Commit-Queue: Will Harris <wfh@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1106253}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4279942
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Zakhar Voit <voit@google.com>
|
||||
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1401}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/components/crash/core/app/BUILD.gn b/components/crash/core/app/BUILD.gn
|
||||
index 09219dd91f4205b38b36d3f62483cf2e9fc3782b..a45dec6b0708a0b0df1fc0f62283c730611b93b7 100644
|
||||
--- a/components/crash/core/app/BUILD.gn
|
||||
+++ b/components/crash/core/app/BUILD.gn
|
||||
@@ -159,7 +159,6 @@ if (is_win) {
|
||||
deps = [
|
||||
"//base",
|
||||
"//build:chromeos_buildflags",
|
||||
- "//components/browser_watcher:activity_report",
|
||||
"//components/gwp_asan/buildflags",
|
||||
"//third_party/crashpad/crashpad/client",
|
||||
"//third_party/crashpad/crashpad/handler",
|
||||
diff --git a/components/crash/core/app/DEPS b/components/crash/core/app/DEPS
|
||||
index 9717215396c918c46e683321115ed55ebcf6534d..9053a97a7068d5c3a240c9c7e99b0f7c2c2c038d 100644
|
||||
--- a/components/crash/core/app/DEPS
|
||||
+++ b/components/crash/core/app/DEPS
|
||||
@@ -3,7 +3,6 @@ include_rules = [
|
||||
"+third_party/breakpad",
|
||||
|
||||
"+components/crash/android/jni_headers",
|
||||
- "+components/browser_watcher/activity_report_user_stream_data_source.h",
|
||||
"+components/gwp_asan/buildflags/buildflags.h",
|
||||
"+components/gwp_asan/crash_handler/crash_handler.h",
|
||||
"+content/public/common/content_descriptors.h",
|
||||
diff --git a/components/crash/core/app/run_as_crashpad_handler_win.cc b/components/crash/core/app/run_as_crashpad_handler_win.cc
|
||||
index 5ae2702540dd635fa208f01ee84e92b2c2f1e220..ac2a160a172a75e6e4d12033b62c73551fb3e288 100644
|
||||
--- a/components/crash/core/app/run_as_crashpad_handler_win.cc
|
||||
+++ b/components/crash/core/app/run_as_crashpad_handler_win.cc
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/platform_thread.h"
|
||||
-#include "components/browser_watcher/activity_report_user_stream_data_source.h"
|
||||
#include "components/gwp_asan/buildflags/buildflags.h"
|
||||
#include "third_party/crashpad/crashpad/client/crashpad_info.h"
|
||||
#include "third_party/crashpad/crashpad/client/simple_string_dictionary.h"
|
||||
@@ -81,15 +80,6 @@ int RunAsCrashpadHandler(const base::CommandLine& command_line,
|
||||
argv.clear();
|
||||
|
||||
crashpad::UserStreamDataSources user_stream_data_sources;
|
||||
- // Interpret an empty user data directory as a missing value.
|
||||
- if (!user_data_dir.empty()) {
|
||||
- // Register an extension to collect stability information. The extension
|
||||
- // will be invoked for any registered process' crashes, but information only
|
||||
- // exists for instrumented browser processes.
|
||||
- user_stream_data_sources.push_back(
|
||||
- std::make_unique<browser_watcher::ActivityReportUserStreamDataSource>(
|
||||
- user_data_dir));
|
||||
- }
|
||||
|
||||
#if BUILDFLAG(ENABLE_GWP_ASAN)
|
||||
user_stream_data_sources.push_back(
|
||||
@@ -0,0 +1,381 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dale Curtis <dalecurtis@chromium.org>
|
||||
Date: Mon, 20 Feb 2023 13:16:32 +0000
|
||||
Subject: Further simplify WebMediaPlayerMSCompositor lifetime.
|
||||
|
||||
M108 merge issues:
|
||||
third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc:
|
||||
- video_task_runner_ is named io_task_runner_ in 108
|
||||
|
||||
third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc:
|
||||
- video_task_runner_ is named io_task_runner_ in 108 (conflict in ReplaceCurrentFrameWithACopy)
|
||||
|
||||
Due to the raw pointer held by VideoFrameSubmitter, there may be
|
||||
tasks pending on the compositor task runner after the RefCounted
|
||||
traits have "destructed" WebMediaPlayerMSCompositor. Through this
|
||||
raw pointer VFS was invoking OnContextLost which attempts to use
|
||||
the zero ref count compositor.
|
||||
|
||||
The solution here is again similar to VideoFrameCompositor, its
|
||||
destruction should be explicit instead of a tangle of RefCounted
|
||||
owners.
|
||||
|
||||
(cherry picked from commit 1622bffc6534a0cc4f53d07c43e0cd8f49975d10)
|
||||
|
||||
Fixed: 1407701, 1411601
|
||||
Change-Id: Ic77294d1113d54ab83bc0f5b625a997edf57bf7c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4210508
|
||||
Commit-Queue: Tony Herre <toprice@chromium.org>
|
||||
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1099726}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4225393
|
||||
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
|
||||
Reviewed-by: Oleh Lamzin <lamzin@google.com>
|
||||
Owners-Override: Oleh Lamzin <lamzin@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1392}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
|
||||
index f8c640d4f866afafa6fab82d67fe5f866810f828..955f867cc24152fa88dd6c20de006425a20b77c5 100644
|
||||
--- a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
|
||||
+++ b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
|
||||
@@ -211,6 +211,8 @@ class BLINK_MODULES_EXPORT WebMediaPlayerMS
|
||||
static const gfx::Size kUseGpuMemoryBufferVideoFramesMinResolution;
|
||||
#endif // BUILDFLAG(IS_WIN)
|
||||
|
||||
+ void ReplaceCurrentFrameWithACopy();
|
||||
+
|
||||
bool IsInPictureInPicture() const;
|
||||
|
||||
// Switch to SurfaceLayer, either initially or from VideoLayer.
|
||||
@@ -313,7 +315,7 @@ class BLINK_MODULES_EXPORT WebMediaPlayerMS
|
||||
// Used for DCHECKs to ensure methods calls executed in the correct thread.
|
||||
THREAD_CHECKER(thread_checker_);
|
||||
|
||||
- scoped_refptr<WebMediaPlayerMSCompositor> compositor_;
|
||||
+ std::unique_ptr<WebMediaPlayerMSCompositor> compositor_;
|
||||
|
||||
const WebString initial_audio_output_device_id_;
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
|
||||
index e4eb2b0053384d3e89545928c22bc2e1a12580fa..a85406d39037a8003eaffd1a91c8021ad38e0267 100644
|
||||
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
|
||||
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
|
||||
@@ -399,8 +399,9 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
|
||||
SendLogMessage(
|
||||
String::Format("%s() [delegate_id=%d]", __func__, delegate_id_));
|
||||
|
||||
- if (!web_stream_.IsNull())
|
||||
+ if (!web_stream_.IsNull()) {
|
||||
web_stream_.RemoveObserver(this);
|
||||
+ }
|
||||
|
||||
// Destruct compositor resources in the proper order.
|
||||
get_client()->SetCcLayer(nullptr);
|
||||
@@ -409,14 +410,35 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
|
||||
video_layer_->StopUsingProvider();
|
||||
}
|
||||
|
||||
- if (frame_deliverer_)
|
||||
- io_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release());
|
||||
+ if (frame_deliverer_) {
|
||||
+ io_task_runner_->DeleteSoon(FROM_HERE, std::move(frame_deliverer_));
|
||||
+ }
|
||||
|
||||
- if (video_frame_provider_)
|
||||
+ if (video_frame_provider_) {
|
||||
video_frame_provider_->Stop();
|
||||
+ }
|
||||
|
||||
- if (audio_renderer_)
|
||||
+ // This must be destroyed before `compositor_` since it will grab a couple of
|
||||
+ // final metrics during destruction.
|
||||
+ watch_time_reporter_.reset();
|
||||
+
|
||||
+ if (compositor_) {
|
||||
+ // `compositor_` receives frames on `io_task_runner_` from
|
||||
+ // `frame_deliverer_` and operates on the `compositor_task_runner_`, so
|
||||
+ // must trampoline through both to ensure a safe destruction.
|
||||
+ PostCrossThreadTask(
|
||||
+ *io_task_runner_, FROM_HERE,
|
||||
+ WTF::CrossThreadBindOnce(
|
||||
+ [](scoped_refptr<base::SingleThreadTaskRunner> task_runner,
|
||||
+ std::unique_ptr<WebMediaPlayerMSCompositor> compositor) {
|
||||
+ task_runner->DeleteSoon(FROM_HERE, std::move(compositor));
|
||||
+ },
|
||||
+ compositor_task_runner_, std::move(compositor_)));
|
||||
+ }
|
||||
+
|
||||
+ if (audio_renderer_) {
|
||||
audio_renderer_->Stop();
|
||||
+ }
|
||||
|
||||
media_log_->AddEvent<media::MediaLogEvent::kWebMediaPlayerDestroyed>();
|
||||
|
||||
@@ -457,7 +479,7 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
|
||||
|
||||
watch_time_reporter_.reset();
|
||||
|
||||
- compositor_ = base::MakeRefCounted<WebMediaPlayerMSCompositor>(
|
||||
+ compositor_ = std::make_unique<WebMediaPlayerMSCompositor>(
|
||||
compositor_task_runner_, io_task_runner_, web_stream_,
|
||||
std::move(submitter_), use_surface_layer_, weak_this_);
|
||||
|
||||
@@ -480,7 +502,7 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
|
||||
frame_deliverer_ = std::make_unique<WebMediaPlayerMS::FrameDeliverer>(
|
||||
weak_this_,
|
||||
CrossThreadBindRepeating(&WebMediaPlayerMSCompositor::EnqueueFrame,
|
||||
- compositor_),
|
||||
+ CrossThreadUnretained(compositor_.get())),
|
||||
media_task_runner_, worker_task_runner_, gpu_factories_);
|
||||
video_frame_provider_ = renderer_factory_->GetVideoRenderer(
|
||||
web_stream_,
|
||||
@@ -826,7 +848,19 @@ void WebMediaPlayerMS::Pause() {
|
||||
video_frame_provider_->Pause();
|
||||
|
||||
compositor_->StopRendering();
|
||||
- compositor_->ReplaceCurrentFrameWithACopy();
|
||||
+
|
||||
+ // Bounce this call off of video task runner to since there might still be
|
||||
+ // frames passed on video task runner.
|
||||
+ PostCrossThreadTask(
|
||||
+ *io_task_runner_, FROM_HERE,
|
||||
+ WTF::CrossThreadBindOnce(
|
||||
+ [](scoped_refptr<base::SingleThreadTaskRunner> task_runner,
|
||||
+ WTF::CrossThreadOnceClosure copy_cb) {
|
||||
+ PostCrossThreadTask(*task_runner, FROM_HERE, std::move(copy_cb));
|
||||
+ },
|
||||
+ main_render_task_runner_,
|
||||
+ WTF::CrossThreadBindOnce(
|
||||
+ &WebMediaPlayerMS::ReplaceCurrentFrameWithACopy, weak_this_)));
|
||||
|
||||
if (audio_renderer_)
|
||||
audio_renderer_->Pause();
|
||||
@@ -841,6 +875,11 @@ void WebMediaPlayerMS::Pause() {
|
||||
paused_ = true;
|
||||
}
|
||||
|
||||
+void WebMediaPlayerMS::ReplaceCurrentFrameWithACopy() {
|
||||
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
+ compositor_->ReplaceCurrentFrameWithACopy();
|
||||
+}
|
||||
+
|
||||
void WebMediaPlayerMS::Seek(double seconds) {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
}
|
||||
@@ -1192,7 +1231,8 @@ void WebMediaPlayerMS::ActivateSurfaceLayerForVideo(
|
||||
PostCrossThreadTask(
|
||||
*compositor_task_runner_, FROM_HERE,
|
||||
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::EnableSubmission,
|
||||
- compositor_, bridge_->GetSurfaceId(), video_transform,
|
||||
+ CrossThreadUnretained(compositor_.get()),
|
||||
+ bridge_->GetSurfaceId(), video_transform,
|
||||
IsInPictureInPicture()));
|
||||
|
||||
// If the element is already in Picture-in-Picture mode, it means that it
|
||||
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
|
||||
index acbdf1c64f0efed4c665de270d712bf446eb2106..67f0c200d85073ecd677e467bc1d624b1817dde0 100644
|
||||
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
|
||||
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
|
||||
@@ -197,18 +197,18 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
|
||||
dropped_frame_count_(0),
|
||||
stopped_(true),
|
||||
render_started_(!stopped_) {
|
||||
+ weak_this_ = weak_ptr_factory_.GetWeakPtr();
|
||||
if (use_surface_layer) {
|
||||
submitter_ = std::move(submitter);
|
||||
|
||||
PostCrossThreadTask(
|
||||
*video_frame_compositor_task_runner_, FROM_HERE,
|
||||
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::InitializeSubmitter,
|
||||
- weak_ptr_factory_.GetWeakPtr()));
|
||||
+ weak_this_));
|
||||
update_submission_state_callback_ = base::BindPostTask(
|
||||
video_frame_compositor_task_runner_,
|
||||
ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
|
||||
- &WebMediaPlayerMSCompositor::SetIsSurfaceVisible,
|
||||
- weak_ptr_factory_.GetWeakPtr())));
|
||||
+ &WebMediaPlayerMSCompositor::SetIsSurfaceVisible, weak_this_)));
|
||||
}
|
||||
|
||||
HeapVector<Member<MediaStreamComponent>> video_components;
|
||||
@@ -236,27 +236,12 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
|
||||
}
|
||||
|
||||
WebMediaPlayerMSCompositor::~WebMediaPlayerMSCompositor() {
|
||||
- // Ensured by destructor traits.
|
||||
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
|
||||
if (video_frame_provider_client_) {
|
||||
video_frame_provider_client_->StopUsingProvider();
|
||||
}
|
||||
}
|
||||
|
||||
-// static
|
||||
-void WebMediaPlayerMSCompositorTraits::Destruct(
|
||||
- const WebMediaPlayerMSCompositor* compositor) {
|
||||
- if (!compositor->video_frame_compositor_task_runner_
|
||||
- ->BelongsToCurrentThread()) {
|
||||
- PostCrossThreadTask(
|
||||
- *compositor->video_frame_compositor_task_runner_, FROM_HERE,
|
||||
- CrossThreadBindOnce(&WebMediaPlayerMSCompositorTraits::Destruct,
|
||||
- CrossThreadUnretained(compositor)));
|
||||
- return;
|
||||
- }
|
||||
- delete compositor;
|
||||
-}
|
||||
-
|
||||
void WebMediaPlayerMSCompositor::InitializeSubmitter() {
|
||||
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
|
||||
submitter_->Initialize(this, /*is_media_stream=*/true);
|
||||
@@ -302,7 +287,7 @@ void WebMediaPlayerMSCompositor::SetForceBeginFrames(bool enable) {
|
||||
PostCrossThreadTask(
|
||||
*video_frame_compositor_task_runner_, FROM_HERE,
|
||||
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::SetForceBeginFrames,
|
||||
- weak_ptr_factory_.GetWeakPtr(), enable));
|
||||
+ weak_this_, enable));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -604,7 +589,7 @@ void WebMediaPlayerMSCompositor::StartRendering() {
|
||||
PostCrossThreadTask(
|
||||
*video_frame_compositor_task_runner_, FROM_HERE,
|
||||
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::StartRenderingInternal,
|
||||
- WrapRefCounted(this)));
|
||||
+ weak_this_));
|
||||
}
|
||||
|
||||
void WebMediaPlayerMSCompositor::StopRendering() {
|
||||
@@ -612,18 +597,7 @@ void WebMediaPlayerMSCompositor::StopRendering() {
|
||||
PostCrossThreadTask(
|
||||
*video_frame_compositor_task_runner_, FROM_HERE,
|
||||
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::StopRenderingInternal,
|
||||
- WrapRefCounted(this)));
|
||||
-}
|
||||
-
|
||||
-void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() {
|
||||
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
- // Bounce this call off of IO thread to since there might still be frames
|
||||
- // passed on IO thread.
|
||||
- io_task_runner_->PostTask(
|
||||
- FROM_HERE,
|
||||
- media::BindToCurrentLoop(WTF::BindOnce(
|
||||
- &WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal,
|
||||
- WrapRefCounted(this))));
|
||||
+ weak_this_));
|
||||
}
|
||||
|
||||
bool WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks(
|
||||
@@ -690,7 +664,7 @@ void WebMediaPlayerMSCompositor::RenderWithoutAlgorithm(
|
||||
*video_frame_compositor_task_runner_, FROM_HERE,
|
||||
CrossThreadBindOnce(
|
||||
&WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor,
|
||||
- WrapRefCounted(this), std::move(frame), is_copy));
|
||||
+ weak_this_, std::move(frame), is_copy));
|
||||
}
|
||||
|
||||
void WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor(
|
||||
@@ -790,9 +764,8 @@ void WebMediaPlayerMSCompositor::SetCurrentFrame(
|
||||
PostCrossThreadTask(
|
||||
*video_frame_compositor_task_runner_, FROM_HERE,
|
||||
CrossThreadBindOnce(&WebMediaPlayerMSCompositor::CheckForFrameChanges,
|
||||
- WrapRefCounted(this), is_first_frame,
|
||||
- has_frame_size_changed, std::move(new_transform),
|
||||
- std::move(new_opacity)));
|
||||
+ weak_this_, is_first_frame, has_frame_size_changed,
|
||||
+ std::move(new_transform), std::move(new_opacity)));
|
||||
}
|
||||
|
||||
void WebMediaPlayerMSCompositor::CheckForFrameChanges(
|
||||
@@ -859,7 +832,7 @@ void WebMediaPlayerMSCompositor::StopRenderingInternal() {
|
||||
video_frame_provider_client_->StopRendering();
|
||||
}
|
||||
|
||||
-void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal() {
|
||||
+void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
scoped_refptr<media::VideoFrame> current_frame_ref;
|
||||
{
|
||||
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
|
||||
index ffeb448be295223f1f997b47eddff37d04bc8f16..197a0f0d02e84378f7f697213aa613e73c9f79f7 100644
|
||||
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
|
||||
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "third_party/blink/renderer/modules/mediastream/video_renderer_algorithm_wrapper.h"
|
||||
#include "third_party/blink/renderer/modules/modules_export.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
|
||||
-#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
|
||||
|
||||
namespace base {
|
||||
class SingleThreadTaskRunner;
|
||||
@@ -46,7 +45,6 @@ class SurfaceId;
|
||||
namespace blink {
|
||||
class MediaStreamDescriptor;
|
||||
class WebMediaPlayerMS;
|
||||
-struct WebMediaPlayerMSCompositorTraits;
|
||||
|
||||
// This class is designed to handle the work load on compositor thread for
|
||||
// WebMediaPlayerMS. It will be instantiated on the main thread, but destroyed
|
||||
@@ -58,9 +56,7 @@ struct WebMediaPlayerMSCompositorTraits;
|
||||
// Otherwise, WebMediaPlayerMSCompositor will simply store the most recent
|
||||
// frame, and submit it whenever asked by the compositor.
|
||||
class MODULES_EXPORT WebMediaPlayerMSCompositor
|
||||
- : public cc::VideoFrameProvider,
|
||||
- public WTF::ThreadSafeRefCounted<WebMediaPlayerMSCompositor,
|
||||
- WebMediaPlayerMSCompositorTraits> {
|
||||
+ : public cc::VideoFrameProvider {
|
||||
public:
|
||||
using OnNewFramePresentedCB = base::OnceClosure;
|
||||
|
||||
@@ -76,6 +72,7 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
|
||||
std::unique_ptr<WebVideoFrameSubmitter> submitter,
|
||||
bool use_surface_layer,
|
||||
const base::WeakPtr<WebMediaPlayerMS>& player);
|
||||
+ ~WebMediaPlayerMSCompositor() override;
|
||||
|
||||
WebMediaPlayerMSCompositor(const WebMediaPlayerMSCompositor&) = delete;
|
||||
WebMediaPlayerMSCompositor& operator=(const WebMediaPlayerMSCompositor&) =
|
||||
@@ -143,10 +140,7 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
|
||||
Metadata GetMetadata();
|
||||
|
||||
private:
|
||||
- friend class WTF::ThreadSafeRefCounted<WebMediaPlayerMSCompositor,
|
||||
- WebMediaPlayerMSCompositorTraits>;
|
||||
friend class WebMediaPlayerMSTest;
|
||||
- friend struct WebMediaPlayerMSCompositorTraits;
|
||||
|
||||
// Struct used to keep information about frames pending in
|
||||
// |rendering_frame_buffer_|.
|
||||
@@ -157,8 +151,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
|
||||
bool is_copy;
|
||||
};
|
||||
|
||||
- ~WebMediaPlayerMSCompositor() override;
|
||||
-
|
||||
// Ran on the |video_frame_compositor_task_runner_| to initialize
|
||||
// |submitter_|
|
||||
void InitializeSubmitter();
|
||||
@@ -204,7 +196,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
|
||||
|
||||
void StartRenderingInternal();
|
||||
void StopRenderingInternal();
|
||||
- void ReplaceCurrentFrameWithACopyInternal();
|
||||
|
||||
void SetAlgorithmEnabledForTesting(bool algorithm_enabled);
|
||||
void RecordFrameDisplayedStats(base::TimeTicks frame_displayed_time);
|
||||
@@ -314,15 +305,10 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
|
||||
// |dropped_frame_count_|, |current_metadata_| and |render_started_|.
|
||||
base::Lock current_frame_lock_;
|
||||
|
||||
+ base::WeakPtr<WebMediaPlayerMSCompositor> weak_this_;
|
||||
base::WeakPtrFactory<WebMediaPlayerMSCompositor> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
-struct WebMediaPlayerMSCompositorTraits {
|
||||
- // Ensure destruction occurs on main thread so that "Web" and other resources
|
||||
- // are destroyed on the correct thread.
|
||||
- static void Destruct(const WebMediaPlayerMSCompositor* player);
|
||||
-};
|
||||
-
|
||||
} // namespace blink
|
||||
|
||||
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_WEBMEDIAPLAYER_MS_COMPOSITOR_H_
|
||||
@@ -0,0 +1,64 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Will Harris <wfh@chromium.org>
|
||||
Date: Thu, 2 Mar 2023 17:21:30 +0000
|
||||
Subject: Prevent potential integer overflow in PersistentMemoryAllocator (2/2)
|
||||
|
||||
https://crrev.com/c/4250177 added an extra check for potential
|
||||
integer overflow in GetAllocSize but forgot to add the same
|
||||
check in GetBlock.
|
||||
|
||||
This meant that it was possible to get a pointer to a block
|
||||
but calling GetAllocSize on the same block would return zero.
|
||||
|
||||
This change makes the two functions consistent with each other
|
||||
so calling GetBlock on invalid data will return nullptr.
|
||||
|
||||
BUG=1417317,1415328
|
||||
|
||||
(cherry picked from commit 81be8e8f2e13a9f1fe6d3150205a3c13af1db6e9)
|
||||
|
||||
Change-Id: I8eb3d91bae4528fc97517d202baf337536a4c81f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4264177
|
||||
Commit-Queue: Alexei Svitkine <asvitkine@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1107105}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4280124
|
||||
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Zakhar Voit <voit@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1402}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/base/metrics/persistent_memory_allocator.cc b/base/metrics/persistent_memory_allocator.cc
|
||||
index b7edfc04c307662450f3a39c20142c3593fbacde..85b5290d8955240f8044054a280105e3f8362714 100644
|
||||
--- a/base/metrics/persistent_memory_allocator.cc
|
||||
+++ b/base/metrics/persistent_memory_allocator.cc
|
||||
@@ -884,8 +884,13 @@ PersistentMemoryAllocator::GetBlock(Reference ref,
|
||||
if (ref % kAllocAlignment != 0)
|
||||
return nullptr;
|
||||
size += sizeof(BlockHeader);
|
||||
- if (ref + size > mem_size_)
|
||||
+ uint32_t total_size;
|
||||
+ if (!base::CheckAdd(ref, size).AssignIfValid(&total_size)) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ if (total_size > mem_size_) {
|
||||
return nullptr;
|
||||
+ }
|
||||
|
||||
// Validation of referenced block-header.
|
||||
if (!free_ok) {
|
||||
@@ -895,8 +900,13 @@ PersistentMemoryAllocator::GetBlock(Reference ref,
|
||||
return nullptr;
|
||||
if (block->size < size)
|
||||
return nullptr;
|
||||
- if (ref + block->size > mem_size_)
|
||||
+ uint32_t block_size;
|
||||
+ if (!base::CheckAdd(ref, block->size).AssignIfValid(&block_size)) {
|
||||
return nullptr;
|
||||
+ }
|
||||
+ if (block_size > mem_size_) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
if (type_id != 0 &&
|
||||
block->type_id.load(std::memory_order_relaxed) != type_id) {
|
||||
return nullptr;
|
||||
@@ -0,0 +1,142 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Rakina Zata Amni <rakina@chromium.org>
|
||||
Date: Tue, 30 May 2023 16:24:26 +0000
|
||||
Subject: Return after ReadyCommitNavigation call in CommitErrorPage if it
|
||||
deletes NavigationRequest
|
||||
|
||||
M108 merge issue:
|
||||
content/browser/renderer_host/navigation_request.cc:
|
||||
topics_eligible_ isn't present in M108
|
||||
|
||||
NavigationRequest::ReadyToCommitNavigation() can cause deletion of the
|
||||
NavigationRequest, so callers should check for that possibility after
|
||||
calling the function. A caller in CommitErrorPage is missing that
|
||||
check, which this CL adds, along with a regression test.
|
||||
|
||||
(cherry picked from commit 42db806805ef2be64ee92803d3a784631b2a7df0)
|
||||
|
||||
Bug: 1444360
|
||||
Change-Id: I3964da4909a6709b7730d25d6497b19c098f4f21
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4520493
|
||||
Commit-Queue: Charlie Reis <creis@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1143298}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4567848
|
||||
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
|
||||
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1460}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
|
||||
index f6f25544bd36fceb60ada013178cc8fb67e7b10a..ebc0a0c57fb78b3f0044979cca115c78f98f8c2d 100644
|
||||
--- a/content/browser/renderer_host/navigation_request.cc
|
||||
+++ b/content/browser/renderer_host/navigation_request.cc
|
||||
@@ -4913,7 +4913,13 @@ void NavigationRequest::CommitErrorPage(
|
||||
}
|
||||
}
|
||||
|
||||
+ base::WeakPtr<NavigationRequest> weak_self(weak_factory_.GetWeakPtr());
|
||||
ReadyToCommitNavigation(true /* is_error */);
|
||||
+ // The caller above might result in the deletion of `this`. Return immediately
|
||||
+ // if so.
|
||||
+ if (!weak_self) {
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
PopulateDocumentTokenForCrossDocumentNavigation();
|
||||
// Use a separate cache shard, and no cookies, for error pages.
|
||||
diff --git a/content/browser/renderer_host/navigation_request_browsertest.cc b/content/browser/renderer_host/navigation_request_browsertest.cc
|
||||
index 486a6871d9ff5256123c47accf9f714b67bc30fc..cc4f9acf9e5ec5f8c8dfa8a812a2cc6fb4505526 100644
|
||||
--- a/content/browser/renderer_host/navigation_request_browsertest.cc
|
||||
+++ b/content/browser/renderer_host/navigation_request_browsertest.cc
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "content/public/test/prerender_test_util.h"
|
||||
#include "content/public/test/test_frame_navigation_observer.h"
|
||||
#include "content/public/test/test_navigation_observer.h"
|
||||
+#include "content/public/test/test_service.mojom.h"
|
||||
#include "content/public/test/test_utils.h"
|
||||
#include "content/public/test/url_loader_interceptor.h"
|
||||
#include "content/shell/browser/shell.h"
|
||||
@@ -3850,4 +3851,83 @@ IN_PROC_BROWSER_TEST_P(NavigationRequestMPArchBrowserTest,
|
||||
}
|
||||
}
|
||||
|
||||
+// Tests that when trying to commit an error page for a failed navigation, but
|
||||
+// the renderer process of the, the navigation won't commit and won't crash.
|
||||
+// Regression test for https://crbug.com/1444360.
|
||||
+IN_PROC_BROWSER_TEST_F(NavigationRequestBrowserTest,
|
||||
+ RendererCrashedBeforeCommitErrorPage) {
|
||||
+ // Navigate to `url_a` first.
|
||||
+ GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
|
||||
+ ASSERT_TRUE(NavigateToURL(shell(), url_a));
|
||||
+
|
||||
+ // Set up an URLLoaderInterceptor which will cause future navigations to fail.
|
||||
+ auto url_loader_interceptor = std::make_unique<URLLoaderInterceptor>(
|
||||
+ base::BindRepeating([](URLLoaderInterceptor::RequestParams* params) {
|
||||
+ network::URLLoaderCompletionStatus status;
|
||||
+ status.error_code = net::ERR_NOT_IMPLEMENTED;
|
||||
+ params->client->OnComplete(status);
|
||||
+ return true;
|
||||
+ }));
|
||||
+
|
||||
+ // Do a navigation to `url_b1` that will fail and commit an error page. This
|
||||
+ // is important so that the next error page navigation won't need to create a
|
||||
+ // speculative RenderFrameHost (unless RenderDocument is enabled) and won't
|
||||
+ // get cancelled earlier than commit time due to speculative RFH deletion.
|
||||
+ GURL url_b1(embedded_test_server()->GetURL("b.com", "/title1.html"));
|
||||
+ EXPECT_FALSE(NavigateToURL(shell(), url_b1));
|
||||
+ EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), url_b1);
|
||||
+ EXPECT_TRUE(
|
||||
+ shell()->web_contents()->GetPrimaryMainFrame()->IsErrorDocument());
|
||||
+
|
||||
+ // For the next navigation, set up a throttle that will be used to wait for
|
||||
+ // WillFailRequest() and then defer the navigation, so that we can crash the
|
||||
+ // error page process first.
|
||||
+ TestNavigationThrottleInstaller installer(
|
||||
+ shell()->web_contents(),
|
||||
+ NavigationThrottle::PROCEED /* will_start_result */,
|
||||
+ NavigationThrottle::PROCEED /* will_redirect_result */,
|
||||
+ NavigationThrottle::DEFER /* will_fail_result */,
|
||||
+ NavigationThrottle::PROCEED /* will_process_result */);
|
||||
+
|
||||
+ // Start a navigation to `url_b2` that will also fail, but before it commits
|
||||
+ // an error page, cause the error page process to crash.
|
||||
+ GURL url_b2(embedded_test_server()->GetURL("b.com", "/title2.html"));
|
||||
+ TestNavigationManager manager(shell()->web_contents(), url_b2);
|
||||
+ shell()->LoadURL(url_b2);
|
||||
+ EXPECT_TRUE(manager.WaitForRequestStart());
|
||||
+
|
||||
+ // Resume the navigation and wait for WillFailRequest(). After this point, we
|
||||
+ // will have picked the final RenderFrameHost & RenderProcessHost for the
|
||||
+ // failed navigation.
|
||||
+ manager.ResumeNavigation();
|
||||
+ installer.WaitForThrottleWillFail();
|
||||
+
|
||||
+ // Kill the error page process. This will cause for the navigation to `url_b2`
|
||||
+ // to return early in `NavigationRequest::ReadyToCommitNavigation()` and not
|
||||
+ // commit a new error page.
|
||||
+ RenderProcessHost* process_to_kill =
|
||||
+ manager.GetNavigationHandle()->GetRenderFrameHost()->GetProcess();
|
||||
+ ASSERT_TRUE(process_to_kill->IsInitializedAndNotDead());
|
||||
+ {
|
||||
+ // Trigger a renderer kill by calling DoSomething() which will cause a bad
|
||||
+ // message to be reported.
|
||||
+ RenderProcessHostBadIpcMessageWaiter kill_waiter(process_to_kill);
|
||||
+ mojo::Remote<mojom::TestService> service;
|
||||
+ process_to_kill->BindReceiver(service.BindNewPipeAndPassReceiver());
|
||||
+ service->DoSomething(base::DoNothing());
|
||||
+ EXPECT_EQ(bad_message::RPH_MOJO_PROCESS_ERROR, kill_waiter.Wait());
|
||||
+ }
|
||||
+ ASSERT_FALSE(process_to_kill->IsInitializedAndNotDead());
|
||||
+
|
||||
+ // Resume the navigation, which won't commit.
|
||||
+ if (!ShouldCreateNewHostForAllFrames()) {
|
||||
+ installer.navigation_throttle()->ResumeNavigation();
|
||||
+ }
|
||||
+ manager.WaitForNavigationFinished();
|
||||
+ EXPECT_FALSE(WaitForLoadStop(shell()->web_contents()));
|
||||
+
|
||||
+ // The tab stayed at `url_b1` as the `url_b2` navigation didn't commit.
|
||||
+ EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), url_b1);
|
||||
+}
|
||||
+
|
||||
} // namespace content
|
||||
@@ -0,0 +1,124 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dale Curtis <dalecurtis@chromium.org>
|
||||
Date: Mon, 20 Feb 2023 10:08:49 +0000
|
||||
Subject: Simplify WebMediaPlayerMSCompositor destruction.
|
||||
|
||||
The code was only sometimes calling StopUsingProvider() and posted
|
||||
the submitter destruction unnecessarily.
|
||||
|
||||
Destruction now works the same as in VideoFrameCompositor, where the
|
||||
class itself is responsible for calling StopUsingProvider() during
|
||||
its own destruction.
|
||||
|
||||
(cherry picked from commit cbd238e85903b7d94910bd2c6362ff9abf9908cc)
|
||||
|
||||
Fixed: 1407701
|
||||
Disallow-Recycled-Builds: test-failures
|
||||
Change-Id: Ia649cb5532519468eea34e12745ed9c990580d82
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4195824
|
||||
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
|
||||
Commit-Queue: Tony Herre <toprice@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1098505}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4225498
|
||||
Reviewed-by: Oleh Lamzin <lamzin@google.com>
|
||||
Owners-Override: Oleh Lamzin <lamzin@google.com>
|
||||
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1391}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
|
||||
index 01b3e059e339341995deb9c27e248ab272acd1b2..e4eb2b0053384d3e89545928c22bc2e1a12580fa 100644
|
||||
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
|
||||
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
|
||||
@@ -412,9 +412,6 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
|
||||
if (frame_deliverer_)
|
||||
io_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release());
|
||||
|
||||
- if (compositor_)
|
||||
- compositor_->StopUsingProvider();
|
||||
-
|
||||
if (video_frame_provider_)
|
||||
video_frame_provider_->Stop();
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
|
||||
index 63957929facc933c23eef3fc200f140b73cb3f50..acbdf1c64f0efed4c665de270d712bf446eb2106 100644
|
||||
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
|
||||
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
|
||||
@@ -238,13 +238,8 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
|
||||
WebMediaPlayerMSCompositor::~WebMediaPlayerMSCompositor() {
|
||||
// Ensured by destructor traits.
|
||||
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
|
||||
-
|
||||
- if (submitter_) {
|
||||
- video_frame_compositor_task_runner_->DeleteSoon(FROM_HERE,
|
||||
- std::move(submitter_));
|
||||
- } else {
|
||||
- DCHECK(!video_frame_provider_client_)
|
||||
- << "Must call StopUsingProvider() before dtor!";
|
||||
+ if (video_frame_provider_client_) {
|
||||
+ video_frame_provider_client_->StopUsingProvider();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +259,7 @@ void WebMediaPlayerMSCompositorTraits::Destruct(
|
||||
|
||||
void WebMediaPlayerMSCompositor::InitializeSubmitter() {
|
||||
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
|
||||
- submitter_->Initialize(this, /* is_media_stream = */ true);
|
||||
+ submitter_->Initialize(this, /*is_media_stream=*/true);
|
||||
}
|
||||
|
||||
void WebMediaPlayerMSCompositor::SetIsSurfaceVisible(
|
||||
@@ -631,15 +626,6 @@ void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() {
|
||||
WrapRefCounted(this))));
|
||||
}
|
||||
|
||||
-void WebMediaPlayerMSCompositor::StopUsingProvider() {
|
||||
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
- PostCrossThreadTask(
|
||||
- *video_frame_compositor_task_runner_, FROM_HERE,
|
||||
- CrossThreadBindOnce(
|
||||
- &WebMediaPlayerMSCompositor::StopUsingProviderInternal,
|
||||
- WrapRefCounted(this)));
|
||||
-}
|
||||
-
|
||||
bool WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks(
|
||||
const std::vector<base::TimeDelta>& timestamps,
|
||||
std::vector<base::TimeTicks>* wall_clock_times) {
|
||||
@@ -873,13 +859,6 @@ void WebMediaPlayerMSCompositor::StopRenderingInternal() {
|
||||
video_frame_provider_client_->StopRendering();
|
||||
}
|
||||
|
||||
-void WebMediaPlayerMSCompositor::StopUsingProviderInternal() {
|
||||
- DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
|
||||
- if (video_frame_provider_client_)
|
||||
- video_frame_provider_client_->StopUsingProvider();
|
||||
- video_frame_provider_client_ = nullptr;
|
||||
-}
|
||||
-
|
||||
void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal() {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
scoped_refptr<media::VideoFrame> current_frame_ref;
|
||||
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
|
||||
index a82497399be7588298f4c740ef67e18ee429967d..ffeb448be295223f1f997b47eddff37d04bc8f16 100644
|
||||
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
|
||||
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h
|
||||
@@ -119,10 +119,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
|
||||
void StopRendering();
|
||||
void ReplaceCurrentFrameWithACopy();
|
||||
|
||||
- // Tell |video_frame_provider_client_| to stop using this instance in
|
||||
- // preparation for dtor.
|
||||
- void StopUsingProvider();
|
||||
-
|
||||
// Sets a hook to be notified when a new frame is presented, to fulfill a
|
||||
// prending video.requestAnimationFrame() request.
|
||||
// Can be called from any thread.
|
||||
@@ -208,7 +204,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
|
||||
|
||||
void StartRenderingInternal();
|
||||
void StopRenderingInternal();
|
||||
- void StopUsingProviderInternal();
|
||||
void ReplaceCurrentFrameWithACopyInternal();
|
||||
|
||||
void SetAlgorithmEnabledForTesting(bool algorithm_enabled);
|
||||
47
patches/chromium/m112_cherry_pick_libxml_cve_fix.patch
Normal file
47
patches/chromium/m112_cherry_pick_libxml_cve_fix.patch
Normal file
@@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joey Arhar <jarhar@chromium.org>
|
||||
Date: Fri, 21 Apr 2023 20:53:40 +0000
|
||||
Subject: M112: Cherry pick libxml CVE fix
|
||||
|
||||
This patch cherry-picks a fix for [CVE-2023-29469] from libxml:
|
||||
https://gitlab.gnome.org/GNOME/libxml2/-/commit/547edbf1cbdccd46b2e8ff322a456eaa5931c5df
|
||||
|
||||
I cherry-picked these by going into my libxml checkout, checking out the
|
||||
commit that libxml is at for this M112 branch, cherry-picking the CVE
|
||||
fixes, then running the roll script on all platforms.
|
||||
|
||||
Bug: 1433328
|
||||
Change-Id: Iaee58b0890f7190386cca3e430286f39ccbbdb02
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4456592
|
||||
Commit-Queue: David Baron <dbaron@chromium.org>
|
||||
Reviewed-by: David Baron <dbaron@chromium.org>
|
||||
Commit-Queue: Joey Arhar <jarhar@chromium.org>
|
||||
Auto-Submit: Joey Arhar <jarhar@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5615@{#1325}
|
||||
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
|
||||
|
||||
diff --git a/third_party/libxml/README.chromium b/third_party/libxml/README.chromium
|
||||
index 9813d7cd51b62164cd9cad86b57a0b660d22a223..182f0a73439a5e549aed0fa01b22bdca94a8ccbc 100644
|
||||
--- a/third_party/libxml/README.chromium
|
||||
+++ b/third_party/libxml/README.chromium
|
||||
@@ -25,5 +25,6 @@ Modifications:
|
||||
in chromium's copy of maldoca. See https://github.com/google/maldoca/issues/87
|
||||
- Add helper classes in the chromium/ subdirectory.
|
||||
- Delete various unused files, see chromium/roll.py
|
||||
+- Cherry picked fix for CVE-2023-29469
|
||||
|
||||
This import was generated by the chromium/roll.py script.
|
||||
diff --git a/third_party/libxml/src/dict.c b/third_party/libxml/src/dict.c
|
||||
index 5c9ca71940ceea9f4aec9f1e7dfb6c3ba6bd8c76..300df7a55638f4c6728a88c336b3c3197ab05676 100644
|
||||
--- a/third_party/libxml/src/dict.c
|
||||
+++ b/third_party/libxml/src/dict.c
|
||||
@@ -455,7 +455,8 @@ static unsigned long
|
||||
xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
|
||||
unsigned long value = seed;
|
||||
|
||||
- if (name == NULL) return(0);
|
||||
+ if ((name == NULL) || (namelen <= 0))
|
||||
+ return(value);
|
||||
value += *name;
|
||||
value <<= 5;
|
||||
if (namelen > 10) {
|
||||
43
patches/chromium/m112_fix_scopedobservation_uaf_in.patch
Normal file
43
patches/chromium/m112_fix_scopedobservation_uaf_in.patch
Normal file
@@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Keren Zhu <kerenzhu@chromium.org>
|
||||
Date: Mon, 24 Apr 2023 15:36:21 +0000
|
||||
Subject: Fix ScopedObservation UaF in
|
||||
BubbleDialogDelegate::AnchorWidgetObserver
|
||||
|
||||
A ScopedObservation can outlive the aura::Window it observes, leading to
|
||||
a use-after-free error in ~ScopedObservation(). The problem occurs in
|
||||
BubbleDialogDelegate::AnchorWidgetObserver. This fix listens for
|
||||
OnWindowDestroying() and resets the observation to prevent the UaF.
|
||||
|
||||
(cherry picked from commit 72bd6a1018548ee63a2ec06d6c7714d3a8cdf8a8)
|
||||
|
||||
Bug: 1423360
|
||||
Change-Id: I742b4624b2664dea3fd97db7b399fcd15e45c8fe
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4455016
|
||||
Code-Coverage: Findit <findit-for-me@appspot.gserviceaccount.com>
|
||||
Reviewed-by: Elly Fong-Jones <ellyjones@chromium.org>
|
||||
Commit-Queue: Keren Zhu <kerenzhu@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1133511}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4466947
|
||||
Reviewed-by: Allen Bauer <kylixrd@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5615@{#1353}
|
||||
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
|
||||
|
||||
diff --git a/ui/views/bubble/bubble_dialog_delegate_view.cc b/ui/views/bubble/bubble_dialog_delegate_view.cc
|
||||
index 2a84e8f5a7078e76dd40208c0265df3db06a7621..ad7f33ebcb5a09dc5ca97ddbcd5b8bc21a9fb529 100644
|
||||
--- a/ui/views/bubble/bubble_dialog_delegate_view.cc
|
||||
+++ b/ui/views/bubble/bubble_dialog_delegate_view.cc
|
||||
@@ -318,6 +318,13 @@ class BubbleDialogDelegate::AnchorWidgetObserver : public WidgetObserver,
|
||||
owner_->OnAnchorBoundsChanged();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // If the native window is closed by the OS, OnWidgetDestroying() won't
|
||||
+ // fire. Instead, OnWindowDestroying() will fire before aura::Window
|
||||
+ // destruction. See //docs/ui/views/widget_destruction.md.
|
||||
+ void OnWindowDestroying(aura::Window* window) override {
|
||||
+ window_observation_.Reset();
|
||||
+ }
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -0,0 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Maggie Chen <magchen@chromium.org>
|
||||
Date: Thu, 18 May 2023 00:20:34 +0000
|
||||
Subject: Fix a crash caused by calling TRACE_EVENT
|
||||
|
||||
Now use literal constant for TRACE_EVENT. Passing a pointer instead of
|
||||
string content to TRACE_EVENT causes a crash in ScopedTracer.
|
||||
|
||||
(cherry picked from commit 6f2e587807aff2306309025db1c15fc59290eb6f)
|
||||
|
||||
Bug: 1444195
|
||||
Change-Id: I02aa1148d61e7596e9293ffc866135e99991e42e
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4522164
|
||||
Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org>
|
||||
Commit-Queue: Maggie Chen <magchen@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1144352}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4544885
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5735@{#749}
|
||||
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
|
||||
|
||||
diff --git a/ui/gl/swap_chain_presenter.cc b/ui/gl/swap_chain_presenter.cc
|
||||
index 31deec1168cd438c0a37edc9230484ba2181b525..5cf91faf97a2a6f4f130d9e62678d972f55756ec 100644
|
||||
--- a/ui/gl/swap_chain_presenter.cc
|
||||
+++ b/ui/gl/swap_chain_presenter.cc
|
||||
@@ -1635,10 +1635,8 @@ bool SwapChainPresenter::ReallocateSwapChain(
|
||||
}
|
||||
}
|
||||
if (!use_yuv_swap_chain) {
|
||||
- std::ostringstream trace_event_stream;
|
||||
- trace_event_stream << "SwapChainPresenter::ReallocateSwapChain::"
|
||||
- << DxgiFormatToString(swap_chain_format);
|
||||
- TRACE_EVENT0("gpu", trace_event_stream.str().c_str());
|
||||
+ TRACE_EVENT1("gpu", "SwapChainPresenter::ReallocateSwapChain::BGRA",
|
||||
+ "format", DxgiFormatToString(swap_chain_format));
|
||||
|
||||
desc.Format = swap_chain_format;
|
||||
desc.Flags = DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO;
|
||||
@@ -0,0 +1,99 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Eugene Zemtsov <eugene@chromium.org>
|
||||
Date: Wed, 21 Jun 2023 17:57:52 +0000
|
||||
Subject: webcodecs: Fix crash when changing temporal layer count in AV1
|
||||
encoder
|
||||
|
||||
(cherry picked from commit f312efac1b90117729e8961b58c643fc0eae1fbd)
|
||||
|
||||
Bug: 1447568
|
||||
Change-Id: I4ecb02ed956707571573a65ade17fdffe676b502
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4554300
|
||||
Auto-Submit: Eugene Zemtsov <eugene@chromium.org>
|
||||
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
|
||||
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1148041}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4610718
|
||||
Cr-Commit-Position: refs/branch-heads/5735@{#1360}
|
||||
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
|
||||
|
||||
diff --git a/media/video/av1_video_encoder.cc b/media/video/av1_video_encoder.cc
|
||||
index 71e4fa09a650183c3cd2ef84520d9493f2655bba..266170a524bc8f4317bec941714fe0be9333de37 100644
|
||||
--- a/media/video/av1_video_encoder.cc
|
||||
+++ b/media/video/av1_video_encoder.cc
|
||||
@@ -118,6 +118,7 @@ EncoderStatus SetUpAomConfig(const VideoEncoder::Options& opts,
|
||||
svc_params = {};
|
||||
svc_params.framerate_factor[0] = 1;
|
||||
svc_params.number_spatial_layers = 1;
|
||||
+ svc_params.number_temporal_layers = 1;
|
||||
if (opts.scalability_mode.has_value()) {
|
||||
switch (opts.scalability_mode.value()) {
|
||||
case SVCScalabilityMode::kL1T2:
|
||||
diff --git a/media/video/software_video_encoder_test.cc b/media/video/software_video_encoder_test.cc
|
||||
index 318c743bddcf9bec3a994f125ea329d45f8c4376..7a27b9326a5df556b1a6bacdad71081d46bcc781 100644
|
||||
--- a/media/video/software_video_encoder_test.cc
|
||||
+++ b/media/video/software_video_encoder_test.cc
|
||||
@@ -602,6 +602,63 @@ TEST_P(SVCVideoEncoderTest, EncodeClipTemporalSvc) {
|
||||
}
|
||||
}
|
||||
|
||||
+TEST_P(SVCVideoEncoderTest, ChangeLayers) {
|
||||
+ VideoEncoder::Options options;
|
||||
+ options.frame_size = gfx::Size(640, 480);
|
||||
+ options.bitrate = Bitrate::ConstantBitrate(1000000u); // 1Mbps
|
||||
+ options.framerate = 25;
|
||||
+ options.scalability_mode = GetParam().scalability_mode;
|
||||
+ std::vector<scoped_refptr<VideoFrame>> frames_to_encode;
|
||||
+
|
||||
+ std::vector<VideoEncoderOutput> chunks;
|
||||
+ size_t total_frames_count = 80;
|
||||
+
|
||||
+ // Encoder all frames with 3 temporal layers and put all outputs in |chunks|
|
||||
+ auto frame_duration = base::Seconds(1.0 / options.framerate.value());
|
||||
+
|
||||
+ VideoEncoder::OutputCB encoder_output_cb = base::BindLambdaForTesting(
|
||||
+ [&](VideoEncoderOutput output,
|
||||
+ absl::optional<VideoEncoder::CodecDescription> desc) {
|
||||
+ chunks.push_back(std::move(output));
|
||||
+ });
|
||||
+
|
||||
+ encoder_->Initialize(profile_, options, /*info_cb=*/base::DoNothing(),
|
||||
+ std::move(encoder_output_cb),
|
||||
+ ValidatingStatusCB(/* quit_run_loop_on_call */ true));
|
||||
+ RunUntilQuit();
|
||||
+
|
||||
+ uint32_t color = 0x964050;
|
||||
+ for (auto frame_index = 0u; frame_index < total_frames_count; frame_index++) {
|
||||
+ auto timestamp = frame_index * frame_duration;
|
||||
+
|
||||
+ const bool reconfigure = (frame_index == total_frames_count / 2);
|
||||
+ if (reconfigure) {
|
||||
+ encoder_->Flush(ValidatingStatusCB(/* quit_run_loop_on_call */ true));
|
||||
+ RunUntilQuit();
|
||||
+
|
||||
+ // Ask encoder to change SVC mode, empty output callback
|
||||
+ // means the encoder should keep the old one.
|
||||
+ options.scalability_mode = SVCScalabilityMode::kL1T1;
|
||||
+ encoder_->ChangeOptions(
|
||||
+ options, VideoEncoder::OutputCB(),
|
||||
+ ValidatingStatusCB(/* quit_run_loop_on_call */ true));
|
||||
+ RunUntilQuit();
|
||||
+ }
|
||||
+
|
||||
+ auto frame =
|
||||
+ CreateFrame(options.frame_size, pixel_format_, timestamp, color);
|
||||
+ color = (color << 1) + frame_index;
|
||||
+ frames_to_encode.push_back(frame);
|
||||
+ encoder_->Encode(frame, VideoEncoder::EncodeOptions(false),
|
||||
+ ValidatingStatusCB(/* quit_run_loop_on_call */ true));
|
||||
+ RunUntilQuit();
|
||||
+ }
|
||||
+
|
||||
+ encoder_->Flush(ValidatingStatusCB(/* quit_run_loop_on_call */ true));
|
||||
+ RunUntilQuit();
|
||||
+ EXPECT_EQ(chunks.size(), total_frames_count);
|
||||
+}
|
||||
+
|
||||
TEST_P(H264VideoEncoderTest, ReconfigureWithResize) {
|
||||
VideoEncoder::Options options;
|
||||
gfx::Size size1(320, 200), size2(400, 240);
|
||||
@@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Date: Sat, 8 Apr 2023 04:16:50 +0000
|
||||
Subject: Check SpdyProxyClientSocket is alive after write callback
|
||||
|
||||
To ensure that we don't use any member field.
|
||||
|
||||
(cherry picked from commit b71541b22ca19d5c3a7c01fedffe521b26577b72)
|
||||
|
||||
Bug: 1428820
|
||||
Change-Id: Icf6677c652a47dc2fd2d01675e94cda031a015f2
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4394863
|
||||
Reviewed-by: Adam Rice <ricea@chromium.org>
|
||||
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1125634}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4410322
|
||||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Auto-Submit: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5615@{#1172}
|
||||
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
|
||||
|
||||
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc
|
||||
index 173fc5cdbb67958cc9ca43284ff989196b287a8e..d9b67febc27cc99e5b3383a372451345cec6daaa 100644
|
||||
--- a/net/spdy/spdy_proxy_client_socket.cc
|
||||
+++ b/net/spdy/spdy_proxy_client_socket.cc
|
||||
@@ -279,7 +279,14 @@ int SpdyProxyClientSocket::GetLocalAddress(IPEndPoint* address) const {
|
||||
|
||||
void SpdyProxyClientSocket::RunWriteCallback(int result) {
|
||||
CHECK(write_callback_);
|
||||
+
|
||||
+ base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr();
|
||||
std::move(write_callback_).Run(result);
|
||||
+ if (!weak_ptr) {
|
||||
+ // `this` was already destroyed while running `write_callback_`. Must
|
||||
+ // return immediately without touching any field member.
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
if (end_stream_state_ == EndStreamState::kEndStreamReceived) {
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
@@ -0,0 +1,94 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Date: Sat, 8 Apr 2023 01:56:25 +0000
|
||||
Subject: Remove the second WeakPtrFactory from SpdyProxyClientSocket
|
||||
|
||||
It was introduced [1] to work around an old issue that wouldn't happen
|
||||
any more since we store a write callback in the class. Instead of having
|
||||
the second WeakPtrFactory and moving the callback, we can just keep it
|
||||
until RunWriteCallback() is called.
|
||||
|
||||
This is a speculative fix for the linked bug.
|
||||
|
||||
[1] https://codereview.chromium.org/338583003/
|
||||
|
||||
(cherry picked from commit 01b25615896b911e21103dd381fafc1f85886d91)
|
||||
|
||||
Bug: 1428820
|
||||
Change-Id: I0b5af2675b68188e208c2ecd42293251b2722b28
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4393905
|
||||
Reviewed-by: Adam Rice <ricea@chromium.org>
|
||||
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1125216}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4410320
|
||||
Auto-Submit: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5615@{#1171}
|
||||
Cr-Branched-From: 9c6408ef696e83a9936b82bbead3d41c93c82ee4-refs/heads/main@{#1109224}
|
||||
|
||||
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc
|
||||
index 5984ecedb3a14274bc33efe20b407dd33bc8a410..173fc5cdbb67958cc9ca43284ff989196b287a8e 100644
|
||||
--- a/net/spdy/spdy_proxy_client_socket.cc
|
||||
+++ b/net/spdy/spdy_proxy_client_socket.cc
|
||||
@@ -123,7 +123,6 @@ void SpdyProxyClientSocket::Disconnect() {
|
||||
|
||||
write_buffer_len_ = 0;
|
||||
write_callback_.Reset();
|
||||
- write_callback_weak_factory_.InvalidateWeakPtrs();
|
||||
|
||||
next_state_ = STATE_DISCONNECTED;
|
||||
|
||||
@@ -278,9 +277,9 @@ int SpdyProxyClientSocket::GetLocalAddress(IPEndPoint* address) const {
|
||||
return spdy_stream_->GetLocalAddress(address);
|
||||
}
|
||||
|
||||
-void SpdyProxyClientSocket::RunWriteCallback(CompletionOnceCallback callback,
|
||||
- int result) const {
|
||||
- std::move(callback).Run(result);
|
||||
+void SpdyProxyClientSocket::RunWriteCallback(int result) {
|
||||
+ CHECK(write_callback_);
|
||||
+ std::move(write_callback_).Run(result);
|
||||
|
||||
if (end_stream_state_ == EndStreamState::kEndStreamReceived) {
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
@@ -517,8 +516,7 @@ void SpdyProxyClientSocket::OnDataSent() {
|
||||
// stream's write callback chain to unwind (see crbug.com/355511).
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, base::BindOnce(&SpdyProxyClientSocket::RunWriteCallback,
|
||||
- write_callback_weak_factory_.GetWeakPtr(),
|
||||
- std::move(write_callback_), rv));
|
||||
+ weak_factory_.GetWeakPtr(), rv));
|
||||
}
|
||||
|
||||
void SpdyProxyClientSocket::OnTrailers(const spdy::Http2HeaderBlock& trailers) {
|
||||
diff --git a/net/spdy/spdy_proxy_client_socket.h b/net/spdy/spdy_proxy_client_socket.h
|
||||
index cbb961a68c93b9485bd0bf1c5e31014bdc95a84e..98b9e74427f48399bbc53bfad5b45a8dc18ab84b 100644
|
||||
--- a/net/spdy/spdy_proxy_client_socket.h
|
||||
+++ b/net/spdy/spdy_proxy_client_socket.h
|
||||
@@ -121,9 +121,9 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
|
||||
STATE_CLOSED
|
||||
};
|
||||
|
||||
- // Calls |callback.Run(result)|. Used to run a callback posted to the
|
||||
+ // Calls `write_callback_(result)`. Used to run a callback posted to the
|
||||
// message loop.
|
||||
- void RunWriteCallback(CompletionOnceCallback callback, int result) const;
|
||||
+ void RunWriteCallback(int result);
|
||||
|
||||
void OnIOComplete(int result);
|
||||
|
||||
@@ -195,13 +195,7 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
|
||||
};
|
||||
EndStreamState end_stream_state_ = EndStreamState::kNone;
|
||||
|
||||
- // The default weak pointer factory.
|
||||
base::WeakPtrFactory<SpdyProxyClientSocket> weak_factory_{this};
|
||||
-
|
||||
- // Only used for posting write callbacks. Weak pointers created by this
|
||||
- // factory are invalidated in Disconnect().
|
||||
- base::WeakPtrFactory<SpdyProxyClientSocket> write_callback_weak_factory_{
|
||||
- this};
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Will Harris <wfh@chromium.org>
|
||||
Date: Thu, 2 Mar 2023 16:49:42 +0000
|
||||
Subject: Prevent potential integer overflow in PersistentMemoryAllocator (1/2)
|
||||
|
||||
BUG=1415328
|
||||
|
||||
(cherry picked from commit 19de280a0c28065acf2a7e001af5c981698a461c)
|
||||
|
||||
Change-Id: I66dcae6a1aacc1310ddd715033b3704c932b9800
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4250177
|
||||
Commit-Queue: Will Harris <wfh@chromium.org>
|
||||
Commit-Queue: Alexei Svitkine <asvitkine@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1105177}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4279513
|
||||
Commit-Queue: Zakhar Voit <voit@google.com>
|
||||
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5359@{#1400}
|
||||
Cr-Branched-From: 27d3765d341b09369006d030f83f582a29eb57ae-refs/heads/main@{#1058933}
|
||||
|
||||
diff --git a/base/metrics/persistent_memory_allocator.cc b/base/metrics/persistent_memory_allocator.cc
|
||||
index bc4618bf30832d010570e8a490d3d893f064237b..b7edfc04c307662450f3a39c20142c3593fbacde 100644
|
||||
--- a/base/metrics/persistent_memory_allocator.cc
|
||||
+++ b/base/metrics/persistent_memory_allocator.cc
|
||||
@@ -531,7 +531,10 @@ size_t PersistentMemoryAllocator::GetAllocSize(Reference ref) const {
|
||||
uint32_t size = block->size;
|
||||
// Header was verified by GetBlock() but a malicious actor could change
|
||||
// the value between there and here. Check it again.
|
||||
- if (size <= sizeof(BlockHeader) || ref + size > mem_size_) {
|
||||
+ uint32_t total_size;
|
||||
+ if (size <= sizeof(BlockHeader) ||
|
||||
+ !base::CheckAdd(ref, size).AssignIfValid(&total_size) ||
|
||||
+ total_size > mem_size_) {
|
||||
SetCorrupt();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Anderson <thomasanderson@chromium.org>
|
||||
Date: Tue, 13 Dec 2022 22:49:47 +0000
|
||||
Subject: Ensure DND buffer size is a multiple of scale
|
||||
|
||||
When using a scale factor of 2.0 on Sway ToT, this fixes a crash when
|
||||
trying to DND an image or text that happens to have an odd width or
|
||||
height. The issue is Wlroots will not allow attaching a buffer to a
|
||||
surface when the buffer's size isn't a multiple of the surface's scale
|
||||
factor.
|
||||
|
||||
R=nickdiego
|
||||
|
||||
Bug: 578890
|
||||
Change-Id: I283ed27a7d0051b895e0eed3b9a74d83feac3a37
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4099423
|
||||
Reviewed-by: Nick Yamane <nickdiego@igalia.com>
|
||||
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1082777}
|
||||
|
||||
diff --git a/ui/ozone/platform/wayland/common/wayland_util.cc b/ui/ozone/platform/wayland/common/wayland_util.cc
|
||||
index 4e8aa4b1e5530311338fbb43483e16d845707d2f..9b5806895a92cc92176644a0477d48bf79a35606 100644
|
||||
--- a/ui/ozone/platform/wayland/common/wayland_util.cc
|
||||
+++ b/ui/ozone/platform/wayland/common/wayland_util.cc
|
||||
@@ -115,7 +115,8 @@ uint32_t IdentifyDirection(const ui::WaylandConnection& connection,
|
||||
bool DrawBitmap(const SkBitmap& bitmap, ui::WaylandShmBuffer* out_buffer) {
|
||||
DCHECK(out_buffer);
|
||||
DCHECK(out_buffer->GetMemory());
|
||||
- DCHECK_EQ(out_buffer->size(), gfx::Size(bitmap.width(), bitmap.height()));
|
||||
+ DCHECK(gfx::Rect(out_buffer->size())
|
||||
+ .Contains(gfx::Rect(bitmap.width(), bitmap.height())));
|
||||
|
||||
auto* mapped_memory = out_buffer->GetMemory();
|
||||
auto size = out_buffer->size();
|
||||
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
|
||||
index f2123ec8bac3f6afe9f46ba358cb9c829b2e9325..2bb7d0f4de6f8c50cc2bbaba6baaa0b684531115 100644
|
||||
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
|
||||
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
|
||||
@@ -140,7 +140,8 @@ bool WaylandDataDragController::StartSession(const OSExchangeData& data,
|
||||
icon_surface_ = std::make_unique<WaylandSurface>(connection_, nullptr);
|
||||
if (icon_surface_->Initialize()) {
|
||||
// Corresponds to actual scale factor of the origin surface.
|
||||
- icon_surface_->set_surface_buffer_scale(origin_window->window_scale());
|
||||
+ icon_surface_buffer_scale_ = origin_window->window_scale();
|
||||
+ icon_surface_->set_surface_buffer_scale(icon_surface_buffer_scale_);
|
||||
// Icon surface do not need input.
|
||||
const gfx::Rect empty_region_px;
|
||||
icon_surface_->set_input_region(&empty_region_px);
|
||||
@@ -153,6 +154,7 @@ bool WaylandDataDragController::StartSession(const OSExchangeData& data,
|
||||
} else {
|
||||
LOG(ERROR) << "Failed to create drag icon surface.";
|
||||
icon_surface_.reset();
|
||||
+ icon_surface_buffer_scale_ = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,21 +227,28 @@ void WaylandDataDragController::DrawIconInternal() {
|
||||
return;
|
||||
|
||||
DCHECK(!icon_bitmap_->empty());
|
||||
- gfx::Size size(icon_bitmap_->width(), icon_bitmap_->height());
|
||||
+ // The protocol expects the attached buffer to have a pixel size that is a
|
||||
+ // multiple of the surface's scale factor. Some compositors (eg. Wlroots) will
|
||||
+ // refuse to attach the buffer if this condition is not met.
|
||||
+ const gfx::Size size_dip =
|
||||
+ gfx::ScaleToCeiledSize({icon_bitmap_->width(), icon_bitmap_->height()},
|
||||
+ 1.0f / icon_surface_buffer_scale_);
|
||||
+ const gfx::Size size_px =
|
||||
+ gfx::ScaleToCeiledSize(size_dip, icon_surface_buffer_scale_);
|
||||
|
||||
icon_buffer_ = std::make_unique<WaylandShmBuffer>(
|
||||
- connection_->wayland_buffer_factory(), size);
|
||||
+ connection_->wayland_buffer_factory(), size_px);
|
||||
if (!icon_buffer_->IsValid()) {
|
||||
LOG(ERROR) << "Failed to create drag icon buffer.";
|
||||
return;
|
||||
}
|
||||
|
||||
- DVLOG(3) << "Drawing drag icon. size=" << size.ToString();
|
||||
+ DVLOG(3) << "Drawing drag icon. size_px=" << size_px.ToString();
|
||||
wl::DrawBitmap(*icon_bitmap_, icon_buffer_.get());
|
||||
auto* const surface = icon_surface_->surface();
|
||||
wl_surface_attach(surface, icon_buffer_->get(), icon_offset_.x(),
|
||||
icon_offset_.y());
|
||||
- wl_surface_damage(surface, 0, 0, size.width(), size.height());
|
||||
+ wl_surface_damage(surface, 0, 0, size_px.width(), size_px.height());
|
||||
wl_surface_commit(surface);
|
||||
}
|
||||
|
||||
@@ -370,6 +379,7 @@ void WaylandDataDragController::OnDataSourceFinish(bool completed) {
|
||||
data_offer_.reset();
|
||||
icon_buffer_.reset();
|
||||
icon_surface_.reset();
|
||||
+ icon_surface_buffer_scale_ = 1.0f;
|
||||
icon_bitmap_ = nullptr;
|
||||
icon_frame_callback_.reset();
|
||||
offered_exchange_data_provider_.reset();
|
||||
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
|
||||
index 9912f1e0aebaf8289d2cdcdbff472a0baa91a981..39acda6bae9eb3a3f7837f6c93fafcee493bf78b 100644
|
||||
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
|
||||
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
|
||||
@@ -224,6 +224,7 @@ class WaylandDataDragController : public WaylandDataDevice::DragDelegate,
|
||||
|
||||
// Drag icon related variables.
|
||||
std::unique_ptr<WaylandSurface> icon_surface_;
|
||||
+ float icon_surface_buffer_scale_ = 1.0f;
|
||||
std::unique_ptr<WaylandShmBuffer> icon_buffer_;
|
||||
raw_ptr<const SkBitmap> icon_bitmap_ = nullptr;
|
||||
gfx::Point icon_offset_;
|
||||
@@ -21,5 +21,13 @@
|
||||
|
||||
"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/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
|
||||
|
||||
"src/electron/patches/pdfium": "src/third_party/pdfium",
|
||||
|
||||
"src/electron/patches/skia": "src/third_party/skia",
|
||||
|
||||
"src/electron/patches/dawn": "src/third_party/dawn",
|
||||
|
||||
"src/electron/patches/webrtc": "src/third_party/webrtc"
|
||||
}
|
||||
|
||||
1
patches/dawn/.patches
Normal file
1
patches/dawn/.patches
Normal file
@@ -0,0 +1 @@
|
||||
change_d3d12_descriptor_allocator_to_invalidate_submitted_descriptors.patch
|
||||
@@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brandon Jones <brandon1.jones@intel.com>
|
||||
Date: Fri, 5 May 2023 18:02:42 +0000
|
||||
Subject: Change D3D12 Descriptor Allocator To Invalidate Submitted Descriptors
|
||||
|
||||
Changes D3D12 descriptor allocator to invalidate existing descriptors
|
||||
after the descriptor heap was submitted for use. This fixes a
|
||||
synchonization issue where stale descriptors were seen as valid because
|
||||
command list execution ran long.
|
||||
|
||||
Bug: dawn:1701
|
||||
Bug: chromium:1442263
|
||||
No-Try: true
|
||||
Change-Id: Ibfd450b3be6cf91d66e8dce4ffd19ecf1a37f7f5
|
||||
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/129920
|
||||
Kokoro: Kokoro <noreply+kokoro@google.com>
|
||||
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
|
||||
Commit-Queue: Brandon1 Jones <brandon1.jones@intel.com>
|
||||
(cherry picked from commit df6cb236493da101dad79fe50d4e6df0d5d1e915)
|
||||
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/131508
|
||||
Kokoro: Austin Eng <enga@chromium.org>
|
||||
Reviewed-by: Austin Eng <enga@chromium.org>
|
||||
|
||||
diff --git a/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp b/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
|
||||
index fe99a63ac9d2d082c2c23eb7940a733a9d13846a..aedb28ad58a0a972879f07a6037499f901fcf04a 100644
|
||||
--- a/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
|
||||
+++ b/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
|
||||
@@ -237,9 +237,11 @@ bool ShaderVisibleDescriptorAllocator::IsLastShaderVisibleHeapInLRUForTesting()
|
||||
|
||||
bool ShaderVisibleDescriptorAllocator::IsAllocationStillValid(
|
||||
const GPUDescriptorHeapAllocation& allocation) const {
|
||||
- // Consider valid if allocated for the pending submit and the shader visible heaps
|
||||
- // have not switched over.
|
||||
- return (allocation.GetLastUsageSerial() > mDevice->GetCompletedCommandSerial() &&
|
||||
+ // Descriptor allocations are only valid for the serial they were created for and are
|
||||
+ // re-allocated every submit. For this reason, we view any descriptors allocated prior to the
|
||||
+ // pending submit as invalid. We must also verify the descriptor heap has not switched (because
|
||||
+ // a larger descriptor heap was needed).
|
||||
+ return (allocation.GetLastUsageSerial() == mDevice->GetPendingCommandSerial() &&
|
||||
allocation.GetHeapSerial() == mHeapSerial);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ index 93d85d46dc6b3b30795b88ffa8070253f62e51bd..05f8232c4b38f51e8059e8d01b0eb247
|
||||
if ((s.flags & SHOULD_NOT_SET_PROMISE_REJECTION_CALLBACK) == 0) {
|
||||
auto* promise_reject_cb = s.promise_reject_callback ?
|
||||
diff --git a/src/node.h b/src/node.h
|
||||
index 38bbb20968772a4ba6bceddb04a83589f8582fc8..a5ee97ae83149a1924e9d6198ad4b2a7fd8b876d 100644
|
||||
index b5e4d42035a23b49fd144d563f5716fcaed2b45c..f2e2acc98c1165430e46351fe07637315cc2c38e 100644
|
||||
--- a/src/node.h
|
||||
+++ b/src/node.h
|
||||
@@ -374,6 +374,8 @@ struct IsolateSettings {
|
||||
|
||||
@@ -52,7 +52,7 @@ index 08894bf3908916d1cb639810c5e1b2afae74ff4d..19cbde58df38009258db145c5f7dbe73
|
||||
o['variables']['v8_enable_lite_mode'] = 1 if options.v8_lite_mode else 0
|
||||
o['variables']['v8_enable_gdbjit'] = 1 if options.gdb else 0
|
||||
diff --git a/src/node.h b/src/node.h
|
||||
index b6a26f8adf11959f94a00de0cbf9016fcc8707cb..38bbb20968772a4ba6bceddb04a83589f8582fc8 100644
|
||||
index b6a26f8adf11959f94a00de0cbf9016fcc8707cb..b5e4d42035a23b49fd144d563f5716fcaed2b45c 100644
|
||||
--- a/src/node.h
|
||||
+++ b/src/node.h
|
||||
@@ -22,6 +22,12 @@
|
||||
@@ -61,7 +61,7 @@ index b6a26f8adf11959f94a00de0cbf9016fcc8707cb..38bbb20968772a4ba6bceddb04a83589
|
||||
|
||||
+#ifdef ELECTRON_ENSURE_CONFIG_GYPI
|
||||
+#ifndef USING_ELECTRON_CONFIG_GYPI
|
||||
+#error "It looks like you are building this native module without using the right config.gypi. This normally means that you need to update electron-rebuild (>=3.2.8) or node-gyp (>=8.4.0) if you're building modules directly."
|
||||
+#error "It looks like you are building this native module without using the right config.gypi. This normally means that you need to update electron-rebuild (>=3.2.8) or node-gyp (>=9.0.0) if you're building modules directly."
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
|
||||
@@ -7,7 +7,7 @@ Wc++98-compat-extra-semi is turned on for Electron so this
|
||||
patch fixes that error in node.
|
||||
|
||||
diff --git a/src/node_serdes.cc b/src/node_serdes.cc
|
||||
index 92d5020f293c98c81d3891a82f7320629bf9f926..2e815154ddbbd687e9c823cb7d42f11b7cb48000 100644
|
||||
index 573c185465407bbe34ef1c4ec5f58f6add596d42..b64333132d5c2322d29ad087fe60e0bbe24bebe2 100644
|
||||
--- a/src/node_serdes.cc
|
||||
+++ b/src/node_serdes.cc
|
||||
@@ -32,7 +32,7 @@ namespace serdes {
|
||||
|
||||
@@ -155,7 +155,7 @@ index f7314c906e580664be445a8912030e17a3ac2fa4..99258ad0aa1e15ea1ba139fd0e83111e
|
||||
|
||||
// Delegate to V8's allocator for compatibility with the V8 memory cage.
|
||||
diff --git a/src/node_serdes.cc b/src/node_serdes.cc
|
||||
index f6f0034bc24d09e3ad65491c7d6be0b9c9db1581..92d5020f293c98c81d3891a82f7320629bf9f926 100644
|
||||
index f6f0034bc24d09e3ad65491c7d6be0b9c9db1581..573c185465407bbe34ef1c4ec5f58f6add596d42 100644
|
||||
--- a/src/node_serdes.cc
|
||||
+++ b/src/node_serdes.cc
|
||||
@@ -29,6 +29,11 @@ using v8::ValueSerializer;
|
||||
@@ -219,17 +219,32 @@ index f6f0034bc24d09e3ad65491c7d6be0b9c9db1581..92d5020f293c98c81d3891a82f732062
|
||||
Maybe<bool> SerializerContext::WriteHostObject(Isolate* isolate,
|
||||
Local<Object> input) {
|
||||
MaybeLocal<Value> ret;
|
||||
@@ -211,7 +240,12 @@ void SerializerContext::ReleaseBuffer(const FunctionCallbackInfo<Value>& args) {
|
||||
@@ -209,9 +238,14 @@ void SerializerContext::ReleaseBuffer(const FunctionCallbackInfo<Value>& args) {
|
||||
// Note: Both ValueSerializer and this Buffer::New() variant use malloc()
|
||||
// as the underlying allocator.
|
||||
std::pair<uint8_t*, size_t> ret = ctx->serializer_.Release();
|
||||
auto buf = Buffer::New(ctx->env(),
|
||||
reinterpret_cast<char*>(ret.first),
|
||||
- auto buf = Buffer::New(ctx->env(),
|
||||
- reinterpret_cast<char*>(ret.first),
|
||||
- ret.second);
|
||||
+ ret.second,
|
||||
+ [](char* data, void* hint){
|
||||
+ if (data)
|
||||
+ GetAllocator()->Free(data, reinterpret_cast<size_t>(hint));
|
||||
+ },
|
||||
+ reinterpret_cast<void*>(ctx->last_length_));
|
||||
+ std::unique_ptr<v8::BackingStore> bs =
|
||||
+ v8::ArrayBuffer::NewBackingStore(reinterpret_cast<char*>(ret.first), ret.second,
|
||||
+ [](void* data, size_t length, void* deleter_data) {
|
||||
+ if (data) GetAllocator()->Free(reinterpret_cast<char*>(data), length);
|
||||
+ }, nullptr);
|
||||
+ Local<ArrayBuffer> ab = v8::ArrayBuffer::New(ctx->env()->isolate(), std::move(bs));
|
||||
+
|
||||
+ auto buf = Buffer::New(ctx->env(), ab, 0, ret.second);
|
||||
|
||||
if (!buf.IsEmpty()) {
|
||||
args.GetReturnValue().Set(buf.ToLocalChecked());
|
||||
diff --git a/test/parallel/test-v8-serialize-leak.js b/test/parallel/test-v8-serialize-leak.js
|
||||
index a90c398adcdaf30491a0fecdcf00895038d62e69..f5b8a1430ad2033eae06ca0157af2fb51d3f36a5 100644
|
||||
--- a/test/parallel/test-v8-serialize-leak.js
|
||||
+++ b/test/parallel/test-v8-serialize-leak.js
|
||||
@@ -23,5 +23,5 @@ const after = process.memoryUsage.rss();
|
||||
if (process.config.variables.asan) {
|
||||
assert(after < before * 10, `asan: before=${before} after=${after}`);
|
||||
} else {
|
||||
- assert(after < before * 2, `before=${before} after=${after}`);
|
||||
+ assert(after < before * 3, `before=${before} after=${after}`);
|
||||
}
|
||||
|
||||
4
patches/pdfium/.patches
Normal file
4
patches/pdfium/.patches
Normal file
@@ -0,0 +1,4 @@
|
||||
cherry-pick-a0d16d18d072.patch
|
||||
m114_observe_cpwl_combobox_across_all_on_methods.patch
|
||||
m114_observe_widget_across_setoptionselection_calls.patch
|
||||
m114_always_check_return_code_from_cpwl_combobox_setpopup.patch
|
||||
164
patches/pdfium/cherry-pick-a0d16d18d072.patch
Normal file
164
patches/pdfium/cherry-pick-a0d16d18d072.patch
Normal file
@@ -0,0 +1,164 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Sepez <tsepez@chromium.org>
|
||||
Date: Tue, 14 Mar 2023 21:18:45 +0000
|
||||
Subject: M110: Observe CPWL_* object destruction across CPDFSDK_Widget methods
|
||||
|
||||
This is a simple fix to stop the symptoms while we investigate
|
||||
how to avoid mutations at these points in the first place.
|
||||
|
||||
-- fix some nearby braces and annoying blank lines while at it.
|
||||
|
||||
Bug: chromium:1419831
|
||||
Change-Id: I20c38806b91c7c0c9016bb1b567a04ce319243d8
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/104397
|
||||
Commit-Queue: Tom Sepez <tsepez@chromium.org>
|
||||
Reviewed-by: Lei Zhang <thestig@chromium.org>
|
||||
(cherry picked from commit 63e3719f1ec20ee6db804b2b2d4b00680db18d9c)
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/104833
|
||||
Auto-Submit: Tom Sepez <tsepez@chromium.org>
|
||||
|
||||
diff --git a/fpdfsdk/formfiller/cffl_checkbox.cpp b/fpdfsdk/formfiller/cffl_checkbox.cpp
|
||||
index 2cea0e0ad0d13149a6e7e499c5ea3366d84c9aaa..7c875486016b0b4205b31b9db077850663bc33af 100644
|
||||
--- a/fpdfsdk/formfiller/cffl_checkbox.cpp
|
||||
+++ b/fpdfsdk/formfiller/cffl_checkbox.cpp
|
||||
@@ -65,9 +65,13 @@ bool CFFL_CheckBox::OnChar(CPDFSDK_Widget* pWidget,
|
||||
CFFL_FormField::OnChar(pWidget, nChar, nFlags);
|
||||
|
||||
CPWL_CheckBox* pWnd = CreateOrUpdatePWLCheckBox(pPageView);
|
||||
- if (pWnd && !pWnd->IsReadOnly())
|
||||
- pWnd->SetCheck(!pWidget->IsChecked());
|
||||
-
|
||||
+ if (pWnd && !pWnd->IsReadOnly()) {
|
||||
+ ObservedPtr<CPWL_CheckBox> pObservedBox(pWnd);
|
||||
+ const bool is_checked = pWidget->IsChecked();
|
||||
+ if (pObservedBox) {
|
||||
+ pObservedBox->SetCheck(!is_checked);
|
||||
+ }
|
||||
+ }
|
||||
return CommitData(pPageView, nFlags);
|
||||
}
|
||||
default:
|
||||
@@ -80,14 +84,17 @@ bool CFFL_CheckBox::OnLButtonUp(CPDFSDK_PageView* pPageView,
|
||||
Mask<FWL_EVENTFLAG> nFlags,
|
||||
const CFX_PointF& point) {
|
||||
CFFL_Button::OnLButtonUp(pPageView, pWidget, nFlags, point);
|
||||
-
|
||||
- if (!IsValid())
|
||||
+ if (!IsValid()) {
|
||||
return true;
|
||||
-
|
||||
+ }
|
||||
CPWL_CheckBox* pWnd = CreateOrUpdatePWLCheckBox(pPageView);
|
||||
- if (pWnd)
|
||||
- pWnd->SetCheck(!pWidget->IsChecked());
|
||||
-
|
||||
+ if (pWnd) {
|
||||
+ ObservedPtr<CPWL_CheckBox> pObservedBox(pWnd);
|
||||
+ const bool is_checked = pWidget->IsChecked();
|
||||
+ if (pObservedBox) {
|
||||
+ pObservedBox->SetCheck(!is_checked);
|
||||
+ }
|
||||
+ }
|
||||
return CommitData(pPageView, nFlags);
|
||||
}
|
||||
|
||||
diff --git a/fpdfsdk/formfiller/cffl_listbox.cpp b/fpdfsdk/formfiller/cffl_listbox.cpp
|
||||
index 96b4aea8e74a629d201cd780d631d4e82d5b284c..4bb100014c804adcfc7f1f2023cd1870f81c85e8 100644
|
||||
--- a/fpdfsdk/formfiller/cffl_listbox.cpp
|
||||
+++ b/fpdfsdk/formfiller/cffl_listbox.cpp
|
||||
@@ -105,11 +105,15 @@ bool CFFL_ListBox::IsDataChanged(const CPDFSDK_PageView* pPageView) {
|
||||
|
||||
void CFFL_ListBox::SaveData(const CPDFSDK_PageView* pPageView) {
|
||||
CPWL_ListBox* pListBox = GetPWLListBox(pPageView);
|
||||
- if (!pListBox)
|
||||
+ if (!pListBox) {
|
||||
return;
|
||||
-
|
||||
+ }
|
||||
int32_t nNewTopIndex = pListBox->GetTopVisibleIndex();
|
||||
+ ObservedPtr<CPWL_ListBox> observed_box(pListBox);
|
||||
m_pWidget->ClearSelection();
|
||||
+ if (!observed_box) {
|
||||
+ return;
|
||||
+ }
|
||||
if (m_pWidget->GetFieldFlags() & pdfium::form_flags::kChoiceMultiSelect) {
|
||||
for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) {
|
||||
if (pListBox->IsItemSelected(i))
|
||||
@@ -121,17 +125,17 @@ void CFFL_ListBox::SaveData(const CPDFSDK_PageView* pPageView) {
|
||||
ObservedPtr<CPDFSDK_Widget> observed_widget(m_pWidget.Get());
|
||||
ObservedPtr<CFFL_ListBox> observed_this(this);
|
||||
m_pWidget->SetTopVisibleIndex(nNewTopIndex);
|
||||
- if (!observed_widget)
|
||||
+ if (!observed_widget) {
|
||||
return;
|
||||
-
|
||||
+ }
|
||||
m_pWidget->ResetFieldAppearance();
|
||||
- if (!observed_widget)
|
||||
+ if (!observed_widget) {
|
||||
return;
|
||||
-
|
||||
+ }
|
||||
m_pWidget->UpdateField();
|
||||
- if (!observed_widget || !observed_this)
|
||||
+ if (!observed_widget || !observed_this) {
|
||||
return;
|
||||
-
|
||||
+ }
|
||||
SetChangeMark();
|
||||
}
|
||||
|
||||
diff --git a/fpdfsdk/formfiller/cffl_textfield.cpp b/fpdfsdk/formfiller/cffl_textfield.cpp
|
||||
index 5ae3e94cd185e56d759cb99dbc90997caa606283..2ceedde4a765e765e75e478ebee43204fe440fe4 100644
|
||||
--- a/fpdfsdk/formfiller/cffl_textfield.cpp
|
||||
+++ b/fpdfsdk/formfiller/cffl_textfield.cpp
|
||||
@@ -142,26 +142,29 @@ bool CFFL_TextField::IsDataChanged(const CPDFSDK_PageView* pPageView) {
|
||||
}
|
||||
|
||||
void CFFL_TextField::SaveData(const CPDFSDK_PageView* pPageView) {
|
||||
- CPWL_Edit* pWnd = GetPWLEdit(pPageView);
|
||||
- if (!pWnd)
|
||||
+ ObservedPtr<CPWL_Edit> observed_edit(GetPWLEdit(pPageView));
|
||||
+ if (!observed_edit) {
|
||||
return;
|
||||
-
|
||||
+ }
|
||||
WideString sOldValue = m_pWidget->GetValue();
|
||||
- WideString sNewValue = pWnd->GetText();
|
||||
+ if (!observed_edit) {
|
||||
+ return;
|
||||
+ }
|
||||
+ WideString sNewValue = observed_edit->GetText();
|
||||
ObservedPtr<CPDFSDK_Widget> observed_widget(m_pWidget.Get());
|
||||
ObservedPtr<CFFL_TextField> observed_this(this);
|
||||
m_pWidget->SetValue(sNewValue);
|
||||
- if (!observed_widget)
|
||||
+ if (!observed_widget) {
|
||||
return;
|
||||
-
|
||||
+ }
|
||||
m_pWidget->ResetFieldAppearance();
|
||||
- if (!observed_widget)
|
||||
+ if (!observed_widget) {
|
||||
return;
|
||||
-
|
||||
+ }
|
||||
m_pWidget->UpdateField();
|
||||
- if (!observed_widget || !observed_this)
|
||||
+ if (!observed_widget || !observed_this) {
|
||||
return;
|
||||
-
|
||||
+ }
|
||||
SetChangeMark();
|
||||
}
|
||||
|
||||
@@ -172,9 +175,7 @@ void CFFL_TextField::GetActionData(const CPDFSDK_PageView* pPageView,
|
||||
case CPDF_AAction::kKeyStroke:
|
||||
if (CPWL_Edit* pWnd = GetPWLEdit(pPageView)) {
|
||||
fa.bFieldFull = pWnd->IsTextFull();
|
||||
-
|
||||
fa.sValue = pWnd->GetText();
|
||||
-
|
||||
if (fa.bFieldFull) {
|
||||
fa.sChange.clear();
|
||||
fa.sChangeEx.clear();
|
||||
@@ -0,0 +1,236 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Sepez <tsepez@chromium.org>
|
||||
Date: Fri, 19 May 2023 18:41:31 +0000
|
||||
Subject: Always check return code from CPWL_ComboBox::SetPopup().
|
||||
|
||||
Operation must not continue when false is returned.
|
||||
|
||||
Bug: chromium:1444238
|
||||
Change-Id: Ic8c29653ac185ac80b6248203649ce05d0e10f06
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107390
|
||||
Commit-Queue: Tom Sepez <tsepez@chromium.org>
|
||||
Reviewed-by: Lei Zhang <thestig@chromium.org>
|
||||
(cherry picked from commit 3eb3c4d77d4f9372f77aa4895b85a1d4e4755c89)
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107812
|
||||
|
||||
diff --git a/fpdfsdk/pwl/cpwl_combo_box.cpp b/fpdfsdk/pwl/cpwl_combo_box.cpp
|
||||
index 4d834e698ee1b08bcc81d20e062e029620438b7e..fdcc2ef1b2fba4257aab3835f58c5ec0913663cf 100644
|
||||
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
|
||||
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
|
||||
@@ -400,7 +400,9 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
|
||||
// options.
|
||||
switch (nChar) {
|
||||
case pdfium::ascii::kReturn:
|
||||
- SetPopup(!IsPopup());
|
||||
+ if (!SetPopup(!IsPopup())) {
|
||||
+ return false;
|
||||
+ }
|
||||
SetSelectText();
|
||||
return true;
|
||||
case pdfium::ascii::kSpace:
|
||||
@@ -408,7 +410,9 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
|
||||
// editable
|
||||
if (!HasFlag(PCBS_ALLOWCUSTOMTEXT)) {
|
||||
if (!IsPopup()) {
|
||||
- SetPopup(/*bPopUp=*/true);
|
||||
+ if (!SetPopup(/*bPopUp=*/true)) {
|
||||
+ return false;
|
||||
+ }
|
||||
SetSelectText();
|
||||
}
|
||||
return true;
|
||||
@@ -438,7 +442,7 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
|
||||
|
||||
void CPWL_ComboBox::NotifyLButtonDown(CPWL_Wnd* child, const CFX_PointF& pos) {
|
||||
if (child == m_pButton) {
|
||||
- SetPopup(!m_bPopup);
|
||||
+ (void)SetPopup(!m_bPopup);
|
||||
// Note, |this| may no longer be viable at this point. If more work needs to
|
||||
// be done, check the return value of SetPopup().
|
||||
}
|
||||
@@ -451,7 +455,7 @@ void CPWL_ComboBox::NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) {
|
||||
SetSelectText();
|
||||
SelectAllText();
|
||||
m_pEdit->SetFocus();
|
||||
- SetPopup(false);
|
||||
+ (void)SetPopup(false);
|
||||
// Note, |this| may no longer be viable at this point. If more work needs to
|
||||
// be done, check the return value of SetPopup().
|
||||
}
|
||||
diff --git a/fpdfsdk/pwl/cpwl_combo_box.h b/fpdfsdk/pwl/cpwl_combo_box.h
|
||||
index 0d13b40b7a1fa1410070a14a3f9f4ef5ad625181..4b97394996d0fb1212e8f7e54f3513e1e93b6b80 100644
|
||||
--- a/fpdfsdk/pwl/cpwl_combo_box.h
|
||||
+++ b/fpdfsdk/pwl/cpwl_combo_box.h
|
||||
@@ -64,7 +64,7 @@ class CPWL_ComboBox final : public CPWL_Wnd {
|
||||
void CreateListBox(const CreateParams& cp);
|
||||
|
||||
// Returns |true| iff this instance is still allocated.
|
||||
- bool SetPopup(bool bPopup);
|
||||
+ [[nodiscard]] bool SetPopup(bool bPopup);
|
||||
|
||||
UnownedPtr<CPWL_Edit> m_pEdit;
|
||||
UnownedPtr<CPWL_CBButton> m_pButton;
|
||||
diff --git a/testing/resources/javascript/xfa_specific/bug_1444238.evt b/testing/resources/javascript/xfa_specific/bug_1444238.evt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..adca35aa0d756e76eb395c5d60ba41b86c3d0090
|
||||
--- /dev/null
|
||||
+++ b/testing/resources/javascript/xfa_specific/bug_1444238.evt
|
||||
@@ -0,0 +1,3 @@
|
||||
+mousedown,left,91,539
|
||||
+mouseup,left,91,539
|
||||
+charcode,32
|
||||
diff --git a/testing/resources/javascript/xfa_specific/bug_1444238.in b/testing/resources/javascript/xfa_specific/bug_1444238.in
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..675178c9446b0181c3633a4b5c9bc664bb4c127d
|
||||
--- /dev/null
|
||||
+++ b/testing/resources/javascript/xfa_specific/bug_1444238.in
|
||||
@@ -0,0 +1,149 @@
|
||||
+{{header}}
|
||||
+{{object 1 0}} <<
|
||||
+ /Type /Catalog
|
||||
+ /Pages 2 0 R
|
||||
+ /AcroForm 4 0 R
|
||||
+ /OpenAction 40 0 R
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 2 0}} <<
|
||||
+ /Type /Pages
|
||||
+ /Count 2
|
||||
+ /Kids [
|
||||
+ 32 0 R
|
||||
+ 34 0 R
|
||||
+ ]
|
||||
+>>
|
||||
+endobj
|
||||
+% Forms
|
||||
+{{object 4 0}} <<
|
||||
+ /XFA 43 0 R
|
||||
+ /Fields [
|
||||
+ 10 0 R
|
||||
+ 11 0 R
|
||||
+ ]
|
||||
+>>
|
||||
+endobj
|
||||
+% Fields
|
||||
+{{object 10 0}} <<
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /FT /Tx
|
||||
+ /T (MyField5)
|
||||
+ /V (myfield_5)
|
||||
+ /Rect [0 500 600 600]
|
||||
+>>
|
||||
+% Fields
|
||||
+{{object 11 0}} <<
|
||||
+ /T (MyField3)
|
||||
+ /Parent 4 0 R
|
||||
+ /Kids [12 0 R]
|
||||
+ /Opt [(a) (b) (c) (d)]
|
||||
+ /V [(a) (b) (c)]
|
||||
+>>
|
||||
+endobj
|
||||
+% Fields
|
||||
+{{object 12 0}} <<
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /FT /Ch
|
||||
+ /Ff 131072
|
||||
+ /Parent 11 0 R
|
||||
+ /Kids [13 0 R]
|
||||
+>>
|
||||
+endobj
|
||||
+% Fields
|
||||
+{{object 13 0}} <<
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /Parent 12 0 R
|
||||
+ /Rect [0 400 600 600]
|
||||
+>>
|
||||
+endobj
|
||||
+% Fields
|
||||
+{{object 14 0}} <<
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /Parent 12 0 R
|
||||
+ /Rect [100 400 500 500]
|
||||
+>>
|
||||
+endobj
|
||||
+% Page number 2.
|
||||
+{{object 32 0}} <<
|
||||
+ /Type /Page
|
||||
+ /Parent 2 0 R
|
||||
+ /MediaBox [0 0 612 792]
|
||||
+ /Annots [13 0 R]
|
||||
+
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 34 0}} <<
|
||||
+ /Type /Page
|
||||
+ /Parent 2 0 R
|
||||
+ /MediaBox [0 0 612 792]
|
||||
+ /Annots [10 0 R]
|
||||
+>>
|
||||
+endobj
|
||||
+% Document JS Action
|
||||
+{{object 40 0}} <<
|
||||
+ /Type /Action
|
||||
+ /S /JavaScript
|
||||
+ /JS 41 0 R
|
||||
+>>
|
||||
+endobj
|
||||
+% JS program to exexute
|
||||
+{{object 41 0}} <<
|
||||
+>>
|
||||
+stream
|
||||
+var f5 = this.getField("MyField5");
|
||||
+var f3 = this.getField("MyField3");
|
||||
+f3.setFocus();
|
||||
+this.__defineGetter__("pageNum",function o(){f5.setFocus(); f3.borderStyle="dashed"; f3.setFocus();});
|
||||
+endstream
|
||||
+endobj
|
||||
+{{object 43 0}} <<
|
||||
+ {{streamlen}}
|
||||
+>>
|
||||
+stream
|
||||
+<?xml version="1.0" encoding="UTF-8"?>
|
||||
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
|
||||
+<config></config>
|
||||
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.8/">
|
||||
+ <subform layout="tb" locale="en_US">
|
||||
+ <pageSet>
|
||||
+ <pageArea id="Page1" name="Page1">
|
||||
+ <contentArea h="268.939mm" w="203.2mm" x="6.35mm" y="6.35mm"/>
|
||||
+ <medium long="792pt" short="612pt" stock="default"/>
|
||||
+ </pageArea>
|
||||
+ </pageSet>
|
||||
+ <field h="9.0001mm" name="MyField3" w="47.625mm" x="120mm" y="120mm">
|
||||
+ <ui>
|
||||
+ <choiceList open="onEntry">
|
||||
+ <border>
|
||||
+ <edge/>
|
||||
+ </border>
|
||||
+ </choiceList>
|
||||
+ </ui>
|
||||
+ <items save="1">
|
||||
+ <text>apples</text>
|
||||
+ <text>bananas</text>
|
||||
+ <text>pears</text>
|
||||
+ </items>
|
||||
+ <value>
|
||||
+ <text>apples</text>
|
||||
+ </value>
|
||||
+ <event activity="preOpen">
|
||||
+ <script contentType="application/x-javascript">
|
||||
+ var aa = this.pageNum;
|
||||
+ </script>
|
||||
+ </event>
|
||||
+ </field>
|
||||
+ </subform>
|
||||
+</template>
|
||||
+</xdp:xdp>
|
||||
+endstream
|
||||
+endobj
|
||||
+{{xref}}
|
||||
+{{trailer}}
|
||||
+{{startxref}}
|
||||
+%%EOF
|
||||
@@ -0,0 +1,213 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Sepez <tsepez@chromium.org>
|
||||
Date: Fri, 19 May 2023 20:05:10 +0000
|
||||
Subject: Observe CPWL_ComboBox across all On* methods
|
||||
|
||||
Bug: chromium:1445426
|
||||
Change-Id: I1d7ebf66fe170ca016c27a0df3ac4574e75c763c
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107650
|
||||
Reviewed-by: Lei Zhang <thestig@chromium.org>
|
||||
Commit-Queue: Tom Sepez <tsepez@chromium.org>
|
||||
(cherry picked from commit 29c665ea4c61b089746c3f502c30fcb5f4b11486)
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107811
|
||||
|
||||
diff --git a/fpdfsdk/pwl/cpwl_combo_box.cpp b/fpdfsdk/pwl/cpwl_combo_box.cpp
|
||||
index 6f89e7df41ea6691e805a4dd3942d5cb89787db3..4d834e698ee1b08bcc81d20e062e029620438b7e 100644
|
||||
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
|
||||
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
|
||||
@@ -339,31 +339,42 @@ bool CPWL_ComboBox::OnKeyDown(FWL_VKEYCODE nKeyCode,
|
||||
if (!m_pEdit)
|
||||
return false;
|
||||
|
||||
+ ObservedPtr<CPWL_Wnd> thisObserved(this);
|
||||
m_nSelectItem = -1;
|
||||
|
||||
switch (nKeyCode) {
|
||||
case FWL_VKEY_Up:
|
||||
if (m_pList->GetCurSel() > 0) {
|
||||
- if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag))
|
||||
+ if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag) ||
|
||||
+ !thisObserved) {
|
||||
return false;
|
||||
- if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag))
|
||||
+ }
|
||||
+ if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag) ||
|
||||
+ !thisObserved) {
|
||||
return false;
|
||||
+ }
|
||||
if (m_pList->IsMovementKey(nKeyCode)) {
|
||||
- if (m_pList->OnMovementKeyDown(nKeyCode, nFlag))
|
||||
+ if (m_pList->OnMovementKeyDown(nKeyCode, nFlag) || !thisObserved) {
|
||||
return false;
|
||||
+ }
|
||||
SetSelectText();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case FWL_VKEY_Down:
|
||||
if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
|
||||
- if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag))
|
||||
+ if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag) ||
|
||||
+ !thisObserved) {
|
||||
return false;
|
||||
- if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag))
|
||||
+ }
|
||||
+ if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag) ||
|
||||
+ !thisObserved) {
|
||||
return false;
|
||||
+ }
|
||||
if (m_pList->IsMovementKey(nKeyCode)) {
|
||||
- if (m_pList->OnMovementKeyDown(nKeyCode, nFlag))
|
||||
+ if (m_pList->OnMovementKeyDown(nKeyCode, nFlag) || !thisObserved) {
|
||||
return false;
|
||||
+ }
|
||||
SetSelectText();
|
||||
}
|
||||
}
|
||||
@@ -411,10 +422,15 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
|
||||
if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
|
||||
return m_pEdit->OnChar(nChar, nFlag);
|
||||
|
||||
- if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag))
|
||||
+ ObservedPtr<CPWL_Wnd> thisObserved(this);
|
||||
+ if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag) ||
|
||||
+ !thisObserved) {
|
||||
return false;
|
||||
- if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag))
|
||||
+ }
|
||||
+ if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag) ||
|
||||
+ !thisObserved) {
|
||||
return false;
|
||||
+ }
|
||||
if (!m_pList->IsChar(nChar, nFlag))
|
||||
return false;
|
||||
return m_pList->OnCharNotify(nChar, nFlag);
|
||||
diff --git a/testing/resources/javascript/bug_1445426.evt b/testing/resources/javascript/bug_1445426.evt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..265e85b0471b33509568238ccae30d2395b4b4ab
|
||||
--- /dev/null
|
||||
+++ b/testing/resources/javascript/bug_1445426.evt
|
||||
@@ -0,0 +1,3 @@
|
||||
+mousedown,left,202,697
|
||||
+mouseup,left,202,697
|
||||
+keycode,40
|
||||
diff --git a/testing/resources/javascript/bug_1445426.in b/testing/resources/javascript/bug_1445426.in
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1483da72f5759e9f2c8fdb538d5c6fa0cd1611c5
|
||||
--- /dev/null
|
||||
+++ b/testing/resources/javascript/bug_1445426.in
|
||||
@@ -0,0 +1,114 @@
|
||||
+{{header}}
|
||||
+{{object 1 0}} <<
|
||||
+ /Type /Catalog
|
||||
+ /Pages 2 0 R
|
||||
+ /AcroForm 4 0 R
|
||||
+ /OpenAction 40 0 R
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 2 0}} <<
|
||||
+ /Type /Pages
|
||||
+ /Count 2
|
||||
+ /Kids [
|
||||
+ 32 0 R
|
||||
+ 34 0 R
|
||||
+ ]
|
||||
+>>
|
||||
+endobj
|
||||
+% Forms
|
||||
+{{object 4 0}} <<
|
||||
+ /Fields [
|
||||
+ 10 0 R
|
||||
+ 11 0 R
|
||||
+ ]
|
||||
+>>
|
||||
+endobj
|
||||
+% Fields
|
||||
+{{object 10 0}} <<
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /FT /Tx
|
||||
+ /T (Field_TextEdit)
|
||||
+ /Rect [0 0 612 792]
|
||||
+>>
|
||||
+{{object 11 0}} <<
|
||||
+ /T (Field_ComboBox)
|
||||
+ /Parent 4 0 R
|
||||
+ /Kids [12 0 R]
|
||||
+ /Opt [(a) (b) (c) (d)]
|
||||
+ /V [(a)]
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 12 0}} <<
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /FT /Ch
|
||||
+ /Ff 131072
|
||||
+ /Parent 11 0 R
|
||||
+ /Kids [13 0 R]
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 13 0}} <<
|
||||
+ /Parent 12 0 R
|
||||
+ /Type /Annot
|
||||
+ /Subtype /Widget
|
||||
+ /Rect [0 0 612 792]
|
||||
+ /AA << /K 20 0 R >>
|
||||
+>>
|
||||
+endobj
|
||||
+% Pages
|
||||
+{{object 32 0}} <<
|
||||
+ /Type /Page
|
||||
+ /Parent 2 0 R
|
||||
+ /MediaBox [0 0 612 792]
|
||||
+ /Annots [13 0 R]
|
||||
+
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 34 0}} <<
|
||||
+ /Type /Page
|
||||
+ /Parent 2 0 R
|
||||
+ /MediaBox [0 0 612 792]
|
||||
+ /Annots [10 0 R]
|
||||
+>>
|
||||
+endobj
|
||||
+% Document JS Action
|
||||
+{{object 40 0}} <<
|
||||
+ /Type /Action
|
||||
+ /S /JavaScript
|
||||
+ /JS 41 0 R
|
||||
+>>
|
||||
+endobj
|
||||
+% JS program to exexute
|
||||
+{{object 41 0}} <<
|
||||
+ {{streamlen}}
|
||||
+>>
|
||||
+stream
|
||||
+var field_text = this.getField("Field_TextEdit");
|
||||
+var field_combobox = this.getField("Field_ComboBox");
|
||||
+field_combobox.setFocus();
|
||||
+this.__defineGetter__("filesize", function new_getter(){
|
||||
+ field_text.setFocus();
|
||||
+ field_combobox.borderStyle="dashed";
|
||||
+ field_combobox.setFocus();
|
||||
+ });
|
||||
+endstream
|
||||
+endobj
|
||||
+% OpenAction action
|
||||
+{{object 20 0}} <<
|
||||
+ /S /JavaScript
|
||||
+ /JS 21 0 R
|
||||
+>>
|
||||
+endobj
|
||||
+% JS program to exexute
|
||||
+{{object 21 0}} <<
|
||||
+ {{streamlen}}
|
||||
+>>
|
||||
+stream
|
||||
+var t = this.filesize;
|
||||
+endstream
|
||||
+endobj
|
||||
+{{xref}}
|
||||
+{{trailer}}
|
||||
+{{startxref}}
|
||||
+%%EOF
|
||||
@@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Sepez <tsepez@chromium.org>
|
||||
Date: Thu, 18 May 2023 18:37:17 +0000
|
||||
Subject: Observe widget across SetOptionSelection() calls.
|
||||
|
||||
Call may re-enter JavaScript.
|
||||
|
||||
Bug: chromium:1444581
|
||||
Change-Id: Id7a2f17b3b81f822ca8f4496ac08c19b7794c48a
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107394
|
||||
Commit-Queue: Tom Sepez <tsepez@chromium.org>
|
||||
Reviewed-by: Lei Zhang <thestig@chromium.org>
|
||||
(cherry picked from commit a9ff918a86d700c3bdf9b5820faed35490c0cd25)
|
||||
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107735
|
||||
Auto-Submit: Tom Sepez <tsepez@chromium.org>
|
||||
|
||||
diff --git a/fpdfsdk/formfiller/cffl_listbox.cpp b/fpdfsdk/formfiller/cffl_listbox.cpp
|
||||
index 4bb100014c804adcfc7f1f2023cd1870f81c85e8..6fe5d91a2472a7aaadf13399b4e6075c2a9617c7 100644
|
||||
--- a/fpdfsdk/formfiller/cffl_listbox.cpp
|
||||
+++ b/fpdfsdk/formfiller/cffl_listbox.cpp
|
||||
@@ -116,11 +116,18 @@ void CFFL_ListBox::SaveData(const CPDFSDK_PageView* pPageView) {
|
||||
}
|
||||
if (m_pWidget->GetFieldFlags() & pdfium::form_flags::kChoiceMultiSelect) {
|
||||
for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) {
|
||||
- if (pListBox->IsItemSelected(i))
|
||||
+ if (pListBox->IsItemSelected(i)) {
|
||||
m_pWidget->SetOptionSelection(i);
|
||||
+ if (!observed_box) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
} else {
|
||||
m_pWidget->SetOptionSelection(pListBox->GetCurSel());
|
||||
+ if (!observed_box) {
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
ObservedPtr<CPDFSDK_Widget> observed_widget(m_pWidget.Get());
|
||||
ObservedPtr<CFFL_ListBox> observed_this(this);
|
||||
2
patches/skia/.patches
Normal file
2
patches/skia/.patches
Normal file
@@ -0,0 +1,2 @@
|
||||
enforce_program_stack_limits_on_function_parameters.patch
|
||||
enforce_size_limits_on_struct_and_array_declarations.patch
|
||||
@@ -0,0 +1,152 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: John Stiles <johnstiles@google.com>
|
||||
Date: Wed, 12 Apr 2023 14:56:54 -0400
|
||||
Subject: Enforce program stack limits on function parameters.
|
||||
|
||||
M108 merge issues:
|
||||
resources/sksl/BUILD.bazel:
|
||||
File doesn't exist in M108, tests are added manually to gn/sksl_tests.gni.
|
||||
|
||||
gn/sksl_tests.gni:
|
||||
Conflicting rts entries
|
||||
|
||||
src/sksl/ir/SkSLFunctionDefinition.cpp:
|
||||
- Conflicting includes
|
||||
- visitStatement():
|
||||
Conflicting declarations of const Variable* var (const Variable& var
|
||||
on 108)
|
||||
|
||||
Previously, a function's parameter list did not count against its
|
||||
stack size limit.
|
||||
|
||||
Bug: chromium:1432603
|
||||
Change-Id: If49dce98f3155f3144a766c26b5a3a39401ce1b2
|
||||
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/670236
|
||||
Auto-Submit: John Stiles <johnstiles@google.com>
|
||||
Commit-Queue: John Stiles <johnstiles@google.com>
|
||||
(cherry picked from commit 4dc748f14c6650cb45c7086a39af1760bfda41d2)
|
||||
|
||||
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni
|
||||
index 2f0100b8b617d3d101660a34c183bcf51a39c11c..6af1a84c6ef8a8853b259815eb17e02cb5027541 100644
|
||||
--- a/gn/sksl_tests.gni
|
||||
+++ b/gn/sksl_tests.gni
|
||||
@@ -283,6 +283,7 @@ sksl_error_tests = [
|
||||
"/sksl/errors/VoidInStruct.rts",
|
||||
"/sksl/errors/VoidVariable.rts",
|
||||
"/sksl/errors/WhileTypeMismatch.sksl",
|
||||
+ "/sksl/errors/ProgramTooLarge_Parameters.rts",
|
||||
]
|
||||
|
||||
sksl_glsl_tests = [
|
||||
diff --git a/resources/sksl/errors/ProgramTooLarge_Parameters.rts b/resources/sksl/errors/ProgramTooLarge_Parameters.rts
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..cced977be40620ffc3b145837bd5ffe16b40295b
|
||||
--- /dev/null
|
||||
+++ b/resources/sksl/errors/ProgramTooLarge_Parameters.rts
|
||||
@@ -0,0 +1,14 @@
|
||||
+struct S {
|
||||
+ half4 ah4[1];
|
||||
+ half ah[99999];
|
||||
+ half4 h4;
|
||||
+ half h;
|
||||
+};
|
||||
+
|
||||
+void func(int small,
|
||||
+ S big_chungus,
|
||||
+ S no_report /*we don't need to report overflows past the first*/) {}
|
||||
+
|
||||
+/*%%*
|
||||
+variable 'big_chungus' exceeds the stack size limit
|
||||
+*%%*/
|
||||
diff --git a/src/sksl/ir/SkSLFunctionDefinition.cpp b/src/sksl/ir/SkSLFunctionDefinition.cpp
|
||||
index 45695a1effe1f98d4185aa4c17d6add29281044c..adfe62dfd22e2810c316cd806aaef16a05aca4ad 100644
|
||||
--- a/src/sksl/ir/SkSLFunctionDefinition.cpp
|
||||
+++ b/src/sksl/ir/SkSLFunctionDefinition.cpp
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <forward_list>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
+#include <vector>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@@ -88,9 +89,29 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
|
||||
bool builtin) {
|
||||
class Finalizer : public ProgramWriter {
|
||||
public:
|
||||
- Finalizer(const Context& context, const FunctionDeclaration& function)
|
||||
+ Finalizer(const Context& context, const FunctionDeclaration& function, Position pos)
|
||||
: fContext(context)
|
||||
- , fFunction(function) {}
|
||||
+ , fFunction(function) {
|
||||
+ // Function parameters count as local variables.
|
||||
+ for (const Variable* var : function.parameters()) {
|
||||
+ this->addLocalVariable(var, pos);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ void addLocalVariable(const Variable* var, Position pos) {
|
||||
+ // We count the number of slots used, but don't consider the precision of the base type.
|
||||
+ // In practice, this reflects what GPUs actually do pretty well. (i.e., RelaxedPrecision
|
||||
+ // math doesn't mean your variable takes less space.) We also don't attempt to reclaim
|
||||
+ // slots at the end of a Block.
|
||||
+ size_t prevSlotsUsed = fSlotsUsed;
|
||||
+ fSlotsUsed = SkSafeMath::Add(fSlotsUsed, var->type().slotCount());
|
||||
+ // To avoid overzealous error reporting, only trigger the error at the first
|
||||
+ // place where the stack limit is exceeded.
|
||||
+ if (prevSlotsUsed < kVariableSlotLimit && fSlotsUsed >= kVariableSlotLimit) {
|
||||
+ fContext.fErrors->error(pos, "variable '" + std::string(var->name()) +
|
||||
+ "' exceeds the stack size limit");
|
||||
+ }
|
||||
+ }
|
||||
|
||||
~Finalizer() override {
|
||||
SkASSERT(fBreakableLevel == 0);
|
||||
@@ -109,24 +130,12 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
|
||||
bool visitStatement(Statement& stmt) override {
|
||||
switch (stmt.kind()) {
|
||||
case Statement::Kind::kVarDeclaration: {
|
||||
- // We count the number of slots used, but don't consider the precision of the
|
||||
- // base type. In practice, this reflects what GPUs really do pretty well.
|
||||
- // (i.e., RelaxedPrecision math doesn't mean your variable takes less space.)
|
||||
- // We also don't attempt to reclaim slots at the end of a Block.
|
||||
- size_t prevSlotsUsed = fSlotsUsed;
|
||||
const Variable& var = stmt.as<VarDeclaration>().var();
|
||||
if (var.type().isOrContainsUnsizedArray()) {
|
||||
fContext.fErrors->error(stmt.fPosition,
|
||||
"unsized arrays are not permitted here");
|
||||
- break;
|
||||
- }
|
||||
- fSlotsUsed = SkSafeMath::Add(fSlotsUsed, var.type().slotCount());
|
||||
- // To avoid overzealous error reporting, only trigger the error at the first
|
||||
- // place where the stack limit is exceeded.
|
||||
- if (prevSlotsUsed < kVariableSlotLimit && fSlotsUsed >= kVariableSlotLimit) {
|
||||
- fContext.fErrors->error(stmt.fPosition,
|
||||
- "variable '" + std::string(var.name()) +
|
||||
- "' exceeds the stack size limit");
|
||||
+ } else {
|
||||
+ this->addLocalVariable(&var, stmt.fPosition);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -219,7 +228,7 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
|
||||
using INHERITED = ProgramWriter;
|
||||
};
|
||||
|
||||
- Finalizer(context, function).visitStatement(*body);
|
||||
+ Finalizer(context, function, pos).visitStatement(*body);
|
||||
if (function.isMain() && ProgramConfig::IsVertex(context.fConfig->fKind)) {
|
||||
append_rtadjust_fixup_to_vertex_main(context, function, body->as<Block>());
|
||||
}
|
||||
diff --git a/tests/sksl/errors/ProgramTooLarge_Parameters.glsl b/tests/sksl/errors/ProgramTooLarge_Parameters.glsl
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d92c3256e82d52115621cf96d6dba99f62cdd945
|
||||
--- /dev/null
|
||||
+++ b/tests/sksl/errors/ProgramTooLarge_Parameters.glsl
|
||||
@@ -0,0 +1,6 @@
|
||||
+### Compilation failed:
|
||||
+
|
||||
+error: 10: variable 'big_chungus' exceeds the stack size limit
|
||||
+ S no_report /*we don't need to report overflows past the first*/) {}
|
||||
+ ^^
|
||||
+1 error
|
||||
@@ -0,0 +1,291 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: John Stiles <johnstiles@google.com>
|
||||
Date: Thu, 13 Apr 2023 17:58:24 -0400
|
||||
Subject: Enforce size limits on struct and array declarations.
|
||||
|
||||
M108 merge issues:
|
||||
resources/sksl/BUILD.bazel:
|
||||
File doesn't exist in M108, tests are added manually to gn/sksl_tests.gni.
|
||||
|
||||
gn/sksl_tests.gni:
|
||||
Conflicting rts entries
|
||||
|
||||
tests/sksl/shared/Ossfuzz37900.*
|
||||
Not present in 108, skipped.
|
||||
|
||||
src/sksl/ir/SkSLType.cpp:
|
||||
- Conflicting includes
|
||||
- MakeStructType():
|
||||
- Conflicting function signature
|
||||
- context isn't a parameter, used ThreadContext::Context() directly.
|
||||
|
||||
This improves error reporting by more clearly attaching the error
|
||||
message to the oversized type.
|
||||
|
||||
Bug: chromium:1432603
|
||||
Change-Id: I26511f08aff22072cf4913abf7be2c49940a732c
|
||||
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/671377
|
||||
Commit-Queue: John Stiles <johnstiles@google.com>
|
||||
(cherry picked from commit 1cbd33ecd73523f8d4bf88e9c5576303b39e5556)
|
||||
|
||||
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni
|
||||
index 6af1a84c6ef8a8853b259815eb17e02cb5027541..20c2026322bf6f6ae6d19d4f649ddb0f5ed048ed 100644
|
||||
--- a/gn/sksl_tests.gni
|
||||
+++ b/gn/sksl_tests.gni
|
||||
@@ -284,6 +284,7 @@ sksl_error_tests = [
|
||||
"/sksl/errors/VoidVariable.rts",
|
||||
"/sksl/errors/WhileTypeMismatch.sksl",
|
||||
"/sksl/errors/ProgramTooLarge_Parameters.rts",
|
||||
+ "/sksl/errors/ProgramTooLarge_Struct.rts",
|
||||
]
|
||||
|
||||
sksl_glsl_tests = [
|
||||
diff --git a/resources/sksl/errors/ProgramTooLarge_Globals.rts b/resources/sksl/errors/ProgramTooLarge_Globals.rts
|
||||
index af0ad17ce7a591d99a9cbb062278b99046bd2fe8..ee2556bb1a99404ebe53641064bceff3a553ea9a 100644
|
||||
--- a/resources/sksl/errors/ProgramTooLarge_Globals.rts
|
||||
+++ b/resources/sksl/errors/ProgramTooLarge_Globals.rts
|
||||
@@ -6,11 +6,10 @@ struct S {
|
||||
};
|
||||
|
||||
int small;
|
||||
-S medium;
|
||||
-S large[10];
|
||||
-S extra_large[100];
|
||||
-S xxl[50000];
|
||||
-
|
||||
+S medium[30];
|
||||
+S large[50];
|
||||
+S extra_large[70];
|
||||
+S xxl[90];
|
||||
|
||||
/*%%*
|
||||
global variable 'extra_large' exceeds the size limit
|
||||
diff --git a/resources/sksl/errors/ProgramTooLarge_Parameters.rts b/resources/sksl/errors/ProgramTooLarge_Parameters.rts
|
||||
index cced977be40620ffc3b145837bd5ffe16b40295b..4e15ebd53e683f2078efed6771202e61d7b7bdc5 100644
|
||||
--- a/resources/sksl/errors/ProgramTooLarge_Parameters.rts
|
||||
+++ b/resources/sksl/errors/ProgramTooLarge_Parameters.rts
|
||||
@@ -1,11 +1,14 @@
|
||||
struct S {
|
||||
half4 ah4[1];
|
||||
- half ah[99999];
|
||||
+ half ah[99990];
|
||||
half4 h4;
|
||||
half h;
|
||||
};
|
||||
|
||||
void func(int small,
|
||||
+ int parameters,
|
||||
+ int are,
|
||||
+ int allowed,
|
||||
S big_chungus,
|
||||
S no_report /*we don't need to report overflows past the first*/) {}
|
||||
|
||||
diff --git a/resources/sksl/errors/ProgramTooLarge_Stack.rts b/resources/sksl/errors/ProgramTooLarge_Stack.rts
|
||||
index 4f004368a17b79d960e5cc142db35d82fb627cbd..a8f5217359ad9dab1fdcfcaac862938c1d205f0a 100644
|
||||
--- a/resources/sksl/errors/ProgramTooLarge_Stack.rts
|
||||
+++ b/resources/sksl/errors/ProgramTooLarge_Stack.rts
|
||||
@@ -1,12 +1,12 @@
|
||||
struct S {
|
||||
half4 ah4[1];
|
||||
- half ah[99999];
|
||||
+ half ah[99990];
|
||||
half4 h4;
|
||||
half h;
|
||||
};
|
||||
|
||||
void func() {
|
||||
- int small;
|
||||
+ int small, variables, are, allowed;
|
||||
S big_chungus;
|
||||
S no_report; // we don't need to report overflows past the first
|
||||
}
|
||||
diff --git a/resources/sksl/errors/ProgramTooLarge_Struct.rts b/resources/sksl/errors/ProgramTooLarge_Struct.rts
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..690e1d37311b5d0745d20d71b48738a69c5c3ecb
|
||||
--- /dev/null
|
||||
+++ b/resources/sksl/errors/ProgramTooLarge_Struct.rts
|
||||
@@ -0,0 +1,24 @@
|
||||
+struct A {
|
||||
+ int4 big[25001]; // 100,004 slots
|
||||
+};
|
||||
+
|
||||
+struct B {
|
||||
+ int4 a[12500]; // 50,000 slots
|
||||
+ int b[49999]; // 99,999 slots
|
||||
+ int c; // 100,000 slots
|
||||
+};
|
||||
+
|
||||
+struct C {
|
||||
+ int a[99999]; // 99,999 slots (safe)
|
||||
+};
|
||||
+
|
||||
+struct D {
|
||||
+ C a; // 99,999 slots
|
||||
+ int b; // 100,000 slots
|
||||
+};
|
||||
+
|
||||
+/*%%*
|
||||
+array size is too large
|
||||
+struct is too large
|
||||
+struct is too large
|
||||
+*%%*/
|
||||
diff --git a/src/sksl/dsl/DSLType.cpp b/src/sksl/dsl/DSLType.cpp
|
||||
index 5648c51c92b61430d31497f71cea73ff19ef8a97..aacdfb000527105ea4fff8b6dc3ba2c38d0e33f4 100644
|
||||
--- a/src/sksl/dsl/DSLType.cpp
|
||||
+++ b/src/sksl/dsl/DSLType.cpp
|
||||
@@ -266,7 +266,7 @@ DSLExpression DSLType::Construct(DSLType type, SkSpan<DSLExpression> argArray) {
|
||||
|
||||
DSLType Array(const DSLType& base, int count, Position pos) {
|
||||
count = base.skslType().convertArraySize(ThreadContext::Context(), pos,
|
||||
- DSLExpression(count, pos).release());
|
||||
+ DSLExpression(count, pos).release());
|
||||
if (!count) {
|
||||
return DSLType(kPoison_Type);
|
||||
}
|
||||
@@ -278,7 +278,7 @@ DSLType UnsizedArray(const DSLType& base, Position pos) {
|
||||
return DSLType(kPoison_Type);
|
||||
}
|
||||
return ThreadContext::SymbolTable()->addArrayDimension(&base.skslType(),
|
||||
- SkSL::Type::kUnsizedArray);
|
||||
+ SkSL::Type::kUnsizedArray);
|
||||
}
|
||||
|
||||
DSLType Struct(std::string_view name, SkSpan<DSLField> fields, Position pos) {
|
||||
diff --git a/src/sksl/ir/SkSLType.cpp b/src/sksl/ir/SkSLType.cpp
|
||||
index 04c1946509ee263ca1c591cab6353765a84a28d0..c474db149f5e4844cc873b1746a0b103f209390f 100644
|
||||
--- a/src/sksl/ir/SkSLType.cpp
|
||||
+++ b/src/sksl/ir/SkSLType.cpp
|
||||
@@ -12,10 +12,12 @@
|
||||
#include "include/private/SkTFitsIn.h"
|
||||
#include "include/sksl/SkSLErrorReporter.h"
|
||||
#include "src/core/SkMathPriv.h"
|
||||
+#include "src/core/SkSafeMath.h"
|
||||
#include "src/sksl/SkSLBuiltinTypes.h"
|
||||
#include "src/sksl/SkSLConstantFolder.h"
|
||||
#include "src/sksl/SkSLContext.h"
|
||||
#include "src/sksl/SkSLProgramSettings.h"
|
||||
+#include "src/sksl/SkSLThreadContext.h"
|
||||
#include "src/sksl/ir/SkSLConstructorArrayCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorCompoundCast.h"
|
||||
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
|
||||
@@ -648,6 +650,17 @@ std::unique_ptr<Type> Type::MakeScalarType(std::string_view name, const char* ab
|
||||
|
||||
std::unique_ptr<Type> Type::MakeStructType(Position pos, std::string_view name,
|
||||
std::vector<Field> fields, bool interfaceBlock) {
|
||||
+ size_t slots = 0;
|
||||
+ for (const Field& field : fields) {
|
||||
+ if (field.fType->isUnsizedArray()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ slots = SkSafeMath::Add(slots, field.fType->slotCount());
|
||||
+ if (slots >= kVariableSlotLimit) {
|
||||
+ ThreadContext::Context().fErrors->error(pos, "struct is too large");
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
return std::make_unique<StructType>(pos, name, std::move(fields), interfaceBlock);
|
||||
}
|
||||
|
||||
@@ -1120,8 +1133,9 @@ bool Type::checkIfUsableInArray(const Context& context, Position arrayPos) const
|
||||
return true;
|
||||
}
|
||||
|
||||
-SKSL_INT Type::convertArraySize(const Context& context, Position arrayPos,
|
||||
- std::unique_ptr<Expression> size) const {
|
||||
+SKSL_INT Type::convertArraySize(const Context& context,
|
||||
+ Position arrayPos,
|
||||
+ std::unique_ptr<Expression> size) const {
|
||||
size = context.fTypes.fInt->coerceExpression(std::move(size), context);
|
||||
if (!size) {
|
||||
return 0;
|
||||
@@ -1138,7 +1152,7 @@ SKSL_INT Type::convertArraySize(const Context& context, Position arrayPos,
|
||||
context.fErrors->error(size->fPosition, "array size must be positive");
|
||||
return 0;
|
||||
}
|
||||
- if (!SkTFitsIn<int32_t>(count)) {
|
||||
+ if (SkSafeMath::Mul(this->slotCount(), count) > kVariableSlotLimit) {
|
||||
context.fErrors->error(size->fPosition, "array size is too large");
|
||||
return 0;
|
||||
}
|
||||
diff --git a/tests/sksl/errors/ProgramTooLarge_Globals.glsl b/tests/sksl/errors/ProgramTooLarge_Globals.glsl
|
||||
index 406949ad38ecb6ea80bbba505cdf5ad9346c9446..ccb7706c3a66a7b41fd5c6444ea1e9967f314282 100644
|
||||
--- a/tests/sksl/errors/ProgramTooLarge_Globals.glsl
|
||||
+++ b/tests/sksl/errors/ProgramTooLarge_Globals.glsl
|
||||
@@ -1,6 +1,6 @@
|
||||
### Compilation failed:
|
||||
|
||||
error: 11: global variable 'extra_large' exceeds the size limit
|
||||
-S extra_large[100];
|
||||
-^^^^^^^^^^^^^^^^^^
|
||||
+S extra_large[70];
|
||||
+^^^^^^^^^^^^^^^^^
|
||||
1 error
|
||||
diff --git a/tests/sksl/errors/ProgramTooLarge_Parameters.glsl b/tests/sksl/errors/ProgramTooLarge_Parameters.glsl
|
||||
index d92c3256e82d52115621cf96d6dba99f62cdd945..3ece6f379c8ab64dd846d856301217f95eb3e7ff 100644
|
||||
--- a/tests/sksl/errors/ProgramTooLarge_Parameters.glsl
|
||||
+++ b/tests/sksl/errors/ProgramTooLarge_Parameters.glsl
|
||||
@@ -1,6 +1,6 @@
|
||||
### Compilation failed:
|
||||
|
||||
-error: 10: variable 'big_chungus' exceeds the stack size limit
|
||||
+error: 13: variable 'big_chungus' exceeds the stack size limit
|
||||
S no_report /*we don't need to report overflows past the first*/) {}
|
||||
^^
|
||||
1 error
|
||||
diff --git a/tests/sksl/errors/ProgramTooLarge_Struct.glsl b/tests/sksl/errors/ProgramTooLarge_Struct.glsl
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ebe47f700dfad807fbd7b774f5f2ce851ff28e64
|
||||
--- /dev/null
|
||||
+++ b/tests/sksl/errors/ProgramTooLarge_Struct.glsl
|
||||
@@ -0,0 +1,12 @@
|
||||
+### Compilation failed:
|
||||
+
|
||||
+error: 2: array size is too large
|
||||
+ int4 big[25001]; // 100,004 slots
|
||||
+ ^^^^^^^^^^^^^^^
|
||||
+error: 5: struct is too large
|
||||
+struct B {
|
||||
+^^^^^^^^^^...
|
||||
+error: 15: struct is too large
|
||||
+struct D {
|
||||
+^^^^^^^^^^...
|
||||
+3 errors
|
||||
diff --git a/tests/sksl/shared/Ossfuzz37900.asm.frag b/tests/sksl/shared/Ossfuzz37900.asm.frag
|
||||
index 9751821fc01e704a2f2851c52d1e9489b204c4f7..5fb2b3c5fd467857b653f617976cc3b8af3a15fb 100644
|
||||
--- a/tests/sksl/shared/Ossfuzz37900.asm.frag
|
||||
+++ b/tests/sksl/shared/Ossfuzz37900.asm.frag
|
||||
@@ -1,6 +1,6 @@
|
||||
### Compilation failed:
|
||||
|
||||
-error: 2: variable 'a' exceeds the stack size limit
|
||||
+error: 2: array size is too large
|
||||
int[2147483646] a, b=a, c=a, d=a, e=a, f=a, g=a, h=a, i=a, j=a, k=a;
|
||||
- ^^^^^^^^^^^^^^^^^
|
||||
+ ^^^^^^^^^^^^^^^
|
||||
1 error
|
||||
diff --git a/tests/sksl/shared/Ossfuzz37900.glsl b/tests/sksl/shared/Ossfuzz37900.glsl
|
||||
index 9751821fc01e704a2f2851c52d1e9489b204c4f7..5fb2b3c5fd467857b653f617976cc3b8af3a15fb 100644
|
||||
--- a/tests/sksl/shared/Ossfuzz37900.glsl
|
||||
+++ b/tests/sksl/shared/Ossfuzz37900.glsl
|
||||
@@ -1,6 +1,6 @@
|
||||
### Compilation failed:
|
||||
|
||||
-error: 2: variable 'a' exceeds the stack size limit
|
||||
+error: 2: array size is too large
|
||||
int[2147483646] a, b=a, c=a, d=a, e=a, f=a, g=a, h=a, i=a, j=a, k=a;
|
||||
- ^^^^^^^^^^^^^^^^^
|
||||
+ ^^^^^^^^^^^^^^^
|
||||
1 error
|
||||
diff --git a/tests/sksl/shared/Ossfuzz37900.metal b/tests/sksl/shared/Ossfuzz37900.metal
|
||||
index 9751821fc01e704a2f2851c52d1e9489b204c4f7..5fb2b3c5fd467857b653f617976cc3b8af3a15fb 100644
|
||||
--- a/tests/sksl/shared/Ossfuzz37900.metal
|
||||
+++ b/tests/sksl/shared/Ossfuzz37900.metal
|
||||
@@ -1,6 +1,6 @@
|
||||
### Compilation failed:
|
||||
|
||||
-error: 2: variable 'a' exceeds the stack size limit
|
||||
+error: 2: array size is too large
|
||||
int[2147483646] a, b=a, c=a, d=a, e=a, f=a, g=a, h=a, i=a, j=a, k=a;
|
||||
- ^^^^^^^^^^^^^^^^^
|
||||
+ ^^^^^^^^^^^^^^^
|
||||
1 error
|
||||
@@ -10,3 +10,18 @@ revert_runtime_dhceck_terminating_exception_in_microtasks.patch
|
||||
chore_disable_is_execution_terminating_dcheck.patch
|
||||
force_cppheapcreateparams_to_be_noncopyable.patch
|
||||
cherry-pick-e17eee4894be.patch
|
||||
cherry-pick-aeceeb2187a6.patch
|
||||
cherry-pick-546e00df97ac.patch
|
||||
cherry-pick-f6ddbf42b1ea.patch
|
||||
cherry-pick-c605df24af3c.patch
|
||||
cherry-pick-f4b66ae451c2.patch
|
||||
cherry-pick-3b0607d14060.patch
|
||||
cherry-pick-9c6dfc733fce.patch
|
||||
merged_ic_fix_store_handler_selection_for_arguments_objects.patch
|
||||
cherry-pick-73af1a19a901.patch
|
||||
merged_regexp_fix_clobbered_register_in_global_unicode_special.patch
|
||||
m108-lts_api_fix_v8_object_setaccessorproperty.patch
|
||||
cherry-pick-2e76270cf65e.patch
|
||||
utf-8_q_shared-struct_20fix_20using_20shared_20objects_20as.patch
|
||||
merged_runtime_set_instance_prototypes_directly_on_maps.patch
|
||||
merged_compiler_stackcheck_can_have_side_effects.patch
|
||||
|
||||
45
patches/v8/cherry-pick-2e76270cf65e.patch
Normal file
45
patches/v8/cherry-pick-2e76270cf65e.patch
Normal file
@@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shu-yu Guo <syg@chromium.org>
|
||||
Date: Mon, 5 Jun 2023 16:05:52 -0700
|
||||
Subject: Merged: Check for encoding when appending in string builder
|
||||
|
||||
Fixed: chromium:1450114
|
||||
(cherry picked from commit a7e2bef27b72f187a7dcdf95714df686f56d9e0b)
|
||||
|
||||
Change-Id: I5838383b6b12d137e84c8a36863ef88000e85c76
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4604652
|
||||
Reviewed-by: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.4@{#41}
|
||||
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
|
||||
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
|
||||
|
||||
diff --git a/src/strings/string-builder.cc b/src/strings/string-builder.cc
|
||||
index 9d1e3a95746b47b99c15f18ec593549d79e10b8c..c7e98e55763aba2d64f4070e25759489f850f589 100644
|
||||
--- a/src/strings/string-builder.cc
|
||||
+++ b/src/strings/string-builder.cc
|
||||
@@ -306,12 +306,21 @@ bool IncrementalStringBuilder::CanAppendByCopy(Handle<String> string) {
|
||||
void IncrementalStringBuilder::AppendStringByCopy(Handle<String> string) {
|
||||
DCHECK(CanAppendByCopy(string));
|
||||
|
||||
- Handle<SeqOneByteString> part =
|
||||
- Handle<SeqOneByteString>::cast(current_part());
|
||||
{
|
||||
DisallowGarbageCollection no_gc;
|
||||
- String::WriteToFlat(*string, part->GetChars(no_gc) + current_index_, 0,
|
||||
- string->length());
|
||||
+ if (encoding_ == String::ONE_BYTE_ENCODING) {
|
||||
+ String::WriteToFlat(
|
||||
+ *string,
|
||||
+ Handle<SeqOneByteString>::cast(current_part())->GetChars(no_gc) +
|
||||
+ current_index_,
|
||||
+ 0, string->length());
|
||||
+ } else {
|
||||
+ String::WriteToFlat(
|
||||
+ *string,
|
||||
+ Handle<SeqTwoByteString>::cast(current_part())->GetChars(no_gc) +
|
||||
+ current_index_,
|
||||
+ 0, string->length());
|
||||
+ }
|
||||
}
|
||||
current_index_ += string->length();
|
||||
DCHECK(current_index_ <= part_length_);
|
||||
186
patches/v8/cherry-pick-3b0607d14060.patch
Normal file
186
patches/v8/cherry-pick-3b0607d14060.patch
Normal file
@@ -0,0 +1,186 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Sheludko <ishell@chromium.org>
|
||||
Date: Wed, 17 May 2023 13:47:36 +0200
|
||||
Subject: Merged: [runtime] Remove redundant calls to GetPropertyAttributes
|
||||
|
||||
... when defining properties in favour of CheckIfCanDefine.
|
||||
|
||||
Drive-by: move JSReceiver::CheckIfCanDefine to
|
||||
JSObject::CheckIfCanDefineAsConfigurable and fix handling of
|
||||
absent properties.
|
||||
|
||||
Bug: chromium:1443452
|
||||
(cherry picked from commit e98baa3526426c0219bb0474028ca301b8bd0677)
|
||||
|
||||
Change-Id: Ia1fd617778be608accee99dcee37f7d1ce3460b8
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4545762
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.4@{#22}
|
||||
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
|
||||
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
|
||||
|
||||
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
|
||||
index fff21e90bad3451e2d942ec327cb02f394fecc46..32039f9888d3cb54699c6aefd0bcc3573044995e 100644
|
||||
--- a/src/ic/ic.cc
|
||||
+++ b/src/ic/ic.cc
|
||||
@@ -1812,14 +1812,14 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
|
||||
// been thrown if the private field already exists in the object.
|
||||
if (IsAnyDefineOwn() && !name->IsPrivateName() && !object->IsJSProxy() &&
|
||||
!Handle<JSObject>::cast(object)->HasNamedInterceptor()) {
|
||||
- Maybe<bool> can_define = JSReceiver::CheckIfCanDefine(
|
||||
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
|
||||
isolate(), &it, value, Nothing<ShouldThrow>());
|
||||
MAYBE_RETURN_NULL(can_define);
|
||||
if (!can_define.FromJust()) {
|
||||
return isolate()->factory()->undefined_value();
|
||||
}
|
||||
- // Restart the lookup iterator updated by CheckIfCanDefine() for
|
||||
- // UpdateCaches() to handle access checks.
|
||||
+ // Restart the lookup iterator updated by CheckIfCanDefineAsConfigurable()
|
||||
+ // for UpdateCaches() to handle access checks.
|
||||
if (use_ic && object->IsAccessCheckNeeded()) {
|
||||
it.Restart();
|
||||
}
|
||||
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
|
||||
index 15356b6c58d2f7355fa8b0dce4d3ea779a2884f9..e86fdec6a57e08bbcd229b7866f22ba3441f608c 100644
|
||||
--- a/src/objects/js-objects.cc
|
||||
+++ b/src/objects/js-objects.cc
|
||||
@@ -243,27 +243,6 @@ Maybe<bool> JSReceiver::CheckPrivateNameStore(LookupIterator* it,
|
||||
return Just(true);
|
||||
}
|
||||
|
||||
-// static
|
||||
-Maybe<bool> JSReceiver::CheckIfCanDefine(Isolate* isolate, LookupIterator* it,
|
||||
- Handle<Object> value,
|
||||
- Maybe<ShouldThrow> should_throw) {
|
||||
- if (it->IsFound()) {
|
||||
- Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
|
||||
- MAYBE_RETURN(attributes, Nothing<bool>());
|
||||
- if ((attributes.FromJust() & DONT_DELETE) != 0) {
|
||||
- RETURN_FAILURE(
|
||||
- isolate, GetShouldThrow(isolate, should_throw),
|
||||
- NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
|
||||
- }
|
||||
- } else if (!JSObject::IsExtensible(
|
||||
- Handle<JSObject>::cast(it->GetReceiver()))) {
|
||||
- RETURN_FAILURE(
|
||||
- isolate, GetShouldThrow(isolate, should_throw),
|
||||
- NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
|
||||
- }
|
||||
- return Just(true);
|
||||
-}
|
||||
-
|
||||
namespace {
|
||||
|
||||
bool HasExcludedProperty(
|
||||
@@ -3639,7 +3618,7 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
|
||||
|
||||
if (semantics == EnforceDefineSemantics::kDefine) {
|
||||
it->Restart();
|
||||
- Maybe<bool> can_define = JSReceiver::CheckIfCanDefine(
|
||||
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
|
||||
it->isolate(), it, value, should_throw);
|
||||
if (can_define.IsNothing() || !can_define.FromJust()) {
|
||||
return can_define;
|
||||
@@ -4068,17 +4047,16 @@ Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
|
||||
Handle<Object> value,
|
||||
Maybe<ShouldThrow> should_throw) {
|
||||
DCHECK(it->GetReceiver()->IsJSObject());
|
||||
- MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>());
|
||||
Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
|
||||
Isolate* isolate = receiver->GetIsolate();
|
||||
|
||||
- Maybe<bool> can_define =
|
||||
- JSReceiver::CheckIfCanDefine(isolate, it, value, should_throw);
|
||||
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
|
||||
+ isolate, it, value, should_throw);
|
||||
if (can_define.IsNothing() || !can_define.FromJust()) {
|
||||
return can_define;
|
||||
}
|
||||
|
||||
- RETURN_ON_EXCEPTION_VALUE(it->isolate(),
|
||||
+ RETURN_ON_EXCEPTION_VALUE(isolate,
|
||||
DefineOwnPropertyIgnoreAttributes(it, value, NONE),
|
||||
Nothing<bool>());
|
||||
|
||||
@@ -4707,19 +4685,42 @@ MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
|
||||
return it.factory()->undefined_value();
|
||||
}
|
||||
|
||||
- CHECK(GetPropertyAttributes(&it).IsJust());
|
||||
-
|
||||
- // ES5 forbids turning a property into an accessor if it's not
|
||||
- // configurable. See 8.6.1 (Table 5).
|
||||
- if (it.IsFound() && !it.IsConfigurable()) {
|
||||
- return it.factory()->undefined_value();
|
||||
- }
|
||||
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
|
||||
+ isolate, &it, info, Nothing<ShouldThrow>());
|
||||
+ MAYBE_RETURN_NULL(can_define);
|
||||
+ if (!can_define.FromJust()) return it.factory()->undefined_value();
|
||||
|
||||
it.TransitionToAccessorPair(info, attributes);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
+// static
|
||||
+Maybe<bool> JSObject::CheckIfCanDefineAsConfigurable(
|
||||
+ Isolate* isolate, LookupIterator* it, Handle<Object> value,
|
||||
+ Maybe<ShouldThrow> should_throw) {
|
||||
+ DCHECK(it->GetReceiver()->IsJSObject());
|
||||
+ if (it->IsFound()) {
|
||||
+ Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
|
||||
+ MAYBE_RETURN(attributes, Nothing<bool>());
|
||||
+ if (attributes.FromJust() != ABSENT) {
|
||||
+ if ((attributes.FromJust() & DONT_DELETE) != 0) {
|
||||
+ RETURN_FAILURE(
|
||||
+ isolate, GetShouldThrow(isolate, should_throw),
|
||||
+ NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
|
||||
+ }
|
||||
+ return Just(true);
|
||||
+ }
|
||||
+ // Property does not exist, check object extensibility.
|
||||
+ }
|
||||
+ if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) {
|
||||
+ RETURN_FAILURE(
|
||||
+ isolate, GetShouldThrow(isolate, should_throw),
|
||||
+ NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
|
||||
+ }
|
||||
+ return Just(true);
|
||||
+}
|
||||
+
|
||||
Object JSObject::SlowReverseLookup(Object value) {
|
||||
if (HasFastProperties()) {
|
||||
DescriptorArray descs = map().instance_descriptors();
|
||||
diff --git a/src/objects/js-objects.h b/src/objects/js-objects.h
|
||||
index 06489c2b7bae61ecadbd8f020060e86ef50e11b6..f663af6ed8a445f8ef30a67bac176a1abe6c85f8 100644
|
||||
--- a/src/objects/js-objects.h
|
||||
+++ b/src/objects/js-objects.h
|
||||
@@ -167,12 +167,6 @@ class JSReceiver : public TorqueGeneratedJSReceiver<JSReceiver, HeapObject> {
|
||||
V8_WARN_UNUSED_RESULT static Maybe<bool> CheckPrivateNameStore(
|
||||
LookupIterator* it, bool is_define);
|
||||
|
||||
- // Check if a data property can be created on the object. It will fail with
|
||||
- // an error when it cannot.
|
||||
- V8_WARN_UNUSED_RESULT static Maybe<bool> CheckIfCanDefine(
|
||||
- Isolate* isolate, LookupIterator* it, Handle<Object> value,
|
||||
- Maybe<ShouldThrow> should_throw);
|
||||
-
|
||||
// ES6 7.3.4 (when passed kDontThrow)
|
||||
V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
|
||||
Isolate* isolate, Handle<JSReceiver> object, Handle<Name> key,
|
||||
@@ -544,6 +538,12 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
|
||||
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> info,
|
||||
PropertyAttributes attributes);
|
||||
|
||||
+ // Check if a data property can be created on the object. It will fail with
|
||||
+ // an error when it cannot.
|
||||
+ V8_WARN_UNUSED_RESULT static Maybe<bool> CheckIfCanDefineAsConfigurable(
|
||||
+ Isolate* isolate, LookupIterator* it, Handle<Object> value,
|
||||
+ Maybe<ShouldThrow> should_throw);
|
||||
+
|
||||
// The result must be checked first for exceptions. If there's no exception,
|
||||
// the output parameter |done| indicates whether the interceptor has a result
|
||||
// or not.
|
||||
75
patches/v8/cherry-pick-546e00df97ac.patch
Normal file
75
patches/v8/cherry-pick-546e00df97ac.patch
Normal file
@@ -0,0 +1,75 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joyee Cheung <joyee@igalia.com>
|
||||
Date: Tue, 14 Feb 2023 00:58:04 +0100
|
||||
Subject: Merged: [ic] store slow stubs for objects with access checks in
|
||||
DefineNamedIC
|
||||
|
||||
The CheckIfCanDefine() used to check the attributes of the object
|
||||
as well as reporting to access check failure callbacks can update
|
||||
the lookup iterator, resulting in wrong store handlers being
|
||||
installed. Restart the lookup iterator in this case to make
|
||||
sure that slow handlers are installed.
|
||||
|
||||
Bug: chromium:1415249
|
||||
(cherry picked from commit da2df213bc70437ef76f47e0ab6995fa45f8014a)
|
||||
|
||||
Change-Id: I92d60af7ea798d80b1115e63b7fce8e2e8026ed9
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4290868
|
||||
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.0@{#33}
|
||||
Cr-Branched-From: 06097c6f0c5af54fd5d6965d37027efb72decd4f-refs/heads/11.0.226@{#1}
|
||||
Cr-Branched-From: 6bf3344f5d9940de1ab253f1817dcb99c641c9d3-refs/heads/main@{#84857}
|
||||
|
||||
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
|
||||
index ae1dde1a8c587dfc80a0a62e96b7bbfe6ba5eea5..fff21e90bad3451e2d942ec327cb02f394fecc46 100644
|
||||
--- a/src/ic/ic.cc
|
||||
+++ b/src/ic/ic.cc
|
||||
@@ -1818,6 +1818,11 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
|
||||
if (!can_define.FromJust()) {
|
||||
return isolate()->factory()->undefined_value();
|
||||
}
|
||||
+ // Restart the lookup iterator updated by CheckIfCanDefine() for
|
||||
+ // UpdateCaches() to handle access checks.
|
||||
+ if (use_ic && object->IsAccessCheckNeeded()) {
|
||||
+ it.Restart();
|
||||
+ }
|
||||
}
|
||||
|
||||
if (use_ic) {
|
||||
diff --git a/test/mjsunit/regress/regress-crbug-1415249.js b/test/mjsunit/regress/regress-crbug-1415249.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5715e0107a4b6e9dded9ca92c7b766c4cce0af72
|
||||
--- /dev/null
|
||||
+++ b/test/mjsunit/regress/regress-crbug-1415249.js
|
||||
@@ -0,0 +1,30 @@
|
||||
+// Copyright 2023 the V8 project authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+// Flags: --always-turbofan
|
||||
+{
|
||||
+ const realm = Realm.createAllowCrossRealmAccess();
|
||||
+ const global = Realm.global(realm);
|
||||
+ function Base() { return global; }
|
||||
+ let i = 0;
|
||||
+ class Klass extends Base {
|
||||
+ field = i++;
|
||||
+ }
|
||||
+ let a = new Klass();
|
||||
+ assertEquals(a.field, 0);
|
||||
+ a = new Klass();
|
||||
+ assertEquals(a.field, 1);
|
||||
+}
|
||||
+
|
||||
+{
|
||||
+ const realm = Realm.create();
|
||||
+ const global = Realm.global(realm);
|
||||
+ function Base() { return global; }
|
||||
+ let i = 0;
|
||||
+ class Klass extends Base {
|
||||
+ field = i++;
|
||||
+ }
|
||||
+ assertThrows(() => new Klass(), Error, /no access/);
|
||||
+ assertThrows(() => new Klass(), Error, /no access/);
|
||||
+}
|
||||
257
patches/v8/cherry-pick-73af1a19a901.patch
Normal file
257
patches/v8/cherry-pick-73af1a19a901.patch
Normal file
@@ -0,0 +1,257 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Sheludko <ishell@chromium.org>
|
||||
Date: Thu, 1 Jun 2023 10:59:39 +0200
|
||||
Subject: Merged: [lookup] Robustify LookupIterator against own lookups
|
||||
|
||||
... on non-JSReceiver objects.
|
||||
|
||||
Bug: chromium:1447430
|
||||
(cherry picked from commit 515f187ba067ee4a99fdf5198cca2c97abd342fd)
|
||||
|
||||
Change-Id: Ib9382d90ce19d6b55ee0b236dd299ded03ade04d
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4575069
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.4@{#35}
|
||||
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
|
||||
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
|
||||
|
||||
diff --git a/src/objects/lookup-inl.h b/src/objects/lookup-inl.h
|
||||
index 642d83ff070d6b631a755af78627989878f685a2..22960729c64062b9e8a4abaf6b5ed8d44ccaa2de 100644
|
||||
--- a/src/objects/lookup-inl.h
|
||||
+++ b/src/objects/lookup-inl.h
|
||||
@@ -190,7 +190,7 @@ Handle<Name> PropertyKey::GetName(Isolate* isolate) {
|
||||
}
|
||||
|
||||
Handle<Name> LookupIterator::name() const {
|
||||
- DCHECK(!IsElement(*holder_));
|
||||
+ DCHECK_IMPLIES(!holder_.is_null(), !IsElement(*holder_));
|
||||
return name_;
|
||||
}
|
||||
|
||||
@@ -281,6 +281,7 @@ void LookupIterator::UpdateProtector() {
|
||||
}
|
||||
|
||||
InternalIndex LookupIterator::descriptor_number() const {
|
||||
+ DCHECK(!holder_.is_null());
|
||||
DCHECK(!IsElement(*holder_));
|
||||
DCHECK(has_property_);
|
||||
DCHECK(holder_->HasFastProperties(isolate_));
|
||||
@@ -288,6 +289,7 @@ InternalIndex LookupIterator::descriptor_number() const {
|
||||
}
|
||||
|
||||
InternalIndex LookupIterator::dictionary_entry() const {
|
||||
+ DCHECK(!holder_.is_null());
|
||||
DCHECK(!IsElement(*holder_));
|
||||
DCHECK(has_property_);
|
||||
DCHECK(!holder_->HasFastProperties(isolate_));
|
||||
@@ -302,13 +304,14 @@ LookupIterator::Configuration LookupIterator::ComputeConfiguration(
|
||||
}
|
||||
|
||||
// static
|
||||
-Handle<JSReceiver> LookupIterator::GetRoot(Isolate* isolate,
|
||||
- Handle<Object> lookup_start_object,
|
||||
- size_t index) {
|
||||
+MaybeHandle<JSReceiver> LookupIterator::GetRoot(
|
||||
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
|
||||
+ Configuration configuration) {
|
||||
if (lookup_start_object->IsJSReceiver(isolate)) {
|
||||
return Handle<JSReceiver>::cast(lookup_start_object);
|
||||
}
|
||||
- return GetRootForNonJSReceiver(isolate, lookup_start_object, index);
|
||||
+ return GetRootForNonJSReceiver(isolate, lookup_start_object, index,
|
||||
+ configuration);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
diff --git a/src/objects/lookup.cc b/src/objects/lookup.cc
|
||||
index e08ebaff089f8ab0a1b347f9eb5befd85e3c115b..920d28ffa81798c2e5fe9e15db016501d72728c6 100644
|
||||
--- a/src/objects/lookup.cc
|
||||
+++ b/src/objects/lookup.cc
|
||||
@@ -42,27 +42,20 @@ PropertyKey::PropertyKey(Isolate* isolate, Handle<Object> key, bool* success) {
|
||||
}
|
||||
}
|
||||
|
||||
-LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
|
||||
- Handle<Name> name, Handle<Map> transition_map,
|
||||
- PropertyDetails details, bool has_property)
|
||||
- : configuration_(DEFAULT),
|
||||
- state_(TRANSITION),
|
||||
- has_property_(has_property),
|
||||
- interceptor_state_(InterceptorState::kUninitialized),
|
||||
- property_details_(details),
|
||||
- isolate_(isolate),
|
||||
- name_(name),
|
||||
- transition_(transition_map),
|
||||
- receiver_(receiver),
|
||||
- lookup_start_object_(receiver),
|
||||
- index_(kInvalidIndex) {
|
||||
- holder_ = GetRoot(isolate, lookup_start_object_);
|
||||
-}
|
||||
-
|
||||
template <bool is_element>
|
||||
void LookupIterator::Start() {
|
||||
// GetRoot might allocate if lookup_start_object_ is a string.
|
||||
- holder_ = GetRoot(isolate_, lookup_start_object_, index_);
|
||||
+ MaybeHandle<JSReceiver> maybe_holder =
|
||||
+ GetRoot(isolate_, lookup_start_object_, index_, configuration_);
|
||||
+ if (!maybe_holder.ToHandle(&holder_)) {
|
||||
+ // This is an attempt to perform an own property lookup on a non-JSReceiver
|
||||
+ // that doesn't have any properties.
|
||||
+ DCHECK(!lookup_start_object_->IsJSReceiver());
|
||||
+ DCHECK(!check_prototype_chain());
|
||||
+ has_property_ = false;
|
||||
+ state_ = NOT_FOUND;
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
{
|
||||
DisallowGarbageCollection no_gc;
|
||||
@@ -135,19 +128,27 @@ template void LookupIterator::RestartInternal<true>(InterceptorState);
|
||||
template void LookupIterator::RestartInternal<false>(InterceptorState);
|
||||
|
||||
// static
|
||||
-Handle<JSReceiver> LookupIterator::GetRootForNonJSReceiver(
|
||||
- Isolate* isolate, Handle<Object> lookup_start_object, size_t index) {
|
||||
- // Strings are the only objects with properties (only elements) directly on
|
||||
- // the wrapper. Hence we can skip generating the wrapper for all other cases.
|
||||
- if (lookup_start_object->IsString(isolate) &&
|
||||
- index <
|
||||
- static_cast<size_t>(String::cast(*lookup_start_object).length())) {
|
||||
- // TODO(verwaest): Speed this up. Perhaps use a cached wrapper on the native
|
||||
- // context, ensuring that we don't leak it into JS?
|
||||
- Handle<JSFunction> constructor = isolate->string_function();
|
||||
- Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
|
||||
- Handle<JSPrimitiveWrapper>::cast(result)->set_value(*lookup_start_object);
|
||||
- return result;
|
||||
+MaybeHandle<JSReceiver> LookupIterator::GetRootForNonJSReceiver(
|
||||
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
|
||||
+ Configuration configuration) {
|
||||
+ // Strings are the only non-JSReceiver objects with properties (only elements
|
||||
+ // and 'length') directly on the wrapper. Hence we can skip generating
|
||||
+ // the wrapper for all other cases.
|
||||
+ bool own_property_lookup = (configuration & kPrototypeChain) == 0;
|
||||
+ if (lookup_start_object->IsString(isolate)) {
|
||||
+ if (own_property_lookup ||
|
||||
+ index <
|
||||
+ static_cast<size_t>(String::cast(*lookup_start_object).length())) {
|
||||
+ // TODO(verwaest): Speed this up. Perhaps use a cached wrapper on the
|
||||
+ // native context, ensuring that we don't leak it into JS?
|
||||
+ Handle<JSFunction> constructor = isolate->string_function();
|
||||
+ Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
|
||||
+ Handle<JSPrimitiveWrapper>::cast(result)->set_value(*lookup_start_object);
|
||||
+ return result;
|
||||
+ }
|
||||
+ } else if (own_property_lookup) {
|
||||
+ // Signal that the lookup will not find anything.
|
||||
+ return {};
|
||||
}
|
||||
Handle<HeapObject> root(
|
||||
lookup_start_object->GetPrototypeChainRootMap(isolate).prototype(isolate),
|
||||
@@ -903,6 +904,7 @@ Handle<Object> LookupIterator::FetchValue(
|
||||
}
|
||||
|
||||
bool LookupIterator::IsConstFieldValueEqualTo(Object value) const {
|
||||
+ DCHECK(!holder_.is_null());
|
||||
DCHECK(!IsElement(*holder_));
|
||||
DCHECK(holder_->HasFastProperties(isolate_));
|
||||
DCHECK_EQ(PropertyLocation::kField, property_details_.location());
|
||||
@@ -944,6 +946,7 @@ bool LookupIterator::IsConstFieldValueEqualTo(Object value) const {
|
||||
}
|
||||
|
||||
bool LookupIterator::IsConstDictValueEqualTo(Object value) const {
|
||||
+ DCHECK(!holder_.is_null());
|
||||
DCHECK(!IsElement(*holder_));
|
||||
DCHECK(!holder_->HasFastProperties(isolate_));
|
||||
DCHECK(!holder_->IsJSGlobalObject());
|
||||
@@ -994,6 +997,7 @@ int LookupIterator::GetAccessorIndex() const {
|
||||
|
||||
FieldIndex LookupIterator::GetFieldIndex() const {
|
||||
DCHECK(has_property_);
|
||||
+ DCHECK(!holder_.is_null());
|
||||
DCHECK(holder_->HasFastProperties(isolate_));
|
||||
DCHECK_EQ(PropertyLocation::kField, property_details_.location());
|
||||
DCHECK(!IsElement(*holder_));
|
||||
@@ -1001,6 +1005,7 @@ FieldIndex LookupIterator::GetFieldIndex() const {
|
||||
}
|
||||
|
||||
Handle<PropertyCell> LookupIterator::GetPropertyCell() const {
|
||||
+ DCHECK(!holder_.is_null());
|
||||
DCHECK(!IsElement(*holder_));
|
||||
Handle<JSGlobalObject> holder = GetHolder<JSGlobalObject>();
|
||||
return handle(holder->global_dictionary(isolate_, kAcquireLoad)
|
||||
diff --git a/src/objects/lookup.h b/src/objects/lookup.h
|
||||
index 67a8bac22e6e29df2d7df36937565e4cc0acde45..78a00d7ca0fab1ab8b2b1e49e3ffb92473b21cc9 100644
|
||||
--- a/src/objects/lookup.h
|
||||
+++ b/src/objects/lookup.h
|
||||
@@ -222,11 +222,6 @@ class V8_EXPORT_PRIVATE LookupIterator final {
|
||||
Handle<Object> lookup_start_object,
|
||||
Configuration configuration);
|
||||
|
||||
- // For |ForTransitionHandler|.
|
||||
- LookupIterator(Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
|
||||
- Handle<Map> transition_map, PropertyDetails details,
|
||||
- bool has_property);
|
||||
-
|
||||
static void InternalUpdateProtector(Isolate* isolate, Handle<Object> receiver,
|
||||
Handle<Name> name);
|
||||
|
||||
@@ -286,12 +281,12 @@ class V8_EXPORT_PRIVATE LookupIterator final {
|
||||
Configuration configuration,
|
||||
Handle<Name> name);
|
||||
|
||||
- static Handle<JSReceiver> GetRootForNonJSReceiver(
|
||||
- Isolate* isolate, Handle<Object> lookup_start_object,
|
||||
- size_t index = kInvalidIndex);
|
||||
- static inline Handle<JSReceiver> GetRoot(Isolate* isolate,
|
||||
- Handle<Object> lookup_start_object,
|
||||
- size_t index = kInvalidIndex);
|
||||
+ static MaybeHandle<JSReceiver> GetRootForNonJSReceiver(
|
||||
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
|
||||
+ Configuration configuration);
|
||||
+ static inline MaybeHandle<JSReceiver> GetRoot(
|
||||
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
|
||||
+ Configuration configuration);
|
||||
|
||||
State NotFound(JSReceiver const holder) const;
|
||||
|
||||
diff --git a/test/mjsunit/regress/regress-crbug-1447430.js b/test/mjsunit/regress/regress-crbug-1447430.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c7bb3e72e3af1b9f8c2fa82faeeb2d813fe6ab3c
|
||||
--- /dev/null
|
||||
+++ b/test/mjsunit/regress/regress-crbug-1447430.js
|
||||
@@ -0,0 +1,34 @@
|
||||
+// Copyright 2023 the V8 project authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+// Flags: --allow-natives-syntax
|
||||
+
|
||||
+var s = %CreatePrivateSymbol('x');
|
||||
+
|
||||
+(function TestSmi() {
|
||||
+ function f(o, p) {
|
||||
+ o[p] = 153;
|
||||
+ }
|
||||
+ (1).__proto__[s] = 42;
|
||||
+ %PrepareFunctionForOptimization(f);
|
||||
+ assertEquals(f(42, s), undefined);
|
||||
+}());
|
||||
+
|
||||
+(function TestString() {
|
||||
+ function f(o, p) {
|
||||
+ o[p] = 153;
|
||||
+ }
|
||||
+ ('xyz').__proto__[s] = 42;
|
||||
+ %PrepareFunctionForOptimization(f);
|
||||
+ assertEquals(f('abc', s), undefined);
|
||||
+}());
|
||||
+
|
||||
+(function TestSymbol() {
|
||||
+ function f(o, p) {
|
||||
+ o[p] = 153;
|
||||
+ }
|
||||
+ Symbol('xyz').__proto__[s] = 42;
|
||||
+ %PrepareFunctionForOptimization(f);
|
||||
+ assertEquals(f(Symbol('abc'), s), undefined);
|
||||
+}());
|
||||
150
patches/v8/cherry-pick-9c6dfc733fce.patch
Normal file
150
patches/v8/cherry-pick-9c6dfc733fce.patch
Normal file
@@ -0,0 +1,150 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Sheludko <ishell@chromium.org>
|
||||
Date: Tue, 16 May 2023 16:01:49 +0200
|
||||
Subject: Merged: [runtime] Fix handling of interceptors
|
||||
|
||||
Drive-by: simplify creation of LookupIterator copies.
|
||||
|
||||
Bug: chromium:1440695
|
||||
(cherry picked from commit d125c7329f6e22af4523de3c55de3a22f168acc9)
|
||||
|
||||
Change-Id: I58416531b9af3456f53264566ec1eb7457328f94
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4545763
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.4@{#23}
|
||||
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
|
||||
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
|
||||
|
||||
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
|
||||
index e86fdec6a57e08bbcd229b7866f22ba3441f608c..b938d82667498d4ff3505d455a7ed3a299cd5247 100644
|
||||
--- a/src/objects/js-objects.cc
|
||||
+++ b/src/objects/js-objects.cc
|
||||
@@ -3629,10 +3629,8 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
|
||||
// own property without the interceptor.
|
||||
Isolate* isolate = it->isolate();
|
||||
Handle<Object> receiver = it->GetReceiver();
|
||||
- LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
|
||||
- LookupIterator own_lookup =
|
||||
- it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
|
||||
- : LookupIterator(isolate, receiver, it->name(), c);
|
||||
+ LookupIterator own_lookup(isolate, receiver, it->GetKey(),
|
||||
+ LookupIterator::OWN_SKIP_INTERCEPTOR);
|
||||
return JSObject::DefineOwnPropertyIgnoreAttributes(
|
||||
&own_lookup, value, attributes, should_throw, handling, semantics,
|
||||
store_origin);
|
||||
diff --git a/src/objects/lookup-inl.h b/src/objects/lookup-inl.h
|
||||
index ff30fcc4f211f49d244e8431cfdb5cba29484329..642d83ff070d6b631a755af78627989878f685a2 100644
|
||||
--- a/src/objects/lookup-inl.h
|
||||
+++ b/src/objects/lookup-inl.h
|
||||
@@ -130,6 +130,29 @@ PropertyKey::PropertyKey(Isolate* isolate, double index) {
|
||||
#endif
|
||||
}
|
||||
|
||||
+PropertyKey::PropertyKey(Isolate* isolate, Handle<Name> name, size_t index)
|
||||
+ : name_(name), index_(index) {
|
||||
+ DCHECK_IMPLIES(index_ == LookupIterator::kInvalidIndex, !name_.is_null());
|
||||
+#if V8_TARGET_ARCH_32_BIT
|
||||
+ DCHECK_IMPLIES(index_ != LookupIterator::kInvalidIndex,
|
||||
+ index_ <= JSObject::kMaxElementIndex);
|
||||
+#endif
|
||||
+#if DEBUG
|
||||
+ if (index_ != LookupIterator::kInvalidIndex && !name_.is_null()) {
|
||||
+ // If both valid index and name are given then the name is a string
|
||||
+ // representation of the same index.
|
||||
+ size_t integer_index;
|
||||
+ CHECK(name_->AsIntegerIndex(&integer_index));
|
||||
+ CHECK_EQ(index_, integer_index);
|
||||
+ } else if (index_ == LookupIterator::kInvalidIndex) {
|
||||
+ // If only name is given it must not be a string representing an integer
|
||||
+ // index.
|
||||
+ size_t integer_index;
|
||||
+ CHECK(!name_->AsIntegerIndex(&integer_index));
|
||||
+ }
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
PropertyKey::PropertyKey(Isolate* isolate, Handle<Name> name) {
|
||||
if (name->AsIntegerIndex(&index_)) {
|
||||
name_ = name;
|
||||
@@ -179,6 +202,10 @@ Handle<Name> LookupIterator::GetName() {
|
||||
return name_;
|
||||
}
|
||||
|
||||
+PropertyKey LookupIterator::GetKey() const {
|
||||
+ return PropertyKey(isolate_, name_, index_);
|
||||
+}
|
||||
+
|
||||
bool LookupIterator::IsElement(JSReceiver object) const {
|
||||
return index_ <= JSObject::kMaxElementIndex ||
|
||||
(index_ != kInvalidIndex &&
|
||||
diff --git a/src/objects/lookup.h b/src/objects/lookup.h
|
||||
index 782a09225c17a92ee8f08d20ede0902613158c27..67a8bac22e6e29df2d7df36937565e4cc0acde45 100644
|
||||
--- a/src/objects/lookup.h
|
||||
+++ b/src/objects/lookup.h
|
||||
@@ -36,6 +36,11 @@ class PropertyKey {
|
||||
inline Handle<Name> GetName(Isolate* isolate);
|
||||
|
||||
private:
|
||||
+ friend LookupIterator;
|
||||
+
|
||||
+ // Shortcut for constructing PropertyKey from an active LookupIterator.
|
||||
+ inline PropertyKey(Isolate* isolate, Handle<Name> name, size_t index);
|
||||
+
|
||||
Handle<Name> name_;
|
||||
size_t index_;
|
||||
};
|
||||
@@ -108,6 +113,9 @@ class V8_EXPORT_PRIVATE LookupIterator final {
|
||||
return static_cast<uint32_t>(index_);
|
||||
}
|
||||
|
||||
+ // Helper method for creating a copy of of the iterator.
|
||||
+ inline PropertyKey GetKey() const;
|
||||
+
|
||||
// Returns true if this LookupIterator has an index in the range
|
||||
// [0, size_t::max).
|
||||
bool IsElement() const { return index_ != kInvalidIndex; }
|
||||
diff --git a/src/objects/objects.cc b/src/objects/objects.cc
|
||||
index c15ac8656adeaf92773a0c4049f7e903ecd2e07f..a7e1833f730e6e5869cd4925cca6dc908859000c 100644
|
||||
--- a/src/objects/objects.cc
|
||||
+++ b/src/objects/objects.cc
|
||||
@@ -2668,11 +2668,8 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
|
||||
|
||||
// Note, the callers rely on the fact that this code is redoing the full own
|
||||
// lookup from scratch.
|
||||
- LookupIterator::Configuration c = LookupIterator::OWN;
|
||||
- LookupIterator own_lookup =
|
||||
- it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
|
||||
- : LookupIterator(isolate, receiver, it->name(), c);
|
||||
-
|
||||
+ LookupIterator own_lookup(isolate, receiver, it->GetKey(),
|
||||
+ LookupIterator::OWN);
|
||||
for (; own_lookup.IsFound(); own_lookup.Next()) {
|
||||
switch (own_lookup.state()) {
|
||||
case LookupIterator::ACCESS_CHECK:
|
||||
@@ -2709,6 +2706,8 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
|
||||
JSReceiver::GetOwnPropertyDescriptor(&own_lookup, &desc);
|
||||
MAYBE_RETURN(owned, Nothing<bool>());
|
||||
if (!owned.FromJust()) {
|
||||
+ // |own_lookup| might become outdated at this point anyway.
|
||||
+ own_lookup.Restart();
|
||||
if (!CheckContextualStoreToJSGlobalObject(&own_lookup,
|
||||
should_throw)) {
|
||||
return Nothing<bool>();
|
||||
diff --git a/test/unittests/api/interceptor-unittest.cc b/test/unittests/api/interceptor-unittest.cc
|
||||
index 635bf6a0b72f8d49591be333b1314846c9c47269..416f9bd1eb4c59160eb03031e6011ae02dcf021e 100644
|
||||
--- a/test/unittests/api/interceptor-unittest.cc
|
||||
+++ b/test/unittests/api/interceptor-unittest.cc
|
||||
@@ -174,8 +174,10 @@ TEST_F(InterceptorLoggingTest, DispatchTest) {
|
||||
EXPECT_EQ(Run("obj.foo"), "named getter");
|
||||
EXPECT_EQ(Run("obj[42]"), "indexed getter");
|
||||
|
||||
- EXPECT_EQ(Run("obj.foo = null"), "named setter, named descriptor");
|
||||
- EXPECT_EQ(Run("obj[42] = null"), "indexed setter, indexed descriptor");
|
||||
+ EXPECT_EQ(Run("obj.foo = null"),
|
||||
+ "named setter, named descriptor, named query");
|
||||
+ EXPECT_EQ(Run("obj[42] = null"),
|
||||
+ "indexed setter, indexed descriptor, indexed query");
|
||||
|
||||
EXPECT_EQ(Run("Object.getOwnPropertyDescriptor(obj, 'foo')"),
|
||||
"named descriptor");
|
||||
90
patches/v8/cherry-pick-aeceeb2187a6.patch
Normal file
90
patches/v8/cherry-pick-aeceeb2187a6.patch
Normal file
@@ -0,0 +1,90 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marja=20H=C3=B6ltt=C3=A4?= <marja@chromium.org>
|
||||
Date: Tue, 21 Feb 2023 13:38:34 +0100
|
||||
Subject: Merged [valueserializer] Fix map transition chain following w/
|
||||
dictionary maps
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Map::Update might return a dictionary map, and the calling code didn't
|
||||
take it into account.
|
||||
|
||||
Bug: chromium:1412487
|
||||
(cherry picked from commit b0db6637936a88807b5512a4de68145d0a9d6f02)
|
||||
|
||||
Change-Id: Ib5e55aa60719e4ac2f14d993a3fc3e908cd43d2e
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4290145
|
||||
Reviewed-by: Marja Hölttä <marja@chromium.org>
|
||||
Reviewed-by: Lutz Vahl <vahl@chromium.org>
|
||||
Commit-Queue: Lutz Vahl <vahl@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.0@{#35}
|
||||
Cr-Branched-From: 06097c6f0c5af54fd5d6965d37027efb72decd4f-refs/heads/11.0.226@{#1}
|
||||
Cr-Branched-From: 6bf3344f5d9940de1ab253f1817dcb99c641c9d3-refs/heads/main@{#84857}
|
||||
|
||||
diff --git a/src/objects/value-serializer.cc b/src/objects/value-serializer.cc
|
||||
index 61a7cae8e8a900694ba22637d04368dac56ebd5f..640f8621719fa5dee4909e215ae788b09f1b0ba5 100644
|
||||
--- a/src/objects/value-serializer.cc
|
||||
+++ b/src/objects/value-serializer.cc
|
||||
@@ -2408,37 +2408,38 @@ Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties(
|
||||
// Deserializaton of |value| might have deprecated current |target|,
|
||||
// ensure we are working with the up-to-date version.
|
||||
target = Map::Update(isolate_, target);
|
||||
-
|
||||
- InternalIndex descriptor(properties.size());
|
||||
- PropertyDetails details =
|
||||
- target->instance_descriptors(isolate_).GetDetails(descriptor);
|
||||
- Representation expected_representation = details.representation();
|
||||
- if (value->FitsRepresentation(expected_representation)) {
|
||||
- if (expected_representation.IsHeapObject() &&
|
||||
- !target->instance_descriptors(isolate_)
|
||||
- .GetFieldType(descriptor)
|
||||
- .NowContains(value)) {
|
||||
- Handle<FieldType> value_type =
|
||||
- value->OptimalType(isolate_, expected_representation);
|
||||
- MapUpdater::GeneralizeField(isolate_, target, descriptor,
|
||||
- details.constness(),
|
||||
- expected_representation, value_type);
|
||||
- }
|
||||
- DCHECK(target->instance_descriptors(isolate_)
|
||||
+ if (!target->is_dictionary_map()) {
|
||||
+ InternalIndex descriptor(properties.size());
|
||||
+ PropertyDetails details =
|
||||
+ target->instance_descriptors(isolate_).GetDetails(descriptor);
|
||||
+ Representation expected_representation = details.representation();
|
||||
+ if (value->FitsRepresentation(expected_representation)) {
|
||||
+ if (expected_representation.IsHeapObject() &&
|
||||
+ !target->instance_descriptors(isolate_)
|
||||
.GetFieldType(descriptor)
|
||||
- .NowContains(value));
|
||||
- properties.push_back(value);
|
||||
- map = target;
|
||||
- continue;
|
||||
- } else {
|
||||
- transitioning = false;
|
||||
+ .NowContains(value)) {
|
||||
+ Handle<FieldType> value_type =
|
||||
+ value->OptimalType(isolate_, expected_representation);
|
||||
+ MapUpdater::GeneralizeField(isolate_, target, descriptor,
|
||||
+ details.constness(),
|
||||
+ expected_representation, value_type);
|
||||
+ }
|
||||
+ DCHECK(target->instance_descriptors(isolate_)
|
||||
+ .GetFieldType(descriptor)
|
||||
+ .NowContains(value));
|
||||
+ properties.push_back(value);
|
||||
+ map = target;
|
||||
+ continue;
|
||||
+ }
|
||||
}
|
||||
+ transitioning = false;
|
||||
}
|
||||
|
||||
// Fell out of transitioning fast path. Commit the properties gathered so
|
||||
// far, and then start setting properties slowly instead.
|
||||
DCHECK(!transitioning);
|
||||
CHECK_LT(properties.size(), std::numeric_limits<uint32_t>::max());
|
||||
+ CHECK(!map->is_dictionary_map());
|
||||
CommitProperties(object, map, properties);
|
||||
num_properties = static_cast<uint32_t>(properties.size());
|
||||
|
||||
36
patches/v8/cherry-pick-c605df24af3c.patch
Normal file
36
patches/v8/cherry-pick-c605df24af3c.patch
Normal file
@@ -0,0 +1,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Sheludko <ishell@chromium.org>
|
||||
Date: Wed, 12 Apr 2023 16:12:16 +0200
|
||||
Subject: Make Error.captureStackTrace() a no-op for global object
|
||||
|
||||
(cherry picked from commit fa81078cca6964def7a3833704e0dba7b05065d8)
|
||||
|
||||
Bug: chromium:1432210
|
||||
Change-Id: I8aa4c3f1d9ecbfffce503085c2879416ff916c69
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4417690
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
|
||||
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
|
||||
Auto-Submit: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#87045}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4419050
|
||||
Reviewed-by: Igor Sheludko <ishell@chromium.org>
|
||||
Reviewed-by: Lutz Vahl <vahl@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.2@{#31}
|
||||
Cr-Branched-From: 755511a138609ac5939449a8ac615c15603a4454-refs/heads/11.2.214@{#1}
|
||||
Cr-Branched-From: e6b1ccefb0f0f1ff8d310578878130dc53d73749-refs/heads/main@{#86014}
|
||||
|
||||
diff --git a/src/builtins/builtins-error.cc b/src/builtins/builtins-error.cc
|
||||
index adb180fba89b61279895e0427caa71703769e28a..4a8dec419d3f483826467a7244b89ad03fa7ff1f 100644
|
||||
--- a/src/builtins/builtins-error.cc
|
||||
+++ b/src/builtins/builtins-error.cc
|
||||
@@ -35,6 +35,9 @@ BUILTIN(ErrorCaptureStackTrace) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kInvalidArgument, object_obj));
|
||||
}
|
||||
+ if (object_obj->IsJSGlobalProxy()) {
|
||||
+ return ReadOnlyRoots(isolate).undefined_value();
|
||||
+ }
|
||||
|
||||
Handle<JSObject> object = Handle<JSObject>::cast(object_obj);
|
||||
Handle<Object> caller = args.atOrUndefined(isolate, 2);
|
||||
33
patches/v8/cherry-pick-f4b66ae451c2.patch
Normal file
33
patches/v8/cherry-pick-f4b66ae451c2.patch
Normal file
@@ -0,0 +1,33 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Darius M <dmercadier@chromium.org>
|
||||
Date: Mon, 27 Mar 2023 13:39:50 +0200
|
||||
Subject: Merged: [compiler] Prevent constant folding of TypeGuard
|
||||
|
||||
TypeGuard are used to prevent operations from floating before a
|
||||
preceding check, and thus shouldn't be constant-folded.
|
||||
|
||||
Bug: chromium:1427388
|
||||
(cherry picked from commit 867716437273c16dc6ef5bc85b9c18affa1fb242)
|
||||
|
||||
Change-Id: Ia334d079707f13974235f8c04ccb468ac16ff794
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4386487
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.2@{#23}
|
||||
Cr-Branched-From: 755511a138609ac5939449a8ac615c15603a4454-refs/heads/11.2.214@{#1}
|
||||
Cr-Branched-From: e6b1ccefb0f0f1ff8d310578878130dc53d73749-refs/heads/main@{#86014}
|
||||
|
||||
diff --git a/src/compiler/constant-folding-reducer.cc b/src/compiler/constant-folding-reducer.cc
|
||||
index 5e74ba75352cc3e7bf29a83ee72273e45720907b..4059e47c2db00e0df82296fa63e09147095f7ba7 100644
|
||||
--- a/src/compiler/constant-folding-reducer.cc
|
||||
+++ b/src/compiler/constant-folding-reducer.cc
|
||||
@@ -66,7 +66,8 @@ ConstantFoldingReducer::~ConstantFoldingReducer() = default;
|
||||
Reduction ConstantFoldingReducer::Reduce(Node* node) {
|
||||
if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) &&
|
||||
node->op()->HasProperty(Operator::kEliminatable) &&
|
||||
- node->opcode() != IrOpcode::kFinishRegion) {
|
||||
+ node->opcode() != IrOpcode::kFinishRegion &&
|
||||
+ node->opcode() != IrOpcode::kTypeGuard) {
|
||||
Node* constant = TryGetConstant(jsgraph(), node);
|
||||
if (constant != nullptr) {
|
||||
DCHECK(NodeProperties::IsTyped(constant));
|
||||
109
patches/v8/cherry-pick-f6ddbf42b1ea.patch
Normal file
109
patches/v8/cherry-pick-f6ddbf42b1ea.patch
Normal file
@@ -0,0 +1,109 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Tebbi <tebbi@chromium.org>
|
||||
Date: Wed, 15 Feb 2023 16:35:18 +0100
|
||||
Subject: check if maps become deprecated during optimization
|
||||
|
||||
(cherry picked from commit f82d802a20aa62e42269f977302f26c5c3ed031b)
|
||||
|
||||
Bug: chromium:1417585
|
||||
No-Try: true
|
||||
No-Presubmit: true
|
||||
No-Tree-Checks: true
|
||||
Change-Id: Ie8eb76d2afb3ee4be66cf5d1c4bff8f745dc145b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4255648
|
||||
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#85848}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4294983
|
||||
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
|
||||
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.8@{#50}
|
||||
Cr-Branched-From: f1bc03fd6b4c201abd9f0fd9d51fb989150f97b9-refs/heads/10.8.168@{#1}
|
||||
Cr-Branched-From: 237de893e1c0a0628a57d0f5797483d3add7f005-refs/heads/main@{#83672}
|
||||
|
||||
diff --git a/src/codegen/bailout-reason.h b/src/codegen/bailout-reason.h
|
||||
index cdd9e123185d142dfeac1e422f345a6a5955658f..33a12a67e4464a907124bb2f45a224f43ed7ec3a 100644
|
||||
--- a/src/codegen/bailout-reason.h
|
||||
+++ b/src/codegen/bailout-reason.h
|
||||
@@ -94,19 +94,20 @@ namespace internal {
|
||||
V(kUnexpectedThreadInWasmSet, "thread_in_wasm flag was already set") \
|
||||
V(kUnexpectedThreadInWasmUnset, "thread_in_wasm flag was not set")
|
||||
|
||||
-#define BAILOUT_MESSAGES_LIST(V) \
|
||||
- V(kNoReason, "no reason") \
|
||||
- \
|
||||
- V(kBailedOutDueToDependencyChange, "Bailed out due to dependency change") \
|
||||
- V(kCodeGenerationFailed, "Code generation failed") \
|
||||
- V(kFunctionBeingDebugged, "Function is being debugged") \
|
||||
- V(kGraphBuildingFailed, "Optimized graph construction failed") \
|
||||
- V(kFunctionTooBig, "Function is too big to be optimized") \
|
||||
- V(kTooManyArguments, "Function contains a call with too many arguments") \
|
||||
- V(kLiveEdit, "LiveEdit") \
|
||||
- V(kNativeFunctionLiteral, "Native function literal") \
|
||||
- V(kOptimizationDisabled, "Optimization disabled") \
|
||||
- V(kHigherTierAvailable, "A higher tier is already available") \
|
||||
+#define BAILOUT_MESSAGES_LIST(V) \
|
||||
+ V(kNoReason, "no reason") \
|
||||
+ \
|
||||
+ V(kBailedOutDueToDependencyChange, "Bailed out due to dependency change") \
|
||||
+ V(kConcurrentMapDeprecation, "Maps became deprecated during optimization") \
|
||||
+ V(kCodeGenerationFailed, "Code generation failed") \
|
||||
+ V(kFunctionBeingDebugged, "Function is being debugged") \
|
||||
+ V(kGraphBuildingFailed, "Optimized graph construction failed") \
|
||||
+ V(kFunctionTooBig, "Function is too big to be optimized") \
|
||||
+ V(kTooManyArguments, "Function contains a call with too many arguments") \
|
||||
+ V(kLiveEdit, "LiveEdit") \
|
||||
+ V(kNativeFunctionLiteral, "Native function literal") \
|
||||
+ V(kOptimizationDisabled, "Optimization disabled") \
|
||||
+ V(kHigherTierAvailable, "A higher tier is already available") \
|
||||
V(kNeverOptimize, "Optimization is always disabled")
|
||||
|
||||
#define ERROR_MESSAGES_CONSTANTS(C, T) C,
|
||||
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc
|
||||
index a142d46a4760d65b09419211afa0972e1f5e6205..7e066adf0a0d04ca332e6b04a253937e51b1d367 100644
|
||||
--- a/src/compiler/pipeline.cc
|
||||
+++ b/src/compiler/pipeline.cc
|
||||
@@ -728,7 +728,10 @@ class PipelineImpl final {
|
||||
// Step D. Run the code finalization pass.
|
||||
MaybeHandle<Code> FinalizeCode(bool retire_broker = true);
|
||||
|
||||
- // Step E. Install any code dependencies.
|
||||
+ // Step E. Ensure all embedded maps are non-deprecated.
|
||||
+ bool CheckNoDeprecatedMaps(Handle<Code> code);
|
||||
+
|
||||
+ // Step F. Install any code dependencies.
|
||||
bool CommitDependencies(Handle<Code> code);
|
||||
|
||||
void VerifyGeneratedCodeIsIdempotent();
|
||||
@@ -1272,6 +1275,9 @@ PipelineCompilationJob::Status PipelineCompilationJob::FinalizeJobImpl(
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
+ if (!pipeline_.CheckNoDeprecatedMaps(code)) {
|
||||
+ return RetryOptimization(BailoutReason::kConcurrentMapDeprecation);
|
||||
+ }
|
||||
if (!pipeline_.CommitDependencies(code)) {
|
||||
return RetryOptimization(BailoutReason::kBailedOutDueToDependencyChange);
|
||||
}
|
||||
@@ -3961,6 +3967,20 @@ MaybeHandle<Code> PipelineImpl::GenerateCode(CallDescriptor* call_descriptor) {
|
||||
return FinalizeCode();
|
||||
}
|
||||
|
||||
+// We must not embed deprecated maps, as we rely in the compiler on all explicit
|
||||
+// maps not being deprecated.
|
||||
+bool PipelineImpl::CheckNoDeprecatedMaps(Handle<Code> code) {
|
||||
+ int mode_mask = RelocInfo::EmbeddedObjectModeMask();
|
||||
+ for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
|
||||
+ DCHECK(RelocInfo::IsEmbeddedObjectMode(it.rinfo()->rmode()));
|
||||
+ HeapObject obj = it.rinfo()->target_object(data_->isolate());
|
||||
+ if (obj.IsMap() && Map::cast(obj).is_deprecated()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
bool PipelineImpl::CommitDependencies(Handle<Code> code) {
|
||||
return data_->dependencies() == nullptr ||
|
||||
data_->dependencies()->Commit(code);
|
||||
366
patches/v8/m108-lts_api_fix_v8_object_setaccessorproperty.patch
Normal file
366
patches/v8/m108-lts_api_fix_v8_object_setaccessorproperty.patch
Normal file
@@ -0,0 +1,366 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Sheludko <ishell@chromium.org>
|
||||
Date: Thu, 27 Apr 2023 11:11:32 +0200
|
||||
Subject: Fix v8::Object::SetAccessorProperty
|
||||
|
||||
... by using JavaScript spec compliant JSReceiver::DefineOwnProperty.
|
||||
|
||||
Drive-by:
|
||||
- cleanup comments in include/v8-object.h, insert links to
|
||||
respective pages of https://tc39.es/ecma262/ when referencing spec,
|
||||
- rename JSObject::DefineAccessor() to
|
||||
JSObject::DefineOwnAccessorIgnoreAttributes().
|
||||
|
||||
(cherry picked from commit b8020e1973d7d3a50b17c076cd948f079e59f9e5)
|
||||
|
||||
Bug: chromium:1433211
|
||||
Change-Id: Ia9edaadd68f1986f18581156ad8f79c438b77744
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4458947
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#87302}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4573392
|
||||
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
|
||||
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
|
||||
Reviewed-by: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.8@{#62}
|
||||
Cr-Branched-From: f1bc03fd6b4c201abd9f0fd9d51fb989150f97b9-refs/heads/10.8.168@{#1}
|
||||
Cr-Branched-From: 237de893e1c0a0628a57d0f5797483d3add7f005-refs/heads/main@{#83672}
|
||||
|
||||
diff --git a/include/v8-object.h b/include/v8-object.h
|
||||
index d7332ba0c88d12e8086f56117631dfb3e1e514b4..dfeda2d39431d481dbeab6698c3d3e7f02a1b19c 100644
|
||||
--- a/include/v8-object.h
|
||||
+++ b/include/v8-object.h
|
||||
@@ -247,13 +247,16 @@ class V8_EXPORT Object : public Value {
|
||||
V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context, uint32_t index,
|
||||
Local<Value> value);
|
||||
|
||||
- // Implements CreateDataProperty (ECMA-262, 7.3.4).
|
||||
- //
|
||||
- // Defines a configurable, writable, enumerable property with the given value
|
||||
- // on the object unless the property already exists and is not configurable
|
||||
- // or the object is not extensible.
|
||||
- //
|
||||
- // Returns true on success.
|
||||
+ /**
|
||||
+ * Implements CreateDataProperty(O, P, V), see
|
||||
+ * https://tc39.es/ecma262/#sec-createdataproperty.
|
||||
+ *
|
||||
+ * Defines a configurable, writable, enumerable property with the given value
|
||||
+ * on the object unless the property already exists and is not configurable
|
||||
+ * or the object is not extensible.
|
||||
+ *
|
||||
+ * Returns true on success.
|
||||
+ */
|
||||
V8_WARN_UNUSED_RESULT Maybe<bool> CreateDataProperty(Local<Context> context,
|
||||
Local<Name> key,
|
||||
Local<Value> value);
|
||||
@@ -261,29 +264,35 @@ class V8_EXPORT Object : public Value {
|
||||
uint32_t index,
|
||||
Local<Value> value);
|
||||
|
||||
- // Implements DefineOwnProperty.
|
||||
- //
|
||||
- // In general, CreateDataProperty will be faster, however, does not allow
|
||||
- // for specifying attributes.
|
||||
- //
|
||||
- // Returns true on success.
|
||||
+ /**
|
||||
+ * Implements [[DefineOwnProperty]] for data property case, see
|
||||
+ * https://tc39.es/ecma262/#table-essential-internal-methods.
|
||||
+ *
|
||||
+ * In general, CreateDataProperty will be faster, however, does not allow
|
||||
+ * for specifying attributes.
|
||||
+ *
|
||||
+ * Returns true on success.
|
||||
+ */
|
||||
V8_WARN_UNUSED_RESULT Maybe<bool> DefineOwnProperty(
|
||||
Local<Context> context, Local<Name> key, Local<Value> value,
|
||||
PropertyAttribute attributes = None);
|
||||
|
||||
- // Implements Object.DefineProperty(O, P, Attributes), see Ecma-262 19.1.2.4.
|
||||
- //
|
||||
- // The defineProperty function is used to add an own property or
|
||||
- // update the attributes of an existing own property of an object.
|
||||
- //
|
||||
- // Both data and accessor descriptors can be used.
|
||||
- //
|
||||
- // In general, CreateDataProperty is faster, however, does not allow
|
||||
- // for specifying attributes or an accessor descriptor.
|
||||
- //
|
||||
- // The PropertyDescriptor can change when redefining a property.
|
||||
- //
|
||||
- // Returns true on success.
|
||||
+ /**
|
||||
+ * Implements Object.defineProperty(O, P, Attributes), see
|
||||
+ * https://tc39.es/ecma262/#sec-object.defineproperty.
|
||||
+ *
|
||||
+ * The defineProperty function is used to add an own property or
|
||||
+ * update the attributes of an existing own property of an object.
|
||||
+ *
|
||||
+ * Both data and accessor descriptors can be used.
|
||||
+ *
|
||||
+ * In general, CreateDataProperty is faster, however, does not allow
|
||||
+ * for specifying attributes or an accessor descriptor.
|
||||
+ *
|
||||
+ * The PropertyDescriptor can change when redefining a property.
|
||||
+ *
|
||||
+ * Returns true on success.
|
||||
+ */
|
||||
V8_WARN_UNUSED_RESULT Maybe<bool> DefineProperty(
|
||||
Local<Context> context, Local<Name> key, PropertyDescriptor& descriptor);
|
||||
|
||||
@@ -302,14 +311,15 @@ class V8_EXPORT Object : public Value {
|
||||
Local<Context> context, Local<Value> key);
|
||||
|
||||
/**
|
||||
- * Returns Object.getOwnPropertyDescriptor as per ES2016 section 19.1.2.6.
|
||||
+ * Implements Object.getOwnPropertyDescriptor(O, P), see
|
||||
+ * https://tc39.es/ecma262/#sec-object.getownpropertydescriptor.
|
||||
*/
|
||||
V8_WARN_UNUSED_RESULT MaybeLocal<Value> GetOwnPropertyDescriptor(
|
||||
Local<Context> context, Local<Name> key);
|
||||
|
||||
/**
|
||||
- * Object::Has() calls the abstract operation HasProperty(O, P) described
|
||||
- * in ECMA-262, 7.3.10. Has() returns
|
||||
+ * Object::Has() calls the abstract operation HasProperty(O, P), see
|
||||
+ * https://tc39.es/ecma262/#sec-hasproperty. Has() returns
|
||||
* true, if the object has the property, either own or on the prototype chain.
|
||||
* Interceptors, i.e., PropertyQueryCallbacks, are called if present.
|
||||
*
|
||||
@@ -347,7 +357,7 @@ class V8_EXPORT Object : public Value {
|
||||
|
||||
void SetAccessorProperty(Local<Name> name, Local<Function> getter,
|
||||
Local<Function> setter = Local<Function>(),
|
||||
- PropertyAttribute attribute = None,
|
||||
+ PropertyAttribute attributes = None,
|
||||
AccessControl settings = DEFAULT);
|
||||
|
||||
/**
|
||||
diff --git a/src/api/api-natives.cc b/src/api/api-natives.cc
|
||||
index 8624c279d66e4fa54a7a20681e1398c453b6cdbd..742d3c17a3e7def43813f44b004c8dc41a27ed68 100644
|
||||
--- a/src/api/api-natives.cc
|
||||
+++ b/src/api/api-natives.cc
|
||||
@@ -92,10 +92,10 @@ MaybeHandle<Object> DefineAccessorProperty(Isolate* isolate,
|
||||
Handle<FunctionTemplateInfo>::cast(setter)),
|
||||
Object);
|
||||
}
|
||||
- RETURN_ON_EXCEPTION(
|
||||
- isolate,
|
||||
- JSObject::DefineAccessor(object, name, getter, setter, attributes),
|
||||
- Object);
|
||||
+ RETURN_ON_EXCEPTION(isolate,
|
||||
+ JSObject::DefineOwnAccessorIgnoreAttributes(
|
||||
+ object, name, getter, setter, attributes),
|
||||
+ Object);
|
||||
return object;
|
||||
}
|
||||
|
||||
diff --git a/src/api/api.cc b/src/api/api.cc
|
||||
index 0bc26565403fa1a9827ced3bc6a49ca87bbf46c0..29e163c2e3073ae1f9a86e88f317e9fd44c6c112 100644
|
||||
--- a/src/api/api.cc
|
||||
+++ b/src/api/api.cc
|
||||
@@ -4932,7 +4932,7 @@ Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
|
||||
|
||||
void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
|
||||
Local<Function> setter,
|
||||
- PropertyAttribute attribute,
|
||||
+ PropertyAttribute attributes,
|
||||
AccessControl settings) {
|
||||
// TODO(verwaest): Remove |settings|.
|
||||
DCHECK_EQ(v8::DEFAULT, settings);
|
||||
@@ -4944,9 +4944,20 @@ void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
|
||||
i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
|
||||
i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
|
||||
if (setter_i.is_null()) setter_i = i_isolate->factory()->null_value();
|
||||
- i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
|
||||
- v8::Utils::OpenHandle(*name), getter_i, setter_i,
|
||||
- static_cast<i::PropertyAttributes>(attribute));
|
||||
+
|
||||
+ i::PropertyDescriptor desc;
|
||||
+ desc.set_enumerable(!(attributes & v8::DontEnum));
|
||||
+ desc.set_configurable(!(attributes & v8::DontDelete));
|
||||
+ desc.set_get(getter_i);
|
||||
+ desc.set_set(setter_i);
|
||||
+
|
||||
+ i::Handle<i::Name> name_i = v8::Utils::OpenHandle(*name);
|
||||
+ // DefineOwnProperty might still throw if the receiver is a JSProxy and it
|
||||
+ // might fail if the receiver is non-extensible or already has this property
|
||||
+ // as non-configurable.
|
||||
+ Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
|
||||
+ i_isolate, self, name_i, &desc, Just(i::kDontThrow));
|
||||
+ USE(success);
|
||||
}
|
||||
|
||||
Maybe<bool> Object::SetNativeDataProperty(
|
||||
diff --git a/src/init/bootstrapper.cc b/src/init/bootstrapper.cc
|
||||
index fc7b17d582e79b956362e0db46a7aefebd594ed0..8a81c4acda9a92b1d25491aa00278a0e929da695 100644
|
||||
--- a/src/init/bootstrapper.cc
|
||||
+++ b/src/init/bootstrapper.cc
|
||||
@@ -634,7 +634,9 @@ V8_NOINLINE void SimpleInstallGetterSetter(Isolate* isolate,
|
||||
Handle<JSFunction> setter =
|
||||
SimpleCreateFunction(isolate, setter_name, call_setter, 1, true);
|
||||
|
||||
- JSObject::DefineAccessor(base, name, getter, setter, DONT_ENUM).Check();
|
||||
+ JSObject::DefineOwnAccessorIgnoreAttributes(base, name, getter, setter,
|
||||
+ DONT_ENUM)
|
||||
+ .Check();
|
||||
}
|
||||
|
||||
void SimpleInstallGetterSetter(Isolate* isolate, Handle<JSObject> base,
|
||||
@@ -658,7 +660,8 @@ V8_NOINLINE Handle<JSFunction> SimpleInstallGetter(Isolate* isolate,
|
||||
|
||||
Handle<Object> setter = isolate->factory()->undefined_value();
|
||||
|
||||
- JSObject::DefineAccessor(base, property_name, getter, setter, DONT_ENUM)
|
||||
+ JSObject::DefineOwnAccessorIgnoreAttributes(base, property_name, getter,
|
||||
+ setter, DONT_ENUM)
|
||||
.Check();
|
||||
|
||||
return getter;
|
||||
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
|
||||
index b938d82667498d4ff3505d455a7ed3a299cd5247..e51264eef22c9fc91c89ef6fe0d223c97ccf7fa9 100644
|
||||
--- a/src/objects/js-objects.cc
|
||||
+++ b/src/objects/js-objects.cc
|
||||
@@ -1498,7 +1498,8 @@ Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
|
||||
? desc->set()
|
||||
: Handle<Object>::cast(isolate->factory()->null_value()));
|
||||
MaybeHandle<Object> result =
|
||||
- JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes());
|
||||
+ JSObject::DefineOwnAccessorIgnoreAttributes(it, getter, setter,
|
||||
+ desc->ToAttributes());
|
||||
if (result.is_null()) return Nothing<bool>();
|
||||
}
|
||||
}
|
||||
@@ -1679,8 +1680,8 @@ Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
|
||||
: current->has_set()
|
||||
? current->set()
|
||||
: Handle<Object>::cast(isolate->factory()->null_value()));
|
||||
- MaybeHandle<Object> result =
|
||||
- JSObject::DefineAccessor(it, getter, setter, attrs);
|
||||
+ MaybeHandle<Object> result = JSObject::DefineOwnAccessorIgnoreAttributes(
|
||||
+ it, getter, setter, attrs);
|
||||
if (result.is_null()) return Nothing<bool>();
|
||||
}
|
||||
}
|
||||
@@ -4611,22 +4612,19 @@ bool JSObject::HasEnumerableElements() {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
-MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
|
||||
- Handle<Name> name,
|
||||
- Handle<Object> getter,
|
||||
- Handle<Object> setter,
|
||||
- PropertyAttributes attributes) {
|
||||
+MaybeHandle<Object> JSObject::DefineOwnAccessorIgnoreAttributes(
|
||||
+ Handle<JSObject> object, Handle<Name> name, Handle<Object> getter,
|
||||
+ Handle<Object> setter, PropertyAttributes attributes) {
|
||||
Isolate* isolate = object->GetIsolate();
|
||||
|
||||
PropertyKey key(isolate, name);
|
||||
LookupIterator it(isolate, object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
|
||||
- return DefineAccessor(&it, getter, setter, attributes);
|
||||
+ return DefineOwnAccessorIgnoreAttributes(&it, getter, setter, attributes);
|
||||
}
|
||||
|
||||
-MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it,
|
||||
- Handle<Object> getter,
|
||||
- Handle<Object> setter,
|
||||
- PropertyAttributes attributes) {
|
||||
+MaybeHandle<Object> JSObject::DefineOwnAccessorIgnoreAttributes(
|
||||
+ LookupIterator* it, Handle<Object> getter, Handle<Object> setter,
|
||||
+ PropertyAttributes attributes) {
|
||||
Isolate* isolate = it->isolate();
|
||||
|
||||
it->UpdateProtector();
|
||||
diff --git a/src/objects/js-objects.h b/src/objects/js-objects.h
|
||||
index f663af6ed8a445f8ef30a67bac176a1abe6c85f8..5e7326eb1c99115829c358cd4069e1f6835f972b 100644
|
||||
--- a/src/objects/js-objects.h
|
||||
+++ b/src/objects/js-objects.h
|
||||
@@ -525,13 +525,14 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
|
||||
GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
|
||||
|
||||
// Defines an AccessorPair property on the given object.
|
||||
- V8_EXPORT_PRIVATE static MaybeHandle<Object> DefineAccessor(
|
||||
- Handle<JSObject> object, Handle<Name> name, Handle<Object> getter,
|
||||
- Handle<Object> setter, PropertyAttributes attributes);
|
||||
- static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
|
||||
- Handle<Object> getter,
|
||||
- Handle<Object> setter,
|
||||
- PropertyAttributes attributes);
|
||||
+ V8_EXPORT_PRIVATE static MaybeHandle<Object>
|
||||
+ DefineOwnAccessorIgnoreAttributes(Handle<JSObject> object, Handle<Name> name,
|
||||
+ Handle<Object> getter,
|
||||
+ Handle<Object> setter,
|
||||
+ PropertyAttributes attributes);
|
||||
+ static MaybeHandle<Object> DefineOwnAccessorIgnoreAttributes(
|
||||
+ LookupIterator* it, Handle<Object> getter, Handle<Object> setter,
|
||||
+ PropertyAttributes attributes);
|
||||
|
||||
// Defines an AccessorInfo property on the given object.
|
||||
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SetAccessor(
|
||||
diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc
|
||||
index 56e58bea3e1c7add75729e590b628d9a78558ce6..01111be8d6ea28ed1e1e81255b29da5a77ab1e39 100644
|
||||
--- a/src/runtime/runtime-object.cc
|
||||
+++ b/src/runtime/runtime-object.cc
|
||||
@@ -1109,7 +1109,8 @@ RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
|
||||
auto attrs = PropertyAttributesFromInt(args.smi_value_at(4));
|
||||
|
||||
RETURN_FAILURE_ON_EXCEPTION(
|
||||
- isolate, JSObject::DefineAccessor(obj, name, getter, setter, attrs));
|
||||
+ isolate, JSObject::DefineOwnAccessorIgnoreAttributes(obj, name, getter,
|
||||
+ setter, attrs));
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
@@ -1215,8 +1216,8 @@ RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
|
||||
|
||||
RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate,
|
||||
- JSObject::DefineAccessor(object, name, getter,
|
||||
- isolate->factory()->null_value(), attrs));
|
||||
+ JSObject::DefineOwnAccessorIgnoreAttributes(
|
||||
+ object, name, getter, isolate->factory()->null_value(), attrs));
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
@@ -1360,8 +1361,8 @@ RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
|
||||
|
||||
RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate,
|
||||
- JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
|
||||
- setter, attrs));
|
||||
+ JSObject::DefineOwnAccessorIgnoreAttributes(
|
||||
+ object, name, isolate->factory()->null_value(), setter, attrs));
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
diff --git a/src/sandbox/testing.cc b/src/sandbox/testing.cc
|
||||
index fead4aa222ceb81d76f6dfec7e7797e337e7ba94..aab72a18015bf7ac1d0949e9497e85d9d089b4b8 100644
|
||||
--- a/src/sandbox/testing.cc
|
||||
+++ b/src/sandbox/testing.cc
|
||||
@@ -156,7 +156,8 @@ void InstallGetter(Isolate* isolate, Handle<JSObject> object,
|
||||
Handle<String> property_name = factory->NewStringFromAsciiChecked(name);
|
||||
Handle<JSFunction> getter = CreateFunc(isolate, func, property_name, false);
|
||||
Handle<Object> setter = factory->null_value();
|
||||
- JSObject::DefineAccessor(object, property_name, getter, setter, FROZEN);
|
||||
+ JSObject::DefineOwnAccessorIgnoreAttributes(object, property_name, getter,
|
||||
+ setter, FROZEN);
|
||||
}
|
||||
|
||||
void InstallFunction(Isolate* isolate, Handle<JSObject> holder,
|
||||
diff --git a/test/cctest/test-code-stub-assembler.cc b/test/cctest/test-code-stub-assembler.cc
|
||||
index 53ad0a95e2e63f32610a77ee7195d15f7037898d..4152456d1a7962da4a0d88e15bc68107da585613 100644
|
||||
--- a/test/cctest/test-code-stub-assembler.cc
|
||||
+++ b/test/cctest/test-code-stub-assembler.cc
|
||||
@@ -1179,7 +1179,9 @@ void AddProperties(Handle<JSObject> object, Handle<Name> names[],
|
||||
Handle<AccessorPair> pair = Handle<AccessorPair>::cast(value);
|
||||
Handle<Object> getter(pair->getter(), isolate);
|
||||
Handle<Object> setter(pair->setter(), isolate);
|
||||
- JSObject::DefineAccessor(object, names[i], getter, setter, NONE).Check();
|
||||
+ JSObject::DefineOwnAccessorIgnoreAttributes(object, names[i], getter,
|
||||
+ setter, NONE)
|
||||
+ .Check();
|
||||
} else {
|
||||
JSObject::AddProperty(isolate, object, names[i], value, NONE);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Tebbi <tebbi@chromium.org>
|
||||
Date: Tue, 13 Jun 2023 17:08:59 +0200
|
||||
Subject: Merged: [compiler] StackCheck can have side effects
|
||||
|
||||
Bug: chromium:1452137
|
||||
(cherry picked from commit e548943e473b020fdc1de6e5543ca31b24d8b7f9)
|
||||
|
||||
Change-Id: Ibd7c9b02efd12341b452e4c34a635a58a817649f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4637129
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
|
||||
Auto-Submit: Tobias Tebbi <tebbi@chromium.org>
|
||||
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.4@{#49}
|
||||
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
|
||||
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
|
||||
|
||||
diff --git a/src/compiler/js-operator.cc b/src/compiler/js-operator.cc
|
||||
index 8af8e7d32fb68fdcaedaf08427103c893d23098d..e60c8a2c78970c89c4f52a6dc34a97d56e602e26 100644
|
||||
--- a/src/compiler/js-operator.cc
|
||||
+++ b/src/compiler/js-operator.cc
|
||||
@@ -1396,7 +1396,7 @@ const Operator* JSOperatorBuilder::CloneObject(FeedbackSource const& feedback,
|
||||
const Operator* JSOperatorBuilder::StackCheck(StackCheckKind kind) {
|
||||
return zone()->New<Operator1<StackCheckKind>>( // --
|
||||
IrOpcode::kJSStackCheck, // opcode
|
||||
- Operator::kNoWrite, // properties
|
||||
+ Operator::kNoProperties, // properties
|
||||
"JSStackCheck", // name
|
||||
0, 1, 1, 0, 1, 2, // counts
|
||||
kind); // parameter
|
||||
@@ -0,0 +1,122 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Sheludko <ishell@chromium.org>
|
||||
Date: Fri, 2 Jun 2023 18:13:01 +0200
|
||||
Subject: Merged: [ic] Fix store handler selection for arguments objects
|
||||
|
||||
Drive-by: fix printing of handlers in --trace-feedback-updates mode.
|
||||
|
||||
(cherry picked from commit e144f3b71e64e01d6ffd247eb15ca1ff56f6287b)
|
||||
|
||||
Bug: chromium:1450481
|
||||
Change-Id: Ifbb97d694b8520584df0610aad30805713b29c00
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4584889
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/10.9@{#32}
|
||||
Cr-Branched-From: 8ade6bf1fa237ad30dd9a05cc6ffe548131699e8-refs/heads/10.9.194@{#1}
|
||||
Cr-Branched-From: 9ff2515271f11cab783f0e82678ae0b925d77dd0-refs/heads/main@{#84164}
|
||||
|
||||
diff --git a/src/diagnostics/objects-printer.cc b/src/diagnostics/objects-printer.cc
|
||||
index 71604afa7a067e14a891057de4011416f45f4f19..3f94e8aa7701eef49d5a35fd552742279b5e8586 100644
|
||||
--- a/src/diagnostics/objects-printer.cc
|
||||
+++ b/src/diagnostics/objects-printer.cc
|
||||
@@ -1308,8 +1308,18 @@ void FeedbackNexus::Print(std::ostream& os) {
|
||||
case FeedbackSlotKind::kSetKeyedStrict: {
|
||||
os << InlineCacheState2String(ic_state());
|
||||
if (ic_state() == InlineCacheState::MONOMORPHIC) {
|
||||
- os << "\n " << Brief(GetFeedback()) << ": ";
|
||||
- StoreHandler::PrintHandler(GetFeedbackExtra().GetHeapObjectOrSmi(), os);
|
||||
+ HeapObject feedback = GetFeedback().GetHeapObject();
|
||||
+ HeapObject feedback_extra = GetFeedbackExtra().GetHeapObject();
|
||||
+ if (feedback.IsName()) {
|
||||
+ os << " with name " << Brief(feedback);
|
||||
+ WeakFixedArray array = WeakFixedArray::cast(feedback_extra);
|
||||
+ os << "\n " << Brief(array.Get(0)) << ": ";
|
||||
+ Object handler = array.Get(1).GetHeapObjectOrSmi();
|
||||
+ StoreHandler::PrintHandler(handler, os);
|
||||
+ } else {
|
||||
+ os << "\n " << Brief(feedback) << ": ";
|
||||
+ StoreHandler::PrintHandler(feedback_extra, os);
|
||||
+ }
|
||||
} else if (ic_state() == InlineCacheState::POLYMORPHIC) {
|
||||
WeakFixedArray array =
|
||||
WeakFixedArray::cast(GetFeedback().GetHeapObject());
|
||||
diff --git a/src/ic/handler-configuration.cc b/src/ic/handler-configuration.cc
|
||||
index 43511407e0eb54e2ce22ee132d8a4d37c52b13a7..cd6d834d6b7ec84c1d46105449ca775cd970f4f2 100644
|
||||
--- a/src/ic/handler-configuration.cc
|
||||
+++ b/src/ic/handler-configuration.cc
|
||||
@@ -584,8 +584,11 @@ void StoreHandler::PrintHandler(Object handler, std::ostream& os) {
|
||||
os << ", validity cell = ";
|
||||
store_handler.validity_cell().ShortPrint(os);
|
||||
os << ")" << std::endl;
|
||||
+ } else if (handler.IsMap()) {
|
||||
+ os << "StoreHandler(field transition to " << Brief(handler) << ")"
|
||||
+ << std::endl;
|
||||
} else {
|
||||
- os << "StoreHandler(<unexpected>)(" << Brief(handler) << ")";
|
||||
+ os << "StoreHandler(<unexpected>)(" << Brief(handler) << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
|
||||
index 32039f9888d3cb54699c6aefd0bcc3573044995e..0a7794de93dc6ba2a20f106ccf2d5f4b30319167 100644
|
||||
--- a/src/ic/ic.cc
|
||||
+++ b/src/ic/ic.cc
|
||||
@@ -2296,10 +2296,18 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
|
||||
receiver_map->has_sealed_elements() ||
|
||||
receiver_map->has_nonextensible_elements() ||
|
||||
receiver_map->has_typed_array_or_rab_gsab_typed_array_elements()) {
|
||||
+ // TODO(jgruber): Update counter name.
|
||||
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub);
|
||||
- code = StoreHandler::StoreFastElementBuiltin(isolate(), store_mode);
|
||||
- if (receiver_map->has_typed_array_or_rab_gsab_typed_array_elements()) {
|
||||
- return code;
|
||||
+ if (receiver_map->IsJSArgumentsObjectMap() &&
|
||||
+ receiver_map->has_fast_packed_elements()) {
|
||||
+ // Allow fast behaviour for in-bounds stores while making it miss and
|
||||
+ // properly handle the out of bounds store case.
|
||||
+ code = StoreHandler::StoreFastElementBuiltin(isolate(), STANDARD_STORE);
|
||||
+ } else {
|
||||
+ code = StoreHandler::StoreFastElementBuiltin(isolate(), store_mode);
|
||||
+ if (receiver_map->has_typed_array_or_rab_gsab_typed_array_elements()) {
|
||||
+ return code;
|
||||
+ }
|
||||
}
|
||||
} else if (IsStoreInArrayLiteralIC()) {
|
||||
// TODO(jgruber): Update counter name.
|
||||
@@ -2310,7 +2318,7 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
|
||||
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub);
|
||||
DCHECK(DICTIONARY_ELEMENTS == receiver_map->elements_kind() ||
|
||||
receiver_map->has_frozen_elements());
|
||||
- code = StoreHandler::StoreSlow(isolate(), store_mode);
|
||||
+ return StoreHandler::StoreSlow(isolate(), store_mode);
|
||||
}
|
||||
|
||||
if (IsAnyDefineOwn() || IsStoreInArrayLiteralIC()) return code;
|
||||
diff --git a/src/objects/map-inl.h b/src/objects/map-inl.h
|
||||
index 04cdb99e103c5ab51c22a91fd7ba0712b757556c..5f93c39b652946a5ad8f23235f958dde4b84cbb4 100644
|
||||
--- a/src/objects/map-inl.h
|
||||
+++ b/src/objects/map-inl.h
|
||||
@@ -589,6 +589,10 @@ bool Map::has_fast_elements() const {
|
||||
return IsFastElementsKind(elements_kind());
|
||||
}
|
||||
|
||||
+bool Map::has_fast_packed_elements() const {
|
||||
+ return IsFastPackedElementsKind(elements_kind());
|
||||
+}
|
||||
+
|
||||
bool Map::has_sloppy_arguments_elements() const {
|
||||
return IsSloppyArgumentsElementsKind(elements_kind());
|
||||
}
|
||||
diff --git a/src/objects/map.h b/src/objects/map.h
|
||||
index 6914a51150f4235386f5dca7af0d8103bc64f9e2..8311850f82bc32b794873689789c510376f67233 100644
|
||||
--- a/src/objects/map.h
|
||||
+++ b/src/objects/map.h
|
||||
@@ -422,6 +422,7 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
|
||||
inline bool has_fast_smi_or_object_elements() const;
|
||||
inline bool has_fast_double_elements() const;
|
||||
inline bool has_fast_elements() const;
|
||||
+ inline bool has_fast_packed_elements() const;
|
||||
inline bool has_sloppy_arguments_elements() const;
|
||||
inline bool has_fast_sloppy_arguments_elements() const;
|
||||
inline bool has_fast_string_wrapper_elements() const;
|
||||
@@ -0,0 +1,304 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shu-yu Guo <syg@chromium.org>
|
||||
Date: Wed, 26 Apr 2023 10:56:03 -0700
|
||||
Subject: Merged: [regexp] Fix clobbered register in global Unicode special
|
||||
case
|
||||
|
||||
Bug: chromium:1439691
|
||||
(cherry picked from commit 2c8a019f39d29b403f881d9b5932e3219fdcc832)
|
||||
|
||||
Change-Id: Ia418ae04bf4352e3618700c55ecd37447023e6eb
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4503810
|
||||
Reviewed-by: Jakob Linke <jgruber@chromium.org>
|
||||
Commit-Queue: Shu-yu Guo <syg@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.2@{#43}
|
||||
Cr-Branched-From: 755511a138609ac5939449a8ac615c15603a4454-refs/heads/11.2.214@{#1}
|
||||
Cr-Branched-From: e6b1ccefb0f0f1ff8d310578878130dc53d73749-refs/heads/main@{#86014}
|
||||
|
||||
diff --git a/src/regexp/arm/regexp-macro-assembler-arm.cc b/src/regexp/arm/regexp-macro-assembler-arm.cc
|
||||
index 2658068b6f94b97f024b1400c8c0b20eefdc5143..5de110c8495ef5bd261df92ca8f459c5f0cc7e5b 100644
|
||||
--- a/src/regexp/arm/regexp-macro-assembler-arm.cc
|
||||
+++ b/src/regexp/arm/regexp-macro-assembler-arm.cc
|
||||
@@ -877,19 +877,18 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
|
||||
__ add(r2, r2, Operand(num_saved_registers_ * kPointerSize));
|
||||
__ str(r2, MemOperand(frame_pointer(), kRegisterOutput));
|
||||
|
||||
- // Prepare r0 to initialize registers with its value in the next run.
|
||||
- __ ldr(r0, MemOperand(frame_pointer(), kStringStartMinusOne));
|
||||
-
|
||||
// Restore the original regexp stack pointer value (effectively, pop the
|
||||
// stored base pointer).
|
||||
PopRegExpBasePointer(backtrack_stackpointer(), r2);
|
||||
|
||||
+ Label reload_string_start_minus_one;
|
||||
+
|
||||
if (global_with_zero_length_check()) {
|
||||
// Special case for zero-length matches.
|
||||
// r4: capture start index
|
||||
__ cmp(current_input_offset(), r4);
|
||||
// Not a zero-length match, restart.
|
||||
- __ b(ne, &load_char_start_regexp);
|
||||
+ __ b(ne, &reload_string_start_minus_one);
|
||||
// Offset from the end is zero if we already reached the end.
|
||||
__ cmp(current_input_offset(), Operand::Zero());
|
||||
__ b(eq, &exit_label_);
|
||||
@@ -901,6 +900,11 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
|
||||
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
|
||||
}
|
||||
|
||||
+ __ bind(&reload_string_start_minus_one);
|
||||
+ // Prepare r0 to initialize registers with its value in the next run.
|
||||
+ // Must be immediately before the jump to avoid clobbering.
|
||||
+ __ ldr(r0, MemOperand(frame_pointer(), kStringStartMinusOne));
|
||||
+
|
||||
__ b(&load_char_start_regexp);
|
||||
} else {
|
||||
__ mov(r0, Operand(SUCCESS));
|
||||
diff --git a/src/regexp/ia32/regexp-macro-assembler-ia32.cc b/src/regexp/ia32/regexp-macro-assembler-ia32.cc
|
||||
index 600234542042ce9a06ceb3b415fece83f6f271bf..6c3df5da7d6c28619902b20419c9cf437325c1d1 100644
|
||||
--- a/src/regexp/ia32/regexp-macro-assembler-ia32.cc
|
||||
+++ b/src/regexp/ia32/regexp-macro-assembler-ia32.cc
|
||||
@@ -915,19 +915,18 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
||||
__ add(Operand(ebp, kRegisterOutput),
|
||||
Immediate(num_saved_registers_ * kSystemPointerSize));
|
||||
|
||||
- // Prepare eax to initialize registers with its value in the next run.
|
||||
- __ mov(eax, Operand(ebp, kStringStartMinusOne));
|
||||
-
|
||||
// Restore the original regexp stack pointer value (effectively, pop the
|
||||
// stored base pointer).
|
||||
PopRegExpBasePointer(backtrack_stackpointer(), ebx);
|
||||
|
||||
+ Label reload_string_start_minus_one;
|
||||
+
|
||||
if (global_with_zero_length_check()) {
|
||||
// Special case for zero-length matches.
|
||||
// edx: capture start index
|
||||
__ cmp(edi, edx);
|
||||
// Not a zero-length match, restart.
|
||||
- __ j(not_equal, &load_char_start_regexp);
|
||||
+ __ j(not_equal, &reload_string_start_minus_one);
|
||||
// edi (offset from the end) is zero if we already reached the end.
|
||||
__ test(edi, edi);
|
||||
__ j(zero, &exit_label_, Label::kNear);
|
||||
@@ -941,6 +940,12 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
||||
}
|
||||
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
|
||||
}
|
||||
+
|
||||
+ __ bind(&reload_string_start_minus_one);
|
||||
+ // Prepare eax to initialize registers with its value in the next run.
|
||||
+ // Must be immediately before the jump to avoid clobbering.
|
||||
+ __ mov(eax, Operand(ebp, kStringStartMinusOne));
|
||||
+
|
||||
__ jmp(&load_char_start_regexp);
|
||||
} else {
|
||||
__ mov(eax, Immediate(SUCCESS));
|
||||
diff --git a/src/regexp/loong64/regexp-macro-assembler-loong64.cc b/src/regexp/loong64/regexp-macro-assembler-loong64.cc
|
||||
index 35fd95bd0f2d210419b4057ced6e16ffd5aec051..d5c52b4134ccbfecef85328e181dae1bbda7bf63 100644
|
||||
--- a/src/regexp/loong64/regexp-macro-assembler-loong64.cc
|
||||
+++ b/src/regexp/loong64/regexp-macro-assembler-loong64.cc
|
||||
@@ -850,18 +850,17 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
|
||||
__ Add_d(a2, a2, num_saved_registers_ * kIntSize);
|
||||
__ St_d(a2, MemOperand(frame_pointer(), kRegisterOutput));
|
||||
|
||||
- // Prepare a0 to initialize registers with its value in the next run.
|
||||
- __ Ld_d(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
|
||||
-
|
||||
// Restore the original regexp stack pointer value (effectively, pop the
|
||||
// stored base pointer).
|
||||
PopRegExpBasePointer(backtrack_stackpointer(), a2);
|
||||
|
||||
+ Label reload_string_start_minus_one;
|
||||
+
|
||||
if (global_with_zero_length_check()) {
|
||||
// Special case for zero-length matches.
|
||||
// t3: capture start index
|
||||
// Not a zero-length match, restart.
|
||||
- __ Branch(&load_char_start_regexp, ne, current_input_offset(),
|
||||
+ __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
|
||||
Operand(t3));
|
||||
// Offset from the end is zero if we already reached the end.
|
||||
__ Branch(&exit_label_, eq, current_input_offset(),
|
||||
@@ -874,6 +873,11 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
|
||||
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
|
||||
}
|
||||
|
||||
+ __ bind(&reload_string_start_minus_one);
|
||||
+ // Prepare a0 to initialize registers with its value in the next run.
|
||||
+ // Must be immediately before the jump to avoid clobbering.
|
||||
+ __ Ld_d(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
|
||||
+
|
||||
__ Branch(&load_char_start_regexp);
|
||||
} else {
|
||||
__ li(a0, Operand(SUCCESS));
|
||||
diff --git a/src/regexp/mips64/regexp-macro-assembler-mips64.cc b/src/regexp/mips64/regexp-macro-assembler-mips64.cc
|
||||
index 456e166adefc72b7bcaa9245798f3885c2a4c2e7..6ee4c709cf96f68a32a0b3c1ebdc42817293bf29 100644
|
||||
--- a/src/regexp/mips64/regexp-macro-assembler-mips64.cc
|
||||
+++ b/src/regexp/mips64/regexp-macro-assembler-mips64.cc
|
||||
@@ -898,19 +898,18 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
||||
__ Daddu(a2, a2, num_saved_registers_ * kIntSize);
|
||||
__ Sd(a2, MemOperand(frame_pointer(), kRegisterOutput));
|
||||
|
||||
- // Prepare a0 to initialize registers with its value in the next run.
|
||||
- __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
|
||||
-
|
||||
// Restore the original regexp stack pointer value (effectively, pop the
|
||||
// stored base pointer).
|
||||
PopRegExpBasePointer(backtrack_stackpointer(), a2);
|
||||
|
||||
+ Label reload_string_start_minus_one;
|
||||
+
|
||||
if (global_with_zero_length_check()) {
|
||||
// Special case for zero-length matches.
|
||||
// t3: capture start index
|
||||
// Not a zero-length match, restart.
|
||||
- __ Branch(
|
||||
- &load_char_start_regexp, ne, current_input_offset(), Operand(t3));
|
||||
+ __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
|
||||
+ Operand(t3));
|
||||
// Offset from the end is zero if we already reached the end.
|
||||
__ Branch(&exit_label_, eq, current_input_offset(),
|
||||
Operand(zero_reg));
|
||||
@@ -922,6 +921,11 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
||||
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
|
||||
}
|
||||
|
||||
+ __ bind(&reload_string_start_minus_one);
|
||||
+ // Prepare a0 to initialize registers with its value in the next run.
|
||||
+ // Must be immediately before the jump to avoid clobbering.
|
||||
+ __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
|
||||
+
|
||||
__ Branch(&load_char_start_regexp);
|
||||
} else {
|
||||
__ li(v0, Operand(SUCCESS));
|
||||
diff --git a/src/regexp/riscv/regexp-macro-assembler-riscv.cc b/src/regexp/riscv/regexp-macro-assembler-riscv.cc
|
||||
index c8f3eb551e05805003d30a1786acdd9aab96d906..c03be100849c50f471d6839d4cd960e5a78d67d3 100644
|
||||
--- a/src/regexp/riscv/regexp-macro-assembler-riscv.cc
|
||||
+++ b/src/regexp/riscv/regexp-macro-assembler-riscv.cc
|
||||
@@ -869,18 +869,17 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
|
||||
__ AddWord(a2, a2, num_saved_registers_ * kIntSize);
|
||||
__ StoreWord(a2, MemOperand(frame_pointer(), kRegisterOutput));
|
||||
|
||||
- // Prepare a0 to initialize registers with its value in the next run.
|
||||
- __ LoadWord(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
|
||||
-
|
||||
// Restore the original regexp stack pointer value (effectively, pop the
|
||||
// stored base pointer).
|
||||
PopRegExpBasePointer(backtrack_stackpointer(), a2);
|
||||
|
||||
+ Label reload_string_start_minus_one;
|
||||
+
|
||||
if (global_with_zero_length_check()) {
|
||||
// Special case for zero-length matches.
|
||||
// s3: capture start index
|
||||
// Not a zero-length match, restart.
|
||||
- __ Branch(&load_char_start_regexp, ne, current_input_offset(),
|
||||
+ __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
|
||||
Operand(s3));
|
||||
// Offset from the end is zero if we already reached the end.
|
||||
__ Branch(&exit_label_, eq, current_input_offset(),
|
||||
@@ -893,6 +892,12 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
|
||||
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
|
||||
}
|
||||
|
||||
+ __ bind(&reload_string_start_minus_one);
|
||||
+ // Prepare a0 to initialize registers with its value in the next run.
|
||||
+ // Must be immediately before the jump to avoid clobbering.
|
||||
+ __ LoadWord(a0,
|
||||
+ MemOperand(frame_pointer(), kStringStartMinusOne));
|
||||
+
|
||||
__ Branch(&load_char_start_regexp);
|
||||
} else {
|
||||
__ li(a0, Operand(SUCCESS));
|
||||
diff --git a/src/regexp/s390/regexp-macro-assembler-s390.cc b/src/regexp/s390/regexp-macro-assembler-s390.cc
|
||||
index a61bc379ba6c265ecb0c5cd7aa8d7a2e35ca6c1e..de184b95862e7f2e64d69cff6b60d866eb212f36 100644
|
||||
--- a/src/regexp/s390/regexp-macro-assembler-s390.cc
|
||||
+++ b/src/regexp/s390/regexp-macro-assembler-s390.cc
|
||||
@@ -947,19 +947,18 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
|
||||
__ AddS64(r4, Operand(num_saved_registers_ * kIntSize));
|
||||
__ StoreU64(r4, MemOperand(frame_pointer(), kRegisterOutput));
|
||||
|
||||
- // Prepare r2 to initialize registers with its value in the next run.
|
||||
- __ LoadU64(r2, MemOperand(frame_pointer(), kStringStartMinusOne));
|
||||
-
|
||||
// Restore the original regexp stack pointer value (effectively, pop the
|
||||
// stored base pointer).
|
||||
PopRegExpBasePointer(backtrack_stackpointer(), r4);
|
||||
|
||||
+ Label reload_string_start_minus_one;
|
||||
+
|
||||
if (global_with_zero_length_check()) {
|
||||
// Special case for zero-length matches.
|
||||
// r6: capture start index
|
||||
__ CmpS64(current_input_offset(), r6);
|
||||
// Not a zero-length match, restart.
|
||||
- __ bne(&load_char_start_regexp);
|
||||
+ __ bne(&reload_string_start_minus_one);
|
||||
// Offset from the end is zero if we already reached the end.
|
||||
__ CmpS64(current_input_offset(), Operand::Zero());
|
||||
__ beq(&exit_label_);
|
||||
@@ -970,6 +969,11 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
|
||||
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
|
||||
}
|
||||
|
||||
+ __ bind(&reload_string_start_minus_one);
|
||||
+ // Prepare r2 to initialize registers with its value in the next run.
|
||||
+ // Must be immediately before the jump to avoid clobbering.
|
||||
+ __ LoadU64(r2, MemOperand(frame_pointer(), kStringStartMinusOne));
|
||||
+
|
||||
__ b(&load_char_start_regexp);
|
||||
} else {
|
||||
__ mov(r2, Operand(SUCCESS));
|
||||
diff --git a/src/regexp/x64/regexp-macro-assembler-x64.cc b/src/regexp/x64/regexp-macro-assembler-x64.cc
|
||||
index 89fd2e34f1296113c43f16896d8f35d741782709..7c59534aa46c4c1c6fed151d7dad13070d133f47 100644
|
||||
--- a/src/regexp/x64/regexp-macro-assembler-x64.cc
|
||||
+++ b/src/regexp/x64/regexp-macro-assembler-x64.cc
|
||||
@@ -951,19 +951,18 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
||||
__ addq(Operand(rbp, kRegisterOutput),
|
||||
Immediate(num_saved_registers_ * kIntSize));
|
||||
|
||||
- // Prepare rax to initialize registers with its value in the next run.
|
||||
- __ movq(rax, Operand(rbp, kStringStartMinusOne));
|
||||
-
|
||||
// Restore the original regexp stack pointer value (effectively, pop the
|
||||
// stored base pointer).
|
||||
PopRegExpBasePointer(backtrack_stackpointer(), kScratchRegister);
|
||||
|
||||
+ Label reload_string_start_minus_one;
|
||||
+
|
||||
if (global_with_zero_length_check()) {
|
||||
// Special case for zero-length matches.
|
||||
// rdx: capture start index
|
||||
__ cmpq(rdi, rdx);
|
||||
// Not a zero-length match, restart.
|
||||
- __ j(not_equal, &load_char_start_regexp);
|
||||
+ __ j(not_equal, &reload_string_start_minus_one);
|
||||
// rdi (offset from the end) is zero if we already reached the end.
|
||||
__ testq(rdi, rdi);
|
||||
__ j(zero, &exit_label_, Label::kNear);
|
||||
@@ -978,6 +977,11 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
||||
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
|
||||
}
|
||||
|
||||
+ __ bind(&reload_string_start_minus_one);
|
||||
+ // Prepare rax to initialize registers with its value in the next run.
|
||||
+ // Must be immediately before the jump to avoid clobbering.
|
||||
+ __ movq(rax, Operand(rbp, kStringStartMinusOne));
|
||||
+
|
||||
__ jmp(&load_char_start_regexp);
|
||||
} else {
|
||||
__ Move(rax, SUCCESS);
|
||||
diff --git a/test/mjsunit/regress/regress-crbug-1439691.js b/test/mjsunit/regress/regress-crbug-1439691.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..6c55835535ab4f42ef0446abf863986962df9e9b
|
||||
--- /dev/null
|
||||
+++ b/test/mjsunit/regress/regress-crbug-1439691.js
|
||||
@@ -0,0 +1,7 @@
|
||||
+// Copyright 2023 the V8 project authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+function f0() {
|
||||
+}
|
||||
+/(?!(a))\1/gudyi[Symbol.replace]("f\uD83D\uDCA9ba\u2603", f0);
|
||||
@@ -0,0 +1,44 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Toon Verwaest <verwaest@chromium.org>
|
||||
Date: Fri, 16 Jun 2023 17:13:52 +0200
|
||||
Subject: Merged: [runtime] Set instance prototypes directly on maps
|
||||
|
||||
Bug: chromium:1452137
|
||||
(cherry picked from commit c7c447735f762f6d6d0878e229371797845ef4ab)
|
||||
|
||||
Change-Id: I611c41f942e2e51f3c4b4f1d119c18410617188e
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4637888
|
||||
Commit-Queue: Igor Sheludko <ishell@chromium.org>
|
||||
Auto-Submit: Igor Sheludko <ishell@chromium.org>
|
||||
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/11.4@{#47}
|
||||
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
|
||||
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
|
||||
|
||||
diff --git a/src/objects/js-function.cc b/src/objects/js-function.cc
|
||||
index 62fe309a471b323c1cb2a9a872380563bbdc369f..878ef8fd6b49debcd46f8d4f3693630fb02fef17 100644
|
||||
--- a/src/objects/js-function.cc
|
||||
+++ b/src/objects/js-function.cc
|
||||
@@ -672,6 +672,10 @@ void SetInstancePrototype(Isolate* isolate, Handle<JSFunction> function,
|
||||
// At that point, a new initial map is created and the prototype is put
|
||||
// into the initial map where it belongs.
|
||||
function->set_prototype_or_initial_map(*value, kReleaseStore);
|
||||
+ if (value->IsJSObjectThatCanBeTrackedAsPrototype()) {
|
||||
+ // Optimize as prototype to detach it from its transition tree.
|
||||
+ JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
|
||||
+ }
|
||||
} else {
|
||||
Handle<Map> new_map =
|
||||
Map::Copy(isolate, initial_map, "SetInstancePrototype");
|
||||
@@ -796,8 +800,10 @@ void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
|
||||
Handle<HeapObject> prototype;
|
||||
if (function->has_instance_prototype()) {
|
||||
prototype = handle(function->instance_prototype(), isolate);
|
||||
+ map->set_prototype(*prototype);
|
||||
} else {
|
||||
prototype = isolate->factory()->NewFunctionPrototype(function);
|
||||
+ Map::SetPrototype(isolate, map, prototype);
|
||||
}
|
||||
DCHECK(map->has_fast_object_elements());
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Pedro Pontes <pepontes@microsoft.com>
|
||||
Date: Thu, 29 Jun 2023 01:16:50 -0700
|
||||
Subject: Fix using shared objects as prototypes more (Partial backport)
|
||||
|
||||
The previous fix from
|
||||
https://chromium-review.googlesource.com/c/v8/v8/+/4086127 was
|
||||
insufficient. It prevented shared objects from being optimized as
|
||||
prototypes, but callers of OptimizeAsPrototype also assume that all
|
||||
JSObjects can track prototype users via prototype_info on the map.
|
||||
|
||||
This CL attempts a broader fix where shared objects are not considered
|
||||
optimizable as prototypes at all. When used as a prototype, shared
|
||||
objects are treated like non-JSObjects (e.g. JSProxy, WasmObject).
|
||||
|
||||
Bug: chromium:1401295, v8:12547
|
||||
Change-Id: I9886e9ccac9e597e7dd34a09083a096ff4e3bf16
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4112150
|
||||
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
|
||||
Commit-Queue: Shu-yu Guo <syg@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#84916}
|
||||
|
||||
diff --git a/src/objects/heap-object.h b/src/objects/heap-object.h
|
||||
index 806b34b969eeaccc7f16cfd0ac734d667b165943..b2d401ba823231f939b8d1ae4f44660360276053 100644
|
||||
--- a/src/objects/heap-object.h
|
||||
+++ b/src/objects/heap-object.h
|
||||
@@ -113,6 +113,8 @@ class HeapObject : public Object {
|
||||
STRUCT_LIST(DECL_STRUCT_PREDICATE)
|
||||
#undef DECL_STRUCT_PREDICATE
|
||||
|
||||
+ V8_INLINE bool IsJSObjectThatCanBeTrackedAsPrototype() const;
|
||||
+
|
||||
// Converts an address to a HeapObject pointer.
|
||||
static inline HeapObject FromAddress(Address address) {
|
||||
DCHECK_TAG_ALIGNED(address);
|
||||
diff --git a/src/objects/objects-inl.h b/src/objects/objects-inl.h
|
||||
index 025c87dbf313cc4b3adb884b4b2d96940c4ce389..baa1167a123b4c161d06b9869938d3cbd4f15fb2 100644
|
||||
--- a/src/objects/objects-inl.h
|
||||
+++ b/src/objects/objects-inl.h
|
||||
@@ -83,6 +83,11 @@ bool Object::InSharedWritableHeap() const {
|
||||
return IsHeapObject() && HeapObject::cast(*this).InSharedWritableHeap();
|
||||
}
|
||||
|
||||
+bool Object::IsJSObjectThatCanBeTrackedAsPrototype() const {
|
||||
+ return IsHeapObject() &&
|
||||
+ HeapObject::cast(*this).IsJSObjectThatCanBeTrackedAsPrototype();
|
||||
+}
|
||||
+
|
||||
#define IS_TYPE_FUNCTION_DEF(type_) \
|
||||
bool Object::Is##type_() const { \
|
||||
return IsHeapObject() && HeapObject::cast(*this).Is##type_(); \
|
||||
@@ -189,6 +194,13 @@ bool HeapObject::InSharedWritableHeap() const {
|
||||
return BasicMemoryChunk::FromHeapObject(*this)->InSharedHeap();
|
||||
}
|
||||
|
||||
+bool HeapObject::IsJSObjectThatCanBeTrackedAsPrototype() const {
|
||||
+ // Do not optimize objects in the shared heap because it is not
|
||||
+ // threadsafe. Objects in the shared heap have fixed layouts and their maps
|
||||
+ // never change.
|
||||
+ return IsJSObject() && !InSharedWritableHeap();
|
||||
+}
|
||||
+
|
||||
bool HeapObject::IsNullOrUndefined(Isolate* isolate) const {
|
||||
return IsNullOrUndefined(ReadOnlyRoots(isolate));
|
||||
}
|
||||
diff --git a/src/objects/objects.h b/src/objects/objects.h
|
||||
index c3a0cbf15a329d0e4e68aa5fd379352a1cc061ba..8814ddadc4bfaac6e243a94c4890147b6ea5b4b9 100644
|
||||
--- a/src/objects/objects.h
|
||||
+++ b/src/objects/objects.h
|
||||
@@ -341,6 +341,8 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
|
||||
bool IsWasmObject(Isolate* = nullptr) const { return false; }
|
||||
#endif
|
||||
|
||||
+ V8_INLINE bool IsJSObjectThatCanBeTrackedAsPrototype() const;
|
||||
+
|
||||
enum class Conversion { kToNumber, kToNumeric };
|
||||
|
||||
#define DECL_STRUCT_PREDICATE(NAME, Name, name) \
|
||||
@@ -0,0 +1,4 @@
|
||||
cherry-pick-e0efbd45ea74.patch
|
||||
cherry-pick-218b56e51638.patch
|
||||
m114_move_transceiver_iteration_loop_over_to_the_signaling_thread.patch
|
||||
m114_sdp_reject_duplicate_ssrcs_in_ssrc-groups.patch
|
||||
|
||||
59
patches/webrtc/cherry-pick-218b56e51638.patch
Normal file
59
patches/webrtc/cherry-pick-218b56e51638.patch
Normal file
@@ -0,0 +1,59 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Cooper <alcooper@chromium.org>
|
||||
Date: Wed, 8 Feb 2023 14:16:01 -0800
|
||||
Subject: Fix Destruction inside WGC Callback
|
||||
|
||||
If we are notified of the destruction of the window before a
|
||||
CaptureFrame call can fail, then we may end up attempting to destroy the
|
||||
underlying WGC object inside it's own event handler. This can be
|
||||
problematic, as the class itself may want to run other code. Instead,
|
||||
we just unsubscribe and signal that any future CaptureFrame calls should
|
||||
reject.
|
||||
|
||||
This also removes setting "is_capture_started_=false" in the item closed
|
||||
handler, as all that served to do is cause the WgcCapturerWin code to
|
||||
attempt to restart the capturer, and somewhat muddies up our metrics.
|
||||
|
||||
(cherry picked from commit 318cf28945d80a0ac6f09382e507c95e649cc4c1)
|
||||
|
||||
Bug: chromium:1413005
|
||||
No-Try: True
|
||||
Change-Id: Ibccb7a2e7ce531ba80b4b331b9bc2cda0ff75f4e
|
||||
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/292762
|
||||
Auto-Submit: Alexander Cooper <alcooper@chromium.org>
|
||||
Reviewed-by: Mark Foltz <mfoltz@chromium.org>
|
||||
Commit-Queue: Mark Foltz <mfoltz@chromium.org>
|
||||
Commit-Queue: Alexander Cooper <alcooper@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#39275}
|
||||
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/293246
|
||||
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5481@{#5}
|
||||
Cr-Branched-From: 2e1a9a4ae0234d4b1ea7a6fd4188afa1fb20379d-refs/heads/main@{#38901}
|
||||
|
||||
diff --git a/modules/desktop_capture/win/wgc_capture_session.cc b/modules/desktop_capture/win/wgc_capture_session.cc
|
||||
index 831257b4d476d674303f835f6002b22bf809a772..20045b6d1d1250fc9b634e51fe3875b484d6c397 100644
|
||||
--- a/modules/desktop_capture/win/wgc_capture_session.cc
|
||||
+++ b/modules/desktop_capture/win/wgc_capture_session.cc
|
||||
@@ -388,17 +388,14 @@ HRESULT WgcCaptureSession::OnItemClosed(WGC::IGraphicsCaptureItem* sender,
|
||||
|
||||
RTC_LOG(LS_INFO) << "Capture target has been closed.";
|
||||
item_closed_ = true;
|
||||
- is_capture_started_ = false;
|
||||
|
||||
RemoveEventHandlers();
|
||||
|
||||
- mapped_texture_ = nullptr;
|
||||
- session_ = nullptr;
|
||||
- frame_pool_ = nullptr;
|
||||
- direct3d_device_ = nullptr;
|
||||
- item_ = nullptr;
|
||||
- d3d11_device_ = nullptr;
|
||||
-
|
||||
+ // Do not attempt to free resources in the OnItemClosed handler, as this
|
||||
+ // causes a race where we try to delete the item that is calling us. Removing
|
||||
+ // the event handlers and setting `item_closed_` above is sufficient to ensure
|
||||
+ // that the resources are no longer used, and the next time the capturer tries
|
||||
+ // to get a frame, we will report a permanent failure and be destroyed.
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user