mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
150 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b8d60305b | ||
|
|
1f6e825a9f | ||
|
|
c9774944ba | ||
|
|
99a521ecbe | ||
|
|
d3152808bb | ||
|
|
3fe97b1b1b | ||
|
|
95d9d7ddfe | ||
|
|
5593485831 | ||
|
|
049b1d0817 | ||
|
|
a5e40fea7d | ||
|
|
840ff8d720 | ||
|
|
f8738fb355 | ||
|
|
16568d71e4 | ||
|
|
8f1074c204 | ||
|
|
0b6842d429 | ||
|
|
4f4c6a2161 | ||
|
|
95b81c16c4 | ||
|
|
bb913bc17b | ||
|
|
7c72a36b15 | ||
|
|
792d189241 | ||
|
|
602f65ab5d | ||
|
|
18d60df173 | ||
|
|
ce12429814 | ||
|
|
b44be57752 | ||
|
|
7d8616b2b7 | ||
|
|
35b0e35544 | ||
|
|
93b44837a2 | ||
|
|
e16d593fcb | ||
|
|
51f9712c8f | ||
|
|
36cdfef776 | ||
|
|
8920fd100e | ||
|
|
4142f4e74e | ||
|
|
ffd43c97f2 | ||
|
|
a576c92d4b | ||
|
|
9c3da1cb35 | ||
|
|
2e5c33a25b | ||
|
|
beca2c5c02 | ||
|
|
4b24e2b045 | ||
|
|
1f1ff0e51f | ||
|
|
e744ac042a | ||
|
|
12a9970969 | ||
|
|
bb915813d7 | ||
|
|
2e9a3d6f28 | ||
|
|
91c465dcea | ||
|
|
200e7294de | ||
|
|
c2cef0aa02 | ||
|
|
581b47582f | ||
|
|
59951f344b | ||
|
|
6e9db782c7 | ||
|
|
a64d0713cd | ||
|
|
e7d7c66636 | ||
|
|
c6f8625947 | ||
|
|
1c198eef50 | ||
|
|
dc664acab2 | ||
|
|
6b89037dea | ||
|
|
d3e828cc4e | ||
|
|
acabbf22fe | ||
|
|
ee95a258b3 | ||
|
|
072bec5d01 | ||
|
|
c3da53d3c0 | ||
|
|
2345ff0644 | ||
|
|
a217df4a9d | ||
|
|
4de0f99073 | ||
|
|
4f3b520516 | ||
|
|
4293389679 | ||
|
|
7c1335ec1c | ||
|
|
779efcfa11 | ||
|
|
bd08155093 | ||
|
|
f71c2c78dd | ||
|
|
5e30c0ae26 | ||
|
|
7966baff5a | ||
|
|
986d23d793 | ||
|
|
afb74be01a | ||
|
|
8068b39ddc | ||
|
|
e8ae6fe0d0 | ||
|
|
b5de6d9440 | ||
|
|
a2f777213d | ||
|
|
f916f172e0 | ||
|
|
6606b743c0 | ||
|
|
ee86f029d8 | ||
|
|
8baf1dc0e5 | ||
|
|
0827a06b1e | ||
|
|
2aec5c5df5 | ||
|
|
5483733b1b | ||
|
|
52f8f91931 | ||
|
|
227d6ead6d | ||
|
|
fb4cd68f93 | ||
|
|
7d3db3d7f8 | ||
|
|
9510e1f6e4 | ||
|
|
a396489101 | ||
|
|
b90f5435a9 | ||
|
|
13a0757acb | ||
|
|
a5a6f12e1d | ||
|
|
cef56e162f | ||
|
|
a73163d09a | ||
|
|
2e98e11364 | ||
|
|
0ead47ffea | ||
|
|
1897909a50 | ||
|
|
62b2243574 | ||
|
|
6e35f2b7dd | ||
|
|
c4bf95576c | ||
|
|
4005935937 | ||
|
|
31fa081da1 | ||
|
|
340b4a2c1e | ||
|
|
fd269ec973 | ||
|
|
d133ec709f | ||
|
|
2b76ac0848 | ||
|
|
726e3f9bb8 | ||
|
|
bc336e16ef | ||
|
|
1faf18f2d4 | ||
|
|
4a1e299053 | ||
|
|
ae1f1f2dfa | ||
|
|
fe4bc1d568 | ||
|
|
d6d9d954b4 | ||
|
|
2ee375c5bf | ||
|
|
c04ec2d332 | ||
|
|
4f9122647a | ||
|
|
846504af8e | ||
|
|
5d97320ba3 | ||
|
|
2aaa5438cd | ||
|
|
08da5ee22a | ||
|
|
f3a4b44662 | ||
|
|
424177164e | ||
|
|
079251f168 | ||
|
|
17054405d8 | ||
|
|
d1d8c9badd | ||
|
|
700c410ec3 | ||
|
|
d3f7ad2035 | ||
|
|
f5deaedfaa | ||
|
|
2717a48f30 | ||
|
|
fea41c6f6d | ||
|
|
d58bfdcdfd | ||
|
|
d0451832ed | ||
|
|
22481aa347 | ||
|
|
7b0bb0b637 | ||
|
|
36f8e9daa2 | ||
|
|
4594af595e | ||
|
|
0bbd268eb4 | ||
|
|
47b9207e6d | ||
|
|
846412cdf1 | ||
|
|
b77e48a2c7 | ||
|
|
87d98480fa | ||
|
|
6d468cd9b5 | ||
|
|
38e585434f | ||
|
|
5481d27bcd | ||
|
|
135133e391 | ||
|
|
ad8de076e3 | ||
|
|
5bad2d106c | ||
|
|
883b089e0f | ||
|
|
d0abffc1e7 |
@@ -300,23 +300,26 @@ step-setup-goma-for-build: &step-setup-goma-for-build
|
||||
npm install
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
node -e "require('./src/utils/goma.js').ensure()"
|
||||
third_party/goma/goma_ctl.py ensure_start
|
||||
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
|
||||
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
|
||||
echo 'export GOMA_FALLBACK_ON_AUTH_FAILURE=true' >> $BASH_ENV
|
||||
cd ..
|
||||
|
||||
step-restore-brew-cache: &step-restore-brew-cache
|
||||
restore_cache:
|
||||
paths:
|
||||
- /usr/local/Homebrew
|
||||
- /usr/local/Cellar/gnu-tar
|
||||
- /usr/local/bin/gtar
|
||||
keys:
|
||||
- v1-brew-cache-{{ arch }}
|
||||
- v4-brew-cache-{{ arch }}
|
||||
|
||||
step-save-brew-cache: &step-save-brew-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- /usr/local/Homebrew
|
||||
key: v1-brew-cache-{{ arch }}
|
||||
- /usr/local/Cellar/gnu-tar
|
||||
- /usr/local/bin/gtar
|
||||
key: v4-brew-cache-{{ arch }}
|
||||
name: Persisting brew cache
|
||||
|
||||
step-get-more-space-on-mac: &step-get-more-space-on-mac
|
||||
@@ -392,8 +395,10 @@ step-install-gnutar-on-mac: &step-install-gnutar-on-mac
|
||||
name: Install gnu-tar on macos
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
brew update
|
||||
brew install gnu-tar
|
||||
if [ ! -d /usr/local/Cellar/gnu-tar/ ]; then
|
||||
brew update
|
||||
brew install gnu-tar
|
||||
fi
|
||||
ln -fs /usr/local/bin/gtar /usr/local/bin/tar
|
||||
fi
|
||||
|
||||
@@ -801,6 +806,8 @@ step-ninja-summary: &step-ninja-summary
|
||||
run:
|
||||
name: Print ninja summary
|
||||
command: |
|
||||
set +e
|
||||
set +o pipefail
|
||||
python depot_tools/post_build_ninja_summary.py -C src/out/Default
|
||||
|
||||
step-ninja-report: &step-ninja-report
|
||||
@@ -1005,7 +1012,6 @@ steps-checkout-and-save-cache: &steps-checkout-and-save-cache
|
||||
- *step-maybe-early-exit-doc-only-change
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-restore-brew-cache
|
||||
- *step-get-more-space-on-mac
|
||||
- *step-install-gnutar-on-mac
|
||||
|
||||
|
||||
13
BUILD.gn
13
BUILD.gn
@@ -1116,6 +1116,19 @@ if (is_mac) {
|
||||
"//build/config/win:delayloads",
|
||||
]
|
||||
|
||||
if (current_cpu == "x86") {
|
||||
# Set the initial stack size to 0.5MiB, instead of the 1.5MiB needed by
|
||||
# Chrome's main thread. This saves significant memory on threads (like
|
||||
# those in the Windows thread pool, and others) whose stack size we can
|
||||
# only control through this setting. Because Chrome's main thread needs
|
||||
# a minimum 1.5 MiB stack, the main thread (in 32-bit builds only) uses
|
||||
# fibers to switch to a 1.5 MiB stack before running any other code.
|
||||
ldflags += [ "/STACK:0x80000" ]
|
||||
} else {
|
||||
# Increase the initial stack size. The default is 1MB, this is 8MB.
|
||||
ldflags += [ "/STACK:0x800000" ]
|
||||
}
|
||||
|
||||
# This is to support renaming of electron.exe. node-gyp has hard-coded
|
||||
# executable names which it will recognise as node. This module definition
|
||||
# file claims that the electron executable is in fact named "node.exe",
|
||||
|
||||
@@ -1 +1 @@
|
||||
10.1.7
|
||||
10.4.4
|
||||
@@ -28,15 +28,12 @@ The preferred method is to install Electron as a development dependency in your
|
||||
app:
|
||||
|
||||
```sh
|
||||
npm install electron --save-dev [--save-exact]
|
||||
npm install electron --save-dev
|
||||
```
|
||||
|
||||
The `--save-exact` flag is recommended for Electron prior to version 2, as it does not follow semantic
|
||||
versioning. As of version 2.0.0, Electron follows semver, so you don't need `--save-exact` flag. For info on how to manage Electron versions in your apps, see
|
||||
[Electron versioning](docs/tutorial/electron-versioning.md).
|
||||
|
||||
For more installation options and troubleshooting tips, see
|
||||
[installation](docs/tutorial/installation.md).
|
||||
[installation](docs/tutorial/installation.md). For info on how to manage Electron versions in your apps, see
|
||||
[Electron versioning](docs/tutorial/electron-versioning.md).
|
||||
|
||||
## Quick start & Electron Fiddle
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ environment:
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
|
||||
GOMA_FALLBACK_ON_AUTH_FAILURE: true
|
||||
notifications:
|
||||
- provider: Webhook
|
||||
url: https://electron-mission-control.herokuapp.com/rest/appveyor-hook
|
||||
|
||||
@@ -92,6 +92,6 @@ steps:
|
||||
condition: always()
|
||||
|
||||
- powershell: |
|
||||
Remove-Item -path $env:APPDATA/Electron* -Recurse
|
||||
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore
|
||||
displayName: 'Delete user app data directories'
|
||||
condition: always()
|
||||
|
||||
@@ -41,14 +41,14 @@ ipcMain.handle('bootstrap', (event) => {
|
||||
return isTrustedSender(event.sender) ? electronPath : null;
|
||||
});
|
||||
|
||||
async function createWindow () {
|
||||
async function createWindow (backgroundColor?: string) {
|
||||
await app.whenReady();
|
||||
|
||||
const options: Electron.BrowserWindowConstructorOptions = {
|
||||
width: 960,
|
||||
height: 620,
|
||||
autoHideMenuBar: true,
|
||||
backgroundColor: '#2f3241',
|
||||
backgroundColor,
|
||||
webPreferences: {
|
||||
preload: path.resolve(__dirname, 'preload.js'),
|
||||
contextIsolation: true,
|
||||
@@ -96,7 +96,7 @@ export const loadURL = async (appUrl: string) => {
|
||||
};
|
||||
|
||||
export const loadFile = async (appPath: string) => {
|
||||
mainWindow = await createWindow();
|
||||
mainWindow = await createWindow(appPath === 'index.html' ? '#2f3241' : undefined);
|
||||
mainWindow.loadFile(appPath);
|
||||
mainWindow.focus();
|
||||
};
|
||||
|
||||
@@ -1829,6 +1829,13 @@ Replacement API for setBrowserView supporting work with multi browser views.
|
||||
|
||||
* `browserView` [BrowserView](browser-view.md)
|
||||
|
||||
#### `win.setTopBrowserView(browserView)` _Experimental_
|
||||
|
||||
* `browserView` [BrowserView](browser-view.md)
|
||||
|
||||
Raises `browserView` above other `BrowserView`s attached to `win`.
|
||||
Throws an error if `browserView` is not attached to `win`.
|
||||
|
||||
#### `win.getBrowserViews()` _Experimental_
|
||||
|
||||
Returns `BrowserView[]` - an array of all BrowserViews that have been attached
|
||||
|
||||
@@ -114,3 +114,9 @@ The following methods of `chrome.management` are supported:
|
||||
- `chrome.management.getPermissionWarningsByManifest`
|
||||
- `chrome.management.onEnabled`
|
||||
- `chrome.management.onDisabled`
|
||||
|
||||
### `chrome.webRequest`
|
||||
|
||||
All features of this API are supported.
|
||||
|
||||
> **NOTE:** Electron's [`webRequest`](web-request.md) module takes precedence over `chrome.webRequest` if there are conflicting handlers.
|
||||
|
||||
@@ -9,7 +9,7 @@ with the operating system so that you can customize the operations for various
|
||||
shortcuts.
|
||||
|
||||
**Note:** The shortcut is global; it will work even if the app does
|
||||
not have the keyboard focus. You should not use this module until the `ready`
|
||||
not have the keyboard focus. This module cannot be used before the `ready`
|
||||
event of the app module is emitted.
|
||||
|
||||
```javascript
|
||||
|
||||
@@ -61,9 +61,13 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
|
||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects is deprecated, and will begin throwing an exception
|
||||
> starting with Electron 9.
|
||||
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects will throw an exception.
|
||||
>
|
||||
> Since the main process does not have support for DOM objects such as
|
||||
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
|
||||
> Electron's IPC to the main process, as the main process would have no way to decode
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
The main process handles it by listening for `channel` with the
|
||||
[`ipcMain`](ipc-main.md) module.
|
||||
@@ -85,9 +89,13 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
|
||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects is deprecated, and will begin throwing an exception
|
||||
> starting with Electron 9.
|
||||
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects will throw an exception.
|
||||
>
|
||||
> Since the main process does not have support for DOM objects such as
|
||||
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
|
||||
> Electron's IPC to the main process, as the main process would have no way to decode
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
The main process should listen for `channel` with
|
||||
[`ipcMain.handle()`](ipc-main.md#ipcmainhandlechannel-listener).
|
||||
@@ -123,9 +131,13 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
|
||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects is deprecated, and will begin throwing an exception
|
||||
> starting with Electron 9.
|
||||
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects will throw an exception.
|
||||
>
|
||||
> Since the main process does not have support for DOM objects such as
|
||||
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
|
||||
> Electron's IPC to the main process, as the main process would have no way to decode
|
||||
> them. Attempting to send such objects over IPC will result in an error.
|
||||
|
||||
The main process handles it by listening for `channel` with [`ipcMain`](ipc-main.md) module,
|
||||
and replies by setting `event.returnValue`.
|
||||
|
||||
@@ -22,8 +22,10 @@ Sets `menu` as the application menu on macOS. On Windows and Linux, the
|
||||
Also on Windows and Linux, you can use a `&` in the top-level item name to
|
||||
indicate which letter should get a generated accelerator. For example, using
|
||||
`&File` for the file menu would result in a generated `Alt-F` accelerator that
|
||||
opens the associated menu. The indicated character in the button label gets an
|
||||
underline. The `&` character is not displayed on the button label.
|
||||
opens the associated menu. The indicated character in the button label then gets an
|
||||
underline, and the `&` character is not displayed on the button label.
|
||||
|
||||
In order to escape the `&` character in an item name, add a proceeding `&`. For example, `&&File` would result in `&File` displayed on the button label.
|
||||
|
||||
Passing `null` will suppress the default menu. On Windows and Linux,
|
||||
this has the additional effect of removing the menu bar from the window.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# IpcMainEvent Object extends `Event`
|
||||
|
||||
* `processId` Integer - The internal ID of the renderer process that sent this message
|
||||
* `frameId` Integer - The ID of the renderer frame that sent this message
|
||||
* `returnValue` any - Set this to the value to be returned in a synchronous message
|
||||
* `sender` WebContents - Returns the `webContents` that sent the message
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# IpcMainInvokeEvent Object extends `Event`
|
||||
|
||||
* `processId` Integer - The internal ID of the renderer process that sent this message
|
||||
* `frameId` Integer - The ID of the renderer frame that sent this message
|
||||
* `sender` WebContents - Returns the `webContents` that sent the message
|
||||
|
||||
@@ -132,6 +132,8 @@ This is necessary for events such as `NSUserDefaultsDidChangeNotification`.
|
||||
* `userInfo` Record<String, unknown>
|
||||
* `object` String
|
||||
|
||||
Returns `Number` - The ID of this subscription
|
||||
|
||||
Same as `subscribeNotification`, but uses `NSWorkspace.sharedWorkspace.notificationCenter`.
|
||||
This is necessary for events such as `NSWorkspaceDidActivateApplicationNotification`.
|
||||
|
||||
|
||||
@@ -1549,8 +1549,7 @@ included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects is deprecated, and will begin throwing an exception
|
||||
> starting with Electron 9.
|
||||
> special Electron objects will throw an exception.
|
||||
|
||||
The renderer process can handle the message by listening to `channel` with the
|
||||
[`ipcRenderer`](ipc-renderer.md) module.
|
||||
@@ -1586,7 +1585,9 @@ app.whenReady().then(() => {
|
||||
|
||||
#### `contents.sendToFrame(frameId, channel, ...args)`
|
||||
|
||||
* `frameId` Integer
|
||||
* `frameId` Integer | [number, number] - the ID of the frame to send to, or a
|
||||
pair of `[processId, frameId]` if the frame is in a different process to the
|
||||
main frame.
|
||||
* `channel` String
|
||||
* `...args` any[]
|
||||
|
||||
@@ -1596,9 +1597,8 @@ Send an asynchronous message to a specific frame in a renderer process via
|
||||
chains will not be included. Sending Functions, Promises, Symbols, WeakMaps, or
|
||||
WeakSets will throw an exception.
|
||||
|
||||
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects is deprecated, and will begin throwing an exception
|
||||
> starting with Electron 9.
|
||||
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
|
||||
> special Electron objects will throw an exception.
|
||||
|
||||
The renderer process can handle the message by listening to `channel` with the
|
||||
[`ipcRenderer`](ipc-renderer.md) module.
|
||||
@@ -1760,7 +1760,7 @@ Returns `Boolean` - If *offscreen rendering* is enabled returns whether it is cu
|
||||
* `fps` Integer
|
||||
|
||||
If *offscreen rendering* is enabled sets the frame rate to the specified number.
|
||||
Only values between 1 and 60 are accepted.
|
||||
Only values between 1 and 240 are accepted.
|
||||
|
||||
#### `contents.getFrameRate()`
|
||||
|
||||
@@ -1858,7 +1858,7 @@ The zoom factor is the zoom percent divided by 100, so 300% = 3.0.
|
||||
#### `contents.frameRate`
|
||||
|
||||
An `Integer` property that sets the frame rate of the web contents to the specified number.
|
||||
Only values between 1 and 60 are accepted.
|
||||
Only values between 1 and 240 are accepted.
|
||||
|
||||
Only applicable if *offscreen rendering* is enabled.
|
||||
|
||||
|
||||
@@ -368,6 +368,52 @@ in Electron 8.x, and cease to exist in Electron 9.x. The layout zoom level
|
||||
limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
|
||||
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
|
||||
|
||||
### Deprecated events in `systemPreferences`
|
||||
|
||||
The following `systemPreferences` events have been deprecated:
|
||||
* `inverted-color-scheme-changed`
|
||||
* `high-contrast-color-scheme-changed`
|
||||
|
||||
Use the new `updated` event on the `nativeTheme` module instead.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
systemPreferences.on('inverted-color-scheme-changed', () => { /* ... */ })
|
||||
systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })
|
||||
|
||||
// Replace with
|
||||
nativeTheme.on('updated', () => { /* ... */ })
|
||||
```
|
||||
|
||||
### Deprecated: methods in `systemPreferences`
|
||||
|
||||
The following `systemPreferences` methods have been deprecated:
|
||||
* `systemPreferences.isDarkMode()`
|
||||
* `systemPreferences.isInvertedColorScheme()`
|
||||
* `systemPreferences.isHighContrastColorScheme()`
|
||||
|
||||
Use the following `nativeTheme` properties instead:
|
||||
* `nativeTheme.shouldUseDarkColors`
|
||||
* `nativeTheme.shouldUseInvertedColorScheme`
|
||||
* `nativeTheme.shouldUseHighContrastColors`
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
systemPreferences.isDarkMode()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseDarkColors
|
||||
|
||||
// Deprecated
|
||||
systemPreferences.isInvertedColorScheme()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseInvertedColorScheme
|
||||
|
||||
// Deprecated
|
||||
systemPreferences.isHighContrastColorScheme()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseHighContrastColors
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (7.0)
|
||||
|
||||
### Deprecated: Atom.io Node Headers URL
|
||||
|
||||
@@ -42,7 +42,7 @@ $ pip install pyobjc
|
||||
If you're developing Electron and don't plan to redistribute your
|
||||
custom Electron build, you may skip this section.
|
||||
|
||||
Official Electron builds are built with [Xcode 9.4.1](http://adcdownload.apple.com/Developer_Tools/Xcode_9.4.1/Xcode_9.4.1.xip), and the macOS 10.13 SDK. Building with a newer SDK works too, but the releases currently use the 10.13 SDK.
|
||||
Official Electron builds are built with [Xcode 11.1](https://download.developer.apple.com/Developer_Tools/Xcode_11.1/Xcode_11.1.xip), and the macOS 10.15 SDK. Building with a newer SDK works too, but the releases currently use the 10.15 SDK.
|
||||
|
||||
## Building Electron
|
||||
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
# DevTools Extension
|
||||
|
||||
Electron supports the [Chrome DevTools Extension][devtools-extension], which can
|
||||
be used to extend the ability of devtools for debugging popular web frameworks.
|
||||
Electron supports [Chrome DevTools extensions][devtools-extension], which can
|
||||
be used to extend the ability of Chrome's developer tools for debugging
|
||||
popular web frameworks.
|
||||
|
||||
## How to load a DevTools Extension
|
||||
## Loading a DevTools extension with tooling
|
||||
|
||||
This document outlines the process for manually loading an extension.
|
||||
You may also try
|
||||
[electron-devtools-installer](https://github.com/GPMDP/electron-devtools-installer),
|
||||
a third-party tool that downloads extensions directly from the Chrome WebStore.
|
||||
The easiest way to load a DevTools extension is to use third-party tooling to automate the
|
||||
process for you. [electron-devtools-installer][electron-devtools-installer] is a popular
|
||||
NPM package that does just that.
|
||||
|
||||
To load an extension in Electron, you need to download it in Chrome browser,
|
||||
locate its filesystem path, and then load it by calling the
|
||||
`BrowserWindow.addDevToolsExtension(extension)` API.
|
||||
## Manually loading a DevTools extension
|
||||
|
||||
Using the [React Developer Tools][react-devtools] as example:
|
||||
If you don't want to use the tooling approach, you can also do all of the necessary
|
||||
operations by hand. To load an extension in Electron, you need to download it via Chrome,
|
||||
locate its filesystem path, and then load it into your [Session][session] by calling the
|
||||
[`ses.loadExtension`] API.
|
||||
|
||||
1. Install it in Chrome browser.
|
||||
Using the [React Developer Tools][react-devtools] as an example:
|
||||
|
||||
1. Install the extension in Google Chrome.
|
||||
1. Navigate to `chrome://extensions`, and find its extension ID, which is a hash
|
||||
string like `fmkadmapgofadopljbjfkapdkoienihi`.
|
||||
1. Find out filesystem location used by Chrome for storing extensions:
|
||||
1. Find out the filesystem location used by Chrome for storing extensions:
|
||||
* on Windows it is `%LOCALAPPDATA%\Google\Chrome\User Data\Default\Extensions`;
|
||||
* on Linux it could be:
|
||||
* `~/.config/google-chrome/Default/Extensions/`
|
||||
@@ -27,36 +30,48 @@ Using the [React Developer Tools][react-devtools] as example:
|
||||
* `~/.config/google-chrome-canary/Default/Extensions/`
|
||||
* `~/.config/chromium/Default/Extensions/`
|
||||
* on macOS it is `~/Library/Application Support/Google/Chrome/Default/Extensions`.
|
||||
1. Pass the location of the extension to `BrowserWindow.addDevToolsExtension`
|
||||
API, for the React Developer Tools, it is something like:
|
||||
1. Pass the location of the extension to the [`ses.loadExtension`][load-extension]
|
||||
API. For React Developer Tools `v4.9.0`, it looks something like:
|
||||
```javascript
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
const { app, session } = require('electron')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
|
||||
BrowserWindow.addDevToolsExtension(
|
||||
path.join(os.homedir(), '/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/4.3.0_0')
|
||||
)
|
||||
// on macOS
|
||||
const reactDevToolsPath = path.join(
|
||||
os.homedir(),
|
||||
'/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/4.9.0_0'
|
||||
)
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
await session.defaultSession.loadExtension(reactDevToolsPath)
|
||||
})
|
||||
```
|
||||
|
||||
**Note:** The `BrowserWindow.addDevToolsExtension` API cannot be called before the
|
||||
ready event of the app module is emitted.
|
||||
**Notes:**
|
||||
|
||||
The extension will be remembered so you only need to call this API once per
|
||||
extension. If you try to add an extension that has already been loaded, this method
|
||||
will not return and instead log a warning to the console.
|
||||
* `loadExtension` returns a Promise with an [Extension object][extension-structure],
|
||||
which contains metadata about the extension that was loaded. This promise needs to
|
||||
resolve (e.g. with an `await` expression) before loading a page. Otherwise, the
|
||||
extension won't be guaranteed to load.
|
||||
* `loadExtension` cannot be called before the `ready` event of the `app` module
|
||||
is emitted, nor can it be called on in-memory (non-persistent) sessions.
|
||||
* `loadExtension` must be called on every boot of your app if you want the
|
||||
extension to be loaded.
|
||||
|
||||
### How to remove a DevTools Extension
|
||||
### Removing a DevTools extension
|
||||
|
||||
You can pass the name of the extension to the `BrowserWindow.removeDevToolsExtension`
|
||||
API to remove it. The name of the extension is returned by
|
||||
`BrowserWindow.addDevToolsExtension` and you can get the names of all installed
|
||||
DevTools Extensions using the `BrowserWindow.getDevToolsExtensions` API.
|
||||
You can pass the extension's ID to the [`ses.removeExtension`][remove-extension] API to
|
||||
remove it from your Session. Loaded extensions are not persisted between
|
||||
app launches.
|
||||
|
||||
## Supported DevTools Extensions
|
||||
## DevTools extension support
|
||||
|
||||
Electron only supports a limited set of `chrome.*` APIs, so some extensions
|
||||
using unsupported `chrome.*` APIs for chrome extension features may not work.
|
||||
Following Devtools Extensions are tested and guaranteed to work in Electron:
|
||||
Electron only supports
|
||||
[a limited set of `chrome.*` APIs][supported-extension-apis],
|
||||
so extensions using unsupported `chrome.*` APIs under the hood may not work.
|
||||
|
||||
The following Devtools extensions have been tested to work in Electron:
|
||||
|
||||
* [Ember Inspector](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
|
||||
* [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)
|
||||
@@ -68,14 +83,22 @@ Following Devtools Extensions are tested and guaranteed to work in Electron:
|
||||
* [Redux DevTools Extension](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd)
|
||||
* [MobX Developer Tools](https://chrome.google.com/webstore/detail/mobx-developer-tools/pfgnfdagidkfgccljigdamigbcnndkod)
|
||||
|
||||
### What should I do if a DevTools Extension is not working?
|
||||
### What should I do if a DevTools extension is not working?
|
||||
|
||||
First please make sure the extension is still being maintained, some extensions
|
||||
can not even work for recent versions of Chrome browser, and we are not able to
|
||||
do anything for them.
|
||||
First, please make sure the extension is still being maintained and is compatible
|
||||
with the latest version of Google Chrome. We cannot provide additional support for
|
||||
unsupported extensions.
|
||||
|
||||
Then file a bug at Electron's issues list, and describe which part of the
|
||||
extension is not working as expected.
|
||||
If the extension works on Chrome but not on Electron, file a bug in Electron's
|
||||
[issue tracker][issue-tracker] and describe which part
|
||||
of the extension is not working as expected.
|
||||
|
||||
[devtools-extension]: https://developer.chrome.com/extensions/devtools
|
||||
[session]: ../api/session.md
|
||||
[react-devtools]: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
|
||||
[load-extension]: ../api/session.md#sesloadextensionpath
|
||||
[extension-structure]: ../api/structures/extension.md
|
||||
[remove-extension]: ../api/session.md#sesremoveextensionextensionid
|
||||
[electron-devtools-installer]: https://github.com/MarshallOfSound/electron-devtools-installer
|
||||
[supported-extension-apis]: ../api/extensions.md
|
||||
[issue-tracker]: https://github.com/electron/electron/issues
|
||||
|
||||
@@ -9,7 +9,7 @@ Two modes of rendering can be used and only the dirty area is passed in the
|
||||
`'paint'` event to be more efficient. The rendering can be stopped, continued
|
||||
and the frame rate can be set. The specified frame rate is a top limit value,
|
||||
when there is nothing happening on a webpage, no frames are generated. The
|
||||
maximum frame rate is 60, because above that there is no benefit, only
|
||||
maximum frame rate is 240, because above that there is no benefit, only
|
||||
performance loss.
|
||||
|
||||
**Note:** An offscreen window is always created as a [Frameless Window](../api/frameless-window.md).
|
||||
|
||||
@@ -16,7 +16,7 @@ if ('getAppLevelAppearance' in systemPreferences) {
|
||||
}
|
||||
|
||||
if ('getEffectiveAppearance' in systemPreferences) {
|
||||
const nativeEAGetter = systemPreferences.getAppLevelAppearance;
|
||||
const nativeEAGetter = systemPreferences.getEffectiveAppearance;
|
||||
Object.defineProperty(SystemPreferences.prototype, 'effectiveAppearance', {
|
||||
get: () => nativeEAGetter.call(systemPreferences)
|
||||
});
|
||||
|
||||
@@ -45,7 +45,7 @@ Object.defineProperty(TopLevelWindow.prototype, 'kiosk', {
|
||||
});
|
||||
|
||||
Object.defineProperty(TopLevelWindow.prototype, 'documentEdited', {
|
||||
get: function () { return this.isFullscreen(); },
|
||||
get: function () { return this.isDocumentEdited(); },
|
||||
set: function (edited) { this.setDocumentEdited(edited); }
|
||||
});
|
||||
|
||||
|
||||
@@ -167,29 +167,29 @@ WebContents.prototype._sendInternalToAll = function (channel, ...args) {
|
||||
|
||||
return this._send(internal, sendToAll, channel, args);
|
||||
};
|
||||
WebContents.prototype.sendToFrame = function (frameId, channel, ...args) {
|
||||
WebContents.prototype.sendToFrame = function (frame, channel, ...args) {
|
||||
if (typeof channel !== 'string') {
|
||||
throw new Error('Missing required channel argument');
|
||||
} else if (typeof frameId !== 'number') {
|
||||
throw new Error('Missing required frameId argument');
|
||||
} else if (!(typeof frame === 'number' || Array.isArray(frame))) {
|
||||
throw new Error('Missing required frame argument (must be number or array)');
|
||||
}
|
||||
|
||||
const internal = false;
|
||||
const sendToAll = false;
|
||||
|
||||
return this._sendToFrame(internal, sendToAll, frameId, channel, args);
|
||||
return this._sendToFrame(internal, sendToAll, frame, channel, args);
|
||||
};
|
||||
WebContents.prototype._sendToFrameInternal = function (frameId, channel, ...args) {
|
||||
WebContents.prototype._sendToFrameInternal = function (frame, channel, ...args) {
|
||||
if (typeof channel !== 'string') {
|
||||
throw new Error('Missing required channel argument');
|
||||
} else if (typeof frameId !== 'number') {
|
||||
throw new Error('Missing required frameId argument');
|
||||
} else if (!(typeof frame === 'number' || Array.isArray(frame))) {
|
||||
throw new Error('Missing required frame argument (must be number or array)');
|
||||
}
|
||||
|
||||
const internal = true;
|
||||
const sendToAll = false;
|
||||
|
||||
return this._sendToFrame(internal, sendToAll, frameId, channel, args);
|
||||
return this._sendToFrame(internal, sendToAll, frame, channel, args);
|
||||
};
|
||||
|
||||
// Following methods are mapped to webFrame.
|
||||
@@ -445,8 +445,9 @@ WebContents.prototype.loadFile = function (filePath, options = {}) {
|
||||
};
|
||||
|
||||
const addReplyToEvent = (event) => {
|
||||
const { processId, frameId } = event;
|
||||
event.reply = (...args) => {
|
||||
event.sender.sendToFrame(event.frameId, ...args);
|
||||
event.sender.sendToFrame([processId, frameId], ...args);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -587,7 +588,6 @@ WebContents.prototype._init = function () {
|
||||
width: 800,
|
||||
height: 600,
|
||||
webContents,
|
||||
title: frameName,
|
||||
webPreferences,
|
||||
...options
|
||||
};
|
||||
|
||||
@@ -48,6 +48,9 @@ export const getSourcesImpl = (event: Electron.IpcMainEvent | null, args: Electr
|
||||
}
|
||||
// Remove from currentlyRunning once we resolve or reject
|
||||
currentlyRunning = currentlyRunning.filter(running => running.options !== options);
|
||||
if (event) {
|
||||
event.sender.removeListener('destroyed', stopRunning);
|
||||
}
|
||||
};
|
||||
|
||||
capturer._onerror = (error: string) => {
|
||||
@@ -66,7 +69,7 @@ export const getSourcesImpl = (event: Electron.IpcMainEvent | null, args: Electr
|
||||
// reference to emit and the capturer itself so that it never dispatches
|
||||
// back to the renderer
|
||||
if (event) {
|
||||
event.sender.once('destroyed', () => stopRunning());
|
||||
event.sender.once('destroyed', stopRunning);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -276,7 +276,7 @@ const fakeConstructor = (constructor: Function, name: string) =>
|
||||
});
|
||||
|
||||
// Convert array of meta data from renderer into array of real values.
|
||||
const unwrapArgs = function (sender: electron.WebContents, frameId: number, contextId: string, args: any[]) {
|
||||
const unwrapArgs = function (sender: electron.WebContents, frameId: [number, number], contextId: string, args: any[]) {
|
||||
const metaToValue = function (meta: MetaTypeFromRenderer): any {
|
||||
switch (meta.type) {
|
||||
case 'nativeimage':
|
||||
@@ -331,7 +331,7 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
|
||||
v8Util.setHiddenValue(callIntoRenderer, 'location', meta.location);
|
||||
Object.defineProperty(callIntoRenderer, 'length', { value: meta.length });
|
||||
|
||||
v8Util.setRemoteCallbackFreer(callIntoRenderer, frameId, contextId, meta.id, sender);
|
||||
v8Util.setRemoteCallbackFreer(callIntoRenderer, frameId[0], frameId[1], contextId, meta.id, sender);
|
||||
rendererFunctions.set(objectId, callIntoRenderer);
|
||||
return callIntoRenderer;
|
||||
}
|
||||
@@ -480,7 +480,7 @@ handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, co
|
||||
});
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
|
||||
args = unwrapArgs(event.sender, event.frameId, contextId, args);
|
||||
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
|
||||
const constructor = objectsRegistry.get(id);
|
||||
|
||||
if (constructor == null) {
|
||||
@@ -491,7 +491,7 @@ handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId,
|
||||
});
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) {
|
||||
args = unwrapArgs(event.sender, event.frameId, contextId, args);
|
||||
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
|
||||
const func = objectsRegistry.get(id);
|
||||
|
||||
if (func == null) {
|
||||
@@ -508,7 +508,7 @@ handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId
|
||||
});
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) {
|
||||
args = unwrapArgs(event.sender, event.frameId, contextId, args);
|
||||
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
|
||||
const object = objectsRegistry.get(id);
|
||||
|
||||
if (object == null) {
|
||||
@@ -519,7 +519,7 @@ handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, cont
|
||||
});
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) {
|
||||
args = unwrapArgs(event.sender, event.frameId, contextId, args);
|
||||
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
|
||||
const object = objectsRegistry.get(id);
|
||||
|
||||
if (object == null) {
|
||||
@@ -536,7 +536,7 @@ handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId,
|
||||
});
|
||||
|
||||
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) {
|
||||
args = unwrapArgs(event.sender, event.frameId, contextId, args);
|
||||
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
|
||||
const obj = objectsRegistry.get(id);
|
||||
|
||||
if (obj == null) {
|
||||
|
||||
@@ -83,7 +83,7 @@ const getPreloadScript = async function (preloadPath) {
|
||||
let preloadSrc = null;
|
||||
let preloadError = null;
|
||||
try {
|
||||
preloadSrc = (await fs.promises.readFile(preloadPath)).toString();
|
||||
preloadSrc = await fs.promises.readFile(preloadPath, 'utf8');
|
||||
} catch (error) {
|
||||
preloadError = error;
|
||||
}
|
||||
|
||||
@@ -597,7 +597,13 @@
|
||||
if (options.withFileTypes) {
|
||||
const dirents = [];
|
||||
for (const file of files) {
|
||||
const stats = archive.stat(file);
|
||||
const childPath = path.join(filePath, file);
|
||||
const stats = archive.stat(childPath);
|
||||
if (!stats) {
|
||||
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
|
||||
nextTick(callback, [error]);
|
||||
return;
|
||||
}
|
||||
if (stats.isFile) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
|
||||
} else if (stats.isDirectory) {
|
||||
@@ -633,7 +639,11 @@
|
||||
if (options.withFileTypes) {
|
||||
const dirents = [];
|
||||
for (const file of files) {
|
||||
const stats = archive.stat(file);
|
||||
const childPath = path.join(filePath, file);
|
||||
const stats = archive.stat(childPath);
|
||||
if (!stats) {
|
||||
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
|
||||
}
|
||||
if (stats.isFile) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
|
||||
} else if (stats.isDirectory) {
|
||||
|
||||
@@ -49,7 +49,7 @@ class WebFrame extends EventEmitter {
|
||||
}
|
||||
|
||||
const { hasSwitch } = process.electronBinding('command_line');
|
||||
const worldSafeJS = hasSwitch('world-safe-execute-javascript') && hasSwitch('context-isolation');
|
||||
const worldSafeJS = hasSwitch('world-safe-execute-javascript') || !hasSwitch('context-isolation');
|
||||
|
||||
// Populate the methods.
|
||||
for (const name in binding) {
|
||||
|
||||
@@ -80,7 +80,7 @@ const isUnsafeEvalEnabled: () => Promise<boolean> = function () {
|
||||
// Call _executeJavaScript to bypass the world-safe deprecation warning
|
||||
return (webFrame as any)._executeJavaScript(`(${(() => {
|
||||
try {
|
||||
new Function(''); // eslint-disable-line no-new,no-new-func
|
||||
eval(window.trustedTypes.emptyScript); // eslint-disable-line no-eval
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
@@ -224,7 +224,7 @@ const warnAboutExperimentalFeatures = function (webPreferences?: Electron.WebPre
|
||||
const warnAboutEnableBlinkFeatures = function (webPreferences?: Electron.WebPreferences) {
|
||||
if (!webPreferences ||
|
||||
!Object.prototype.hasOwnProperty.call(webPreferences, 'enableBlinkFeatures') ||
|
||||
(webPreferences.enableBlinkFeatures && webPreferences.enableBlinkFeatures.length === 0)) {
|
||||
(webPreferences.enableBlinkFeatures != null && webPreferences.enableBlinkFeatures.length === 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@ export class WebViewImpl {
|
||||
// Create internal iframe element.
|
||||
this.internalElement = this.createInternalElement();
|
||||
const shadowRoot = this.webviewNode.attachShadow({ mode: 'open' });
|
||||
shadowRoot.innerHTML = '<!DOCTYPE html><style type="text/css">:host { display: flex; }</style>';
|
||||
const style = shadowRoot.ownerDocument!.createElement('style');
|
||||
style.textContent = ':host { display: flex; }';
|
||||
shadowRoot.appendChild(style);
|
||||
this.setupWebViewAttributes();
|
||||
this.viewInstanceId = getNextId();
|
||||
shadowRoot.appendChild(this.internalElement);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "10.1.7",
|
||||
"version": "10.4.4",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -116,3 +116,59 @@ cherry-pick-bbb64b5c6916.patch
|
||||
ignore_renderframehostimpl_detach_for_speculative_rfhs.patch
|
||||
cherry-pick-eec5025668f8.patch
|
||||
cherry-pick-bbc6ab5bb49c.patch
|
||||
cherry-pick-3abc372c9c00.patch
|
||||
cherry-pick-d8d64b7cd244.patch
|
||||
cherry-pick-5ffbb7ed173a.patch
|
||||
ui_check_that_unpremultiply_is_passed_a_32bpp_image.patch
|
||||
cherry-pick-ecdec1fb0f42.patch
|
||||
merge_m86_ensure_that_buffers_used_by_imagedecoder_haven_t_been.patch
|
||||
cherry-pick-2d18de63acf1.patch
|
||||
only_zero_out_cross-origin_audio_that_doesn_t_get_played_out.patch
|
||||
fix_setparentacessibile_crash_win.patch
|
||||
backport_1142331.patch
|
||||
backport_1151865.patch
|
||||
cherry-pick-19aeffd4d93f.patch
|
||||
cherry-pick-4794770cf175.patch
|
||||
cherry-pick-79440c3a0675.patch
|
||||
cherry-pick-d866af575997.patch
|
||||
cherry-pick-da9b5ec032ad.patch
|
||||
cherry-pick-861253f1de98.patch
|
||||
cherry-pick-3ca3d70c7af5.patch
|
||||
mediacapabilities_use_threadsafe_static_wtf_string.patch
|
||||
cherry-pick-d74ba931c4b7.patch
|
||||
cherry-pick-9ec949913373.patch
|
||||
ots_backport_maxp_sanitization.patch
|
||||
ots_backport_of_glyf_guard_access_to_maxp_version_1_field.patch
|
||||
layoutng_fix_an_incorrect_cache-hit_for_line_boxes.patch
|
||||
cherry-pick-0d2bf89e15cc.patch
|
||||
cherry-pick-df438f22f7d2.patch
|
||||
cherry-pick-9afec1792cfc.patch
|
||||
cherry-pick-76cb1cc32baa.patch
|
||||
stop_using_raw_webcontents_ptr_in_dragdownloadfile.patch
|
||||
fix_heap_overflow_in_videoframeyuvconverter.patch
|
||||
disable_gpu_acceleration_on_all_mesa_software_rasterizers.patch
|
||||
websocket_don_t_clear_event_queue_on_destruction.patch
|
||||
cherry-pick-7e0e52df283c.patch
|
||||
cherry-pick-dea071d8b30f.patch
|
||||
cherry-pick-a4faa754a9ef.patch
|
||||
mediarecorder_tolerate_non-gmb_nv12_frames_for_h264.patch
|
||||
cherry-pick-6e8856624cbb.patch
|
||||
cherry-pick-b772b48067c4.patch
|
||||
cherry-pick-3910c9f5cde6.patch
|
||||
cherry-pick-5651fb858b75.patch
|
||||
cherry-pick-b3dc4c4b349d.patch
|
||||
cherry-pick-c6d6f7aee733.patch
|
||||
cherry-pick-37210e5ab006.patch
|
||||
reland_reland_fsa_add_issafepathcomponent_checks_to.patch
|
||||
css_make_fetches_from_inline_css_use_the_document_s_url_as_referrer.patch
|
||||
cherry-pick-3c80bb2a594f.patch
|
||||
cherry-pick-6a6361c9f31c.patch
|
||||
cherry-pick-012e9baf46c9.patch
|
||||
cherry-pick-8c3eb9d1c409.patch
|
||||
use_idtype_for_permission_change_subscriptions.patch
|
||||
cherry-pick-fe85e04a1797.patch
|
||||
m86-lts_add_null_pointer_check_in_renderwidgethostinputeventrouter.patch
|
||||
m86-lts_add_weak_pointer_to_rwhier_framesinkidownermap_and.patch
|
||||
cherry-pick-406ae3e8a9a8.patch
|
||||
cherry-pick-fe20b05a0e5e.patch
|
||||
cherry-pick-6b84dc72351b.patch
|
||||
|
||||
141
patches/chromium/backport_1142331.patch
Normal file
141
patches/chromium/backport_1142331.patch
Normal file
@@ -0,0 +1,141 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Belenko <anbelen@microsoft.com>
|
||||
Date: Thu, 10 Dec 2020 18:04:03 +0100
|
||||
Subject: Chromium backport: crbug.com/1142331
|
||||
|
||||
M87-1
|
||||
Clipboard: Fix UaP in ClipboardWriter/FileReaderLoader
|
||||
https://chromium-review.googlesource.com/c/chromium/src/+/2536946
|
||||
CVE-2020-16037
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
|
||||
index fc5f32d86fd2cc4aeeaadddc94da6ce5e8e7990a..9c72fb55426f685045418947427406016d947589 100644
|
||||
--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
|
||||
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
|
||||
@@ -104,7 +104,7 @@ ScriptPromise ClipboardPromise::CreateForWriteText(ExecutionContext* context,
|
||||
|
||||
ClipboardPromise::ClipboardPromise(ExecutionContext* context,
|
||||
ScriptState* script_state)
|
||||
- : ExecutionContextClient(context),
|
||||
+ : ExecutionContextLifecycleObserver(context),
|
||||
script_state_(script_state),
|
||||
script_promise_resolver_(
|
||||
MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
|
||||
@@ -483,13 +483,20 @@ scoped_refptr<base::SingleThreadTaskRunner> ClipboardPromise::GetTaskRunner() {
|
||||
return GetExecutionContext()->GetTaskRunner(TaskType::kUserInteraction);
|
||||
}
|
||||
|
||||
+// ExecutionContextLifecycleObserver implementation.
|
||||
+void ClipboardPromise::ContextDestroyed() {
|
||||
+ script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
|
||||
+ DOMExceptionCode::kNotAllowedError, "Document detached."));
|
||||
+ clipboard_writer_.Clear();
|
||||
+}
|
||||
+
|
||||
void ClipboardPromise::Trace(Visitor* visitor) const {
|
||||
visitor->Trace(script_state_);
|
||||
visitor->Trace(script_promise_resolver_);
|
||||
visitor->Trace(clipboard_writer_);
|
||||
visitor->Trace(permission_service_);
|
||||
visitor->Trace(clipboard_item_data_);
|
||||
- ExecutionContextClient::Trace(visitor);
|
||||
+ ExecutionContextLifecycleObserver::Trace(visitor);
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
|
||||
index 18efbc8c632dd7061fb31437529f1b14a25beb3a..307ce3b51a7c75b60301885685f5c0d780997250 100644
|
||||
--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
|
||||
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
|
||||
@@ -26,7 +26,7 @@ class ExecutionContext;
|
||||
class ClipboardItemOptions;
|
||||
|
||||
class ClipboardPromise final : public GarbageCollected<ClipboardPromise>,
|
||||
- public ExecutionContextClient {
|
||||
+ public ExecutionContextLifecycleObserver {
|
||||
USING_GARBAGE_COLLECTED_MIXIN(ClipboardPromise);
|
||||
|
||||
public:
|
||||
@@ -83,6 +83,9 @@ class ClipboardPromise final : public GarbageCollected<ClipboardPromise>,
|
||||
LocalFrame* GetLocalFrame() const;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner();
|
||||
|
||||
+ // ExecutionContextLifecycleObserver
|
||||
+ void ContextDestroyed() override;
|
||||
+
|
||||
Member<ScriptState> script_state_;
|
||||
Member<ScriptPromiseResolver> script_promise_resolver_;
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
|
||||
index 2891db58d47b30575efd782ae1c7cf8ee7558cc4..4b224c9679ca51c01328479685970235f35a32fd 100644
|
||||
--- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
|
||||
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
|
||||
@@ -188,9 +188,12 @@ ClipboardWriter::ClipboardWriter(SystemClipboard* system_clipboard,
|
||||
file_reading_task_runner_(promise->GetExecutionContext()->GetTaskRunner(
|
||||
TaskType::kFileReading)),
|
||||
system_clipboard_(system_clipboard),
|
||||
- raw_system_clipboard_(raw_system_clipboard) {}
|
||||
+ raw_system_clipboard_(raw_system_clipboard),
|
||||
+ self_keep_alive_(PERSISTENT_FROM_HERE, this) {}
|
||||
|
||||
-ClipboardWriter::~ClipboardWriter() = default;
|
||||
+ClipboardWriter::~ClipboardWriter() {
|
||||
+ DCHECK(!file_reader_);
|
||||
+}
|
||||
|
||||
// static
|
||||
bool ClipboardWriter::IsValidType(const String& type, bool is_raw) {
|
||||
@@ -220,7 +223,9 @@ void ClipboardWriter::DidFinishLoading() {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
DOMArrayBuffer* array_buffer = file_reader_->ArrayBufferResult();
|
||||
DCHECK(array_buffer);
|
||||
+
|
||||
file_reader_.reset();
|
||||
+ self_keep_alive_.Clear();
|
||||
|
||||
worker_pool::PostTask(
|
||||
FROM_HERE, CrossThreadBindOnce(&ClipboardWriter::DecodeOnBackgroundThread,
|
||||
@@ -230,6 +235,8 @@ void ClipboardWriter::DidFinishLoading() {
|
||||
}
|
||||
|
||||
void ClipboardWriter::DidFail(FileErrorCode error_code) {
|
||||
+ file_reader_.reset();
|
||||
+ self_keep_alive_.Clear();
|
||||
promise_->RejectFromReadOrDecodeFailure();
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.h b/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
|
||||
index 527b063cd20900653dc37027bef8d24af31fb6de..3de3f5ad34b8ebf378421c64c917e3091e5343c6 100644
|
||||
--- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
|
||||
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "third_party/blink/renderer/core/fileapi/blob.h"
|
||||
#include "third_party/blink/renderer/core/fileapi/file_reader_loader_client.h"
|
||||
#include "third_party/blink/renderer/platform/heap/heap.h"
|
||||
+#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
|
||||
#include "third_party/skia/include/core/SkImage.h"
|
||||
|
||||
namespace blink {
|
||||
@@ -27,6 +28,11 @@ class RawSystemClipboard;
|
||||
// take advantage of vulnerabilities in their decoders. In
|
||||
// ClipboardRawDataWriter, this decoding is skipped.
|
||||
// (3) Writing the blob's decoded contents to the system clipboard.
|
||||
+//
|
||||
+// ClipboardWriter is owned only by itself and ClipboardPromise. It keeps
|
||||
+// itself alive for the duration of FileReaderLoader's async operations using
|
||||
+// SelfKeepAlive, and keeps itself alive afterwards during cross-thread
|
||||
+// operations by using WrapCrossThreadPersistent.
|
||||
class ClipboardWriter : public GarbageCollected<ClipboardWriter>,
|
||||
public FileReaderLoaderClient {
|
||||
public:
|
||||
@@ -80,6 +86,10 @@ class ClipboardWriter : public GarbageCollected<ClipboardWriter>,
|
||||
Member<SystemClipboard> system_clipboard_;
|
||||
// Access to the global unsanitized system clipboard.
|
||||
Member<RawSystemClipboard> raw_system_clipboard_;
|
||||
+
|
||||
+ // Oilpan: ClipboardWriter must remain alive until Member<T>::Clear() is
|
||||
+ // called, to keep the FileReaderLoader alive and avoid unexpected UaPs.
|
||||
+ SelfKeepAlive<ClipboardWriter> self_keep_alive_;
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
23
patches/chromium/backport_1151865.patch
Normal file
23
patches/chromium/backport_1151865.patch
Normal file
@@ -0,0 +1,23 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Belenko <anbelen@microsoft.com>
|
||||
Date: Thu, 10 Dec 2020 22:16:48 +0100
|
||||
Subject: Chromium backport: crbug.com/1151865
|
||||
|
||||
M87-1
|
||||
Reject mojom::DataElement serialization if array size read failed
|
||||
https://chromium-review.googlesource.com/c/chromium/src/+/2567130
|
||||
CVE-2020-16041
|
||||
|
||||
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc
|
||||
index ce1478f6df691d5b1f7862a45ac3989a43e2d814..881bcb23ab3291e61088458f46c446fe9e7fb7cf 100644
|
||||
--- a/services/network/public/cpp/url_request_mojom_traits.cc
|
||||
+++ b/services/network/public/cpp/url_request_mojom_traits.cc
|
||||
@@ -286,6 +286,8 @@ bool StructTraits<network::mojom::DataElementDataView, network::DataElement>::
|
||||
if (data.type() == network::mojom::DataElementType::kBytes) {
|
||||
if (!data.ReadBuf(&out->buf_))
|
||||
return false;
|
||||
+ if (data.length() != out->buf_.size())
|
||||
+ return false;
|
||||
}
|
||||
out->type_ = data.type();
|
||||
out->data_pipe_getter_ = data.TakeDataPipeGetter<
|
||||
86
patches/chromium/cherry-pick-012e9baf46c9.patch
Normal file
86
patches/chromium/cherry-pick-012e9baf46c9.patch
Normal file
@@ -0,0 +1,86 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jana Grill <janagrill@google.com>
|
||||
Date: Thu, 15 Apr 2021 20:49:42 +0000
|
||||
Subject: Mojo: Remove some inappropriate DCHECKs
|
||||
|
||||
There are a few places where we DCHECK conditions that cannot be
|
||||
reliably asserted since they depend on untrusted inputs. These are
|
||||
replaced with logic to conditionally terminate the connection to the
|
||||
offending peer process.
|
||||
|
||||
(cherry picked from commit a32b061fc92cc3864d036ffb8c22c12b05202589)
|
||||
|
||||
Fixed: 1195333
|
||||
Change-Id: I0c6873bf55d6b0b1d0cbb3c2e5b256e1a57ff696
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2808893
|
||||
Reviewed-by: Robert Sesek <rsesek@chromium.org>
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#870007}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2821958
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1608}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc
|
||||
index c7646fa4dc5c5062e8a8a620e55839301af51bed..c333ed64f71f0dfe5d0012b07bcedccfd94cd5e9 100644
|
||||
--- a/mojo/core/node_controller.cc
|
||||
+++ b/mojo/core/node_controller.cc
|
||||
@@ -942,7 +942,11 @@ void NodeController::OnBrokerClientAdded(const ports::NodeName& from_node,
|
||||
void NodeController::OnAcceptBrokerClient(const ports::NodeName& from_node,
|
||||
const ports::NodeName& broker_name,
|
||||
PlatformHandle broker_channel) {
|
||||
- DCHECK(!GetConfiguration().is_broker_process);
|
||||
+ if (GetConfiguration().is_broker_process) {
|
||||
+ // The broker should never receive this message from anyone.
|
||||
+ DropPeer(from_node, nullptr);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
// This node should already have an inviter in bootstrap mode.
|
||||
ports::NodeName inviter_name;
|
||||
@@ -953,8 +957,13 @@ void NodeController::OnAcceptBrokerClient(const ports::NodeName& from_node,
|
||||
inviter = bootstrap_inviter_channel_;
|
||||
bootstrap_inviter_channel_ = nullptr;
|
||||
}
|
||||
- DCHECK(inviter_name == from_node);
|
||||
- DCHECK(inviter);
|
||||
+
|
||||
+ if (inviter_name != from_node || !inviter ||
|
||||
+ broker_name == ports::kInvalidNodeName) {
|
||||
+ // We are not expecting this message. Assume the source is hostile.
|
||||
+ DropPeer(from_node, nullptr);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
base::queue<ports::NodeName> pending_broker_clients;
|
||||
std::unordered_map<ports::NodeName, OutgoingMessageQueue>
|
||||
@@ -965,22 +974,22 @@ void NodeController::OnAcceptBrokerClient(const ports::NodeName& from_node,
|
||||
std::swap(pending_broker_clients, pending_broker_clients_);
|
||||
std::swap(pending_relay_messages, pending_relay_messages_);
|
||||
}
|
||||
- DCHECK(broker_name != ports::kInvalidNodeName);
|
||||
|
||||
// It's now possible to add both the broker and the inviter as peers.
|
||||
// Note that the broker and inviter may be the same node.
|
||||
scoped_refptr<NodeChannel> broker;
|
||||
if (broker_name == inviter_name) {
|
||||
- DCHECK(!broker_channel.is_valid());
|
||||
broker = inviter;
|
||||
- } else {
|
||||
- DCHECK(broker_channel.is_valid());
|
||||
+ } else if (broker_channel.is_valid()) {
|
||||
broker = NodeChannel::Create(
|
||||
this,
|
||||
ConnectionParams(PlatformChannelEndpoint(std::move(broker_channel))),
|
||||
Channel::HandlePolicy::kAcceptHandles, io_task_runner_,
|
||||
ProcessErrorCallback());
|
||||
AddPeer(broker_name, broker, true /* start_channel */);
|
||||
+ } else {
|
||||
+ DropPeer(from_node, nullptr);
|
||||
+ return;
|
||||
}
|
||||
|
||||
AddPeer(inviter_name, inviter, false /* start_channel */);
|
||||
148
patches/chromium/cherry-pick-0d2bf89e15cc.patch
Normal file
148
patches/chromium/cherry-pick-0d2bf89e15cc.patch
Normal file
@@ -0,0 +1,148 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sam McNally <sammc@chromium.org>
|
||||
Date: Thu, 17 Dec 2020 02:58:09 +0000
|
||||
Subject: Observe ProcessManager shutdowns from KeepAliveImpl.
|
||||
|
||||
ExtensionRegistry uses the underlying BrowserContext for incognito
|
||||
contexts. Thus, for incognito uses, the ProcessManager can be destroyed
|
||||
without the KeepAliveImpl being notified. Observe ProcessManager
|
||||
shutdowns directly to ensure KeepAliveImpls are cleaned up when a
|
||||
ProcessManager is shut down.
|
||||
|
||||
[Substituted ScopedObserver for base::ScopedObservation since the latter
|
||||
was introduced in 88]
|
||||
|
||||
(cherry picked from commit 5a55fe16e633dd02e3c40e513acabf4324bb6318)
|
||||
|
||||
(cherry picked from commit c2bf2463fbeff3959ea1998a4f3ae82dd648b56c)
|
||||
|
||||
Bug: 1149177
|
||||
Change-Id: I39a0cf54bcf8cf0d58e36560935b8d2f79399cd2
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2548585
|
||||
Auto-Submit: Sam McNally <sammc@chromium.org>
|
||||
Commit-Queue: Ben Wells <benwells@chromium.org>
|
||||
Reviewed-by: Ben Wells <benwells@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#830107}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2563379
|
||||
Reviewed-by: Sam McNally <sammc@chromium.org>
|
||||
Commit-Queue: Sam McNally <sammc@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4280@{#1653}
|
||||
Cr-Original-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2587154
|
||||
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1496}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/extensions/browser/mojo/keep_alive_impl.cc b/extensions/browser/mojo/keep_alive_impl.cc
|
||||
index 0cc74657805296772e00d98225f8113b69904ac5..a7344015d62c4d84eeeddcf9da6f5d38db7e802c 100644
|
||||
--- a/extensions/browser/mojo/keep_alive_impl.cc
|
||||
+++ b/extensions/browser/mojo/keep_alive_impl.cc
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
-#include "extensions/browser/process_manager.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
@@ -32,6 +31,7 @@ KeepAliveImpl::KeepAliveImpl(content::BrowserContext* context,
|
||||
receiver_.set_disconnect_handler(
|
||||
base::BindOnce(&KeepAliveImpl::OnDisconnected, base::Unretained(this)));
|
||||
extension_registry_observer_.Add(ExtensionRegistry::Get(context_));
|
||||
+ process_manager_observation_.Add(ProcessManager::Get(context_));
|
||||
}
|
||||
|
||||
KeepAliveImpl::~KeepAliveImpl() = default;
|
||||
@@ -54,4 +54,8 @@ void KeepAliveImpl::OnDisconnected() {
|
||||
delete this;
|
||||
}
|
||||
|
||||
+void KeepAliveImpl::OnProcessManagerShutdown(ProcessManager* manager) {
|
||||
+ delete this;
|
||||
+}
|
||||
+
|
||||
} // namespace extensions
|
||||
diff --git a/extensions/browser/mojo/keep_alive_impl.h b/extensions/browser/mojo/keep_alive_impl.h
|
||||
index a3e4233a3e6691999decb281dbaf80f74bf922cc..331fc2fdf670e44d51adc610ee39144dac15ae87 100644
|
||||
--- a/extensions/browser/mojo/keep_alive_impl.h
|
||||
+++ b/extensions/browser/mojo/keep_alive_impl.h
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "base/scoped_observer.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/extension_registry_observer.h"
|
||||
+#include "extensions/browser/process_manager.h"
|
||||
+#include "extensions/browser/process_manager_observer.h"
|
||||
#include "extensions/common/mojom/keep_alive.mojom.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
@@ -21,10 +23,13 @@ class RenderFrameHost;
|
||||
|
||||
namespace extensions {
|
||||
class Extension;
|
||||
+class ProcessManager;
|
||||
|
||||
// An RAII mojo service implementation for extension keep alives. This adds a
|
||||
// keep alive on construction and removes it on destruction.
|
||||
-class KeepAliveImpl : public KeepAlive, public ExtensionRegistryObserver {
|
||||
+class KeepAliveImpl : public KeepAlive,
|
||||
+ public ExtensionRegistryObserver,
|
||||
+ public ProcessManagerObserver {
|
||||
public:
|
||||
// Create a keep alive for |extension| running in |context| and connect it to
|
||||
// |receiver|. When the receiver closes its pipe, the keep alive ends.
|
||||
@@ -45,6 +50,9 @@ class KeepAliveImpl : public KeepAlive, public ExtensionRegistryObserver {
|
||||
UnloadedExtensionReason reason) override;
|
||||
void OnShutdown(ExtensionRegistry* registry) override;
|
||||
|
||||
+ // ProcessManagerObserver overrides.
|
||||
+ void OnProcessManagerShutdown(ProcessManager* manager) override;
|
||||
+
|
||||
// Invoked when the mojo connection is disconnected.
|
||||
void OnDisconnected();
|
||||
|
||||
@@ -52,6 +60,8 @@ class KeepAliveImpl : public KeepAlive, public ExtensionRegistryObserver {
|
||||
const Extension* extension_;
|
||||
ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
|
||||
extension_registry_observer_{this};
|
||||
+ ScopedObserver<ProcessManager, ProcessManagerObserver>
|
||||
+ process_manager_observation_{this};
|
||||
mojo::Receiver<KeepAlive> receiver_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(KeepAliveImpl);
|
||||
diff --git a/extensions/browser/mojo/keep_alive_impl_unittest.cc b/extensions/browser/mojo/keep_alive_impl_unittest.cc
|
||||
index 90599cc46d24dc7ec0eabb1da17545b489d93445..e6f60c39cf29d9554cb0f1096ed87345d3e38923 100644
|
||||
--- a/extensions/browser/mojo/keep_alive_impl_unittest.cc
|
||||
+++ b/extensions/browser/mojo/keep_alive_impl_unittest.cc
|
||||
@@ -160,7 +160,7 @@ TEST_F(KeepAliveTest, UnloadExtension) {
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
-TEST_F(KeepAliveTest, Shutdown) {
|
||||
+TEST_F(KeepAliveTest, ShutdownExtensionRegistry) {
|
||||
mojo::Remote<KeepAlive> keep_alive;
|
||||
CreateKeepAlive(keep_alive.BindNewPipeAndPassReceiver());
|
||||
EXPECT_EQ(1, GetKeepAliveCount());
|
||||
@@ -178,4 +178,22 @@ TEST_F(KeepAliveTest, Shutdown) {
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
+TEST_F(KeepAliveTest, ShutdownProcessManager) {
|
||||
+ mojo::Remote<KeepAlive> keep_alive;
|
||||
+ CreateKeepAlive(keep_alive.BindNewPipeAndPassReceiver());
|
||||
+ EXPECT_EQ(1, GetKeepAliveCount());
|
||||
+ EXPECT_EQ(1u, GetActivities().count(mojo_activity_));
|
||||
+
|
||||
+ ProcessManager::Get(browser_context())->Shutdown();
|
||||
+ // After a shutdown event, the KeepAliveImpl should not access its
|
||||
+ // ProcessManager and so the keep-alive count should remain unchanged.
|
||||
+ EXPECT_EQ(1, GetKeepAliveCount());
|
||||
+ EXPECT_EQ(1u, GetActivities().count(mojo_activity_));
|
||||
+
|
||||
+ // Wait for |keep_alive| to disconnect.
|
||||
+ base::RunLoop run_loop;
|
||||
+ keep_alive.set_disconnect_handler(run_loop.QuitClosure());
|
||||
+ run_loop.Run();
|
||||
+}
|
||||
+
|
||||
} // namespace extensions
|
||||
124
patches/chromium/cherry-pick-19aeffd4d93f.patch
Normal file
124
patches/chromium/cherry-pick-19aeffd4d93f.patch
Normal file
@@ -0,0 +1,124 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Denton <mpdenton@chromium.org>
|
||||
Date: Tue, 15 Dec 2020 01:09:52 +0000
|
||||
Subject: Fix UAF in ~MultiThreadedCertVerifier
|
||||
|
||||
MultiThreadedCertVerifier keeps a list of
|
||||
MultiThreadedCertVerifier::InternalRequests in order to eagerly reset
|
||||
callbacks passed to Verify() if the MultiThreadedCertVerifier is
|
||||
itself deleted (CertVerifier contract guarantees this eager reset
|
||||
behavior).
|
||||
|
||||
In ~MultiThreadedCertVerifier we loop through this list and reset the
|
||||
callbacks, but then delete the InternalRequest from the list. However,
|
||||
the callbacks are allowed to own the InternalRequest, so this leads
|
||||
to a UaF.
|
||||
|
||||
We don't need to remove the InternalRequest from the list in
|
||||
~MultiThreadedCertVerifier, because we are not in charge of the
|
||||
lifetime of the InternalRequest. InternalRequest can remove itself
|
||||
from the list during ~InternalRequest, or MultiThreadedCertVerifier
|
||||
can remove it from the list when a CertVerification job is complete.
|
||||
The former is safe because ~InternalRequest won't remove itself from
|
||||
the list if the MultiThreadedCertVerifier is already destructed.
|
||||
The latter is obviously safe because if the request was cancelled,
|
||||
then InternalRequest::OnJobCompleted will never run, so
|
||||
|this| is always valid to remove from the list during
|
||||
InternalRequest::OnJobCompleted.
|
||||
|
||||
The added test reproduces the UAF without the fix.
|
||||
|
||||
Bug: 1157562
|
||||
Change-Id: I92d0dc6ca6df084f55ea511ea692853ee63f5033
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2587560
|
||||
Reviewed-by: Ryan Sleevi <rsleevi@chromium.org>
|
||||
Commit-Queue: Matthew Denton <mpdenton@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#836903}
|
||||
|
||||
diff --git a/net/cert/multi_threaded_cert_verifier.cc b/net/cert/multi_threaded_cert_verifier.cc
|
||||
index f2546d9187dc6aedbf5eab055d2017939df6a705..b46dbf68d0f239c2d002f9dedeecd6f10709f9c4 100644
|
||||
--- a/net/cert/multi_threaded_cert_verifier.cc
|
||||
+++ b/net/cert/multi_threaded_cert_verifier.cc
|
||||
@@ -202,10 +202,13 @@ MultiThreadedCertVerifier::~MultiThreadedCertVerifier() {
|
||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||
// Reset the callbacks for each InternalRequest to fulfill the respective
|
||||
// net::CertVerifier contract.
|
||||
- while (!request_list_.empty()) {
|
||||
- base::LinkNode<InternalRequest>* curr = request_list_.head();
|
||||
- curr->value()->ResetCallback();
|
||||
- curr->RemoveFromList();
|
||||
+ for (base::LinkNode<InternalRequest>* node = request_list_.head();
|
||||
+ node != request_list_.end();) {
|
||||
+ // Resetting the callback may delete the request, so save a pointer to the
|
||||
+ // next node first.
|
||||
+ base::LinkNode<InternalRequest>* next_node = node->next();
|
||||
+ node->value()->ResetCallback();
|
||||
+ node = next_node;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/net/cert/multi_threaded_cert_verifier.h b/net/cert/multi_threaded_cert_verifier.h
|
||||
index 82b750a42f8eb99675e35aa41ef167c1e7896a33..05c5463abffc61644e31293b6876801efc6138fb 100644
|
||||
--- a/net/cert/multi_threaded_cert_verifier.h
|
||||
+++ b/net/cert/multi_threaded_cert_verifier.h
|
||||
@@ -50,6 +50,10 @@ class NET_EXPORT_PRIVATE MultiThreadedCertVerifier : public CertVerifier {
|
||||
Config config_;
|
||||
scoped_refptr<CertVerifyProc> verify_proc_;
|
||||
|
||||
+ // Holds a list of CertVerifier::Requests that have not yet completed or been
|
||||
+ // deleted. It is used to ensure that when the MultiThreadedCertVerifier is
|
||||
+ // deleted, we eagerly reset all of the callbacks provided to Verify(), and
|
||||
+ // don't call them later, as required by the CertVerifier contract.
|
||||
base::LinkedList<InternalRequest> request_list_;
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
diff --git a/net/cert/multi_threaded_cert_verifier_unittest.cc b/net/cert/multi_threaded_cert_verifier_unittest.cc
|
||||
index 89c394541a94697036e34c7430e982c4eeb1a1f7..b5cf4bbaf3648f8b562fffd3804b65ab5b9379ab 100644
|
||||
--- a/net/cert/multi_threaded_cert_verifier_unittest.cc
|
||||
+++ b/net/cert/multi_threaded_cert_verifier_unittest.cc
|
||||
@@ -152,6 +152,45 @@ TEST_F(MultiThreadedCertVerifierTest, DeleteVerifier) {
|
||||
RunUntilIdle();
|
||||
}
|
||||
|
||||
+namespace {
|
||||
+
|
||||
+struct CertVerifyResultHelper {
|
||||
+ void FailTest(int /* result */) { FAIL(); }
|
||||
+ std::unique_ptr<CertVerifier::Request> request;
|
||||
+};
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+// The same as the above "DeleteVerifier" test, except the callback provided
|
||||
+// will own the CertVerifier::Request as allowed by the CertVerifier contract.
|
||||
+// This is a regression test for https://crbug.com/1157562.
|
||||
+TEST_F(MultiThreadedCertVerifierTest, DeleteVerifierCallbackOwnsResult) {
|
||||
+ base::FilePath certs_dir = GetTestCertsDirectory();
|
||||
+ scoped_refptr<X509Certificate> test_cert(
|
||||
+ ImportCertFromFile(certs_dir, "ok_cert.pem"));
|
||||
+ ASSERT_NE(static_cast<X509Certificate*>(nullptr), test_cert.get());
|
||||
+
|
||||
+ int error;
|
||||
+ CertVerifyResult verify_result;
|
||||
+ std::unique_ptr<CertVerifyResultHelper> result_helper =
|
||||
+ std::make_unique<CertVerifyResultHelper>();
|
||||
+ CertVerifyResultHelper* result_helper_ptr = result_helper.get();
|
||||
+ CompletionOnceCallback callback = base::BindOnce(
|
||||
+ &CertVerifyResultHelper::FailTest, std::move(result_helper));
|
||||
+
|
||||
+ error = verifier_->Verify(
|
||||
+ CertVerifier::RequestParams(test_cert, "www.example.com", 0,
|
||||
+ /*ocsp_response=*/std::string(),
|
||||
+ /*sct_list=*/std::string()),
|
||||
+ &verify_result, std::move(callback), &result_helper_ptr->request,
|
||||
+ NetLogWithSource());
|
||||
+ ASSERT_THAT(error, IsError(ERR_IO_PENDING));
|
||||
+ ASSERT_TRUE(result_helper_ptr->request);
|
||||
+ verifier_.reset();
|
||||
+
|
||||
+ RunUntilIdle();
|
||||
+}
|
||||
+
|
||||
// Tests that a canceled request is not leaked.
|
||||
TEST_F(MultiThreadedCertVerifierTest, CancelRequestThenQuit) {
|
||||
base::FilePath certs_dir = GetTestCertsDirectory();
|
||||
52
patches/chromium/cherry-pick-2d18de63acf1.patch
Normal file
52
patches/chromium/cherry-pick-2d18de63acf1.patch
Normal file
@@ -0,0 +1,52 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: danakj <danakj@chromium.org>
|
||||
Date: Tue, 17 Nov 2020 21:47:27 +0000
|
||||
Subject: Convert strides with padding in skia::SkBitmapToN32OpaqueOrPremul().
|
||||
|
||||
Code using bitmaps converted with SkBitmapToN32OpaqueOrPremul() can
|
||||
easily assume that the pixels are one contiguous (width*4*height)-sized
|
||||
buffer. If it's not then out-of-bounds read/write can occur.
|
||||
|
||||
Also adds tests for SkBitmapToN32OpaqueOrPremul().
|
||||
|
||||
R=fmalita@chromium.org
|
||||
|
||||
Bug: 1147431, 1144462
|
||||
Change-Id: I21f7a958a8c9231bf5f052f8ff246f2c249bd70b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2544032
|
||||
Commit-Queue: danakj <danakj@chromium.org>
|
||||
Reviewed-by: Florin Malita <fmalita@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#828406}
|
||||
|
||||
diff --git a/skia/ext/skia_utils_base.cc b/skia/ext/skia_utils_base.cc
|
||||
index 516ad7ea1e3a0acb1c8b207f98f6daf534262cbc..f9e622eff3ec6c3287138d7cdf68814b8535a338 100644
|
||||
--- a/skia/ext/skia_utils_base.cc
|
||||
+++ b/skia/ext/skia_utils_base.cc
|
||||
@@ -85,7 +85,8 @@ void WriteSkFontStyle(base::Pickle* pickle, SkFontStyle style) {
|
||||
bool SkBitmapToN32OpaqueOrPremul(const SkBitmap& in, SkBitmap* out) {
|
||||
DCHECK(out);
|
||||
const SkImageInfo& info = in.info();
|
||||
- if (info.colorType() == kN32_SkColorType &&
|
||||
+ const bool stride_matches_width = in.rowBytes() == info.minRowBytes();
|
||||
+ if (stride_matches_width && info.colorType() == kN32_SkColorType &&
|
||||
(info.alphaType() == kPremul_SkAlphaType ||
|
||||
info.alphaType() == kOpaque_SkAlphaType)) {
|
||||
// Shallow copy if the data is already in the right format.
|
||||
diff --git a/skia/ext/skia_utils_base.h b/skia/ext/skia_utils_base.h
|
||||
index 2a1eca124e91695ddec635e593ad1e9b650aa156..40401bb2fe0e484fae64490757d63f85e5c5ffea 100644
|
||||
--- a/skia/ext/skia_utils_base.h
|
||||
+++ b/skia/ext/skia_utils_base.h
|
||||
@@ -42,9 +42,10 @@ SK_API void WriteSkFontIdentity(
|
||||
// Writes style into the request pickle.
|
||||
SK_API void WriteSkFontStyle(base::Pickle* pickle, SkFontStyle style);
|
||||
|
||||
-// Converts an SkBitmap to an Opaque or Premul N32 SkBitmap. If the input is in
|
||||
-// the right format (N32 Opaque or Premul) already, points |out| directly at
|
||||
-// |in|. |out| may or may not be GPU-backed.
|
||||
+// Converts an SkBitmap to an Opaque or Premul N32 SkBitmap with stride matching
|
||||
+// the width of each row. If the input is has the right format (N32 Opaque or
|
||||
+// Premul) without stride padding already, this assigns `in` to `out`, sharing
|
||||
+// the backing pixels. `out` may or may not be GPU-backed.
|
||||
//
|
||||
// If unsuccessful, returns false, but |out| may be modified.
|
||||
SK_API bool SkBitmapToN32OpaqueOrPremul(const SkBitmap& in, SkBitmap* out);
|
||||
148
patches/chromium/cherry-pick-37210e5ab006.patch
Normal file
148
patches/chromium/cherry-pick-37210e5ab006.patch
Normal file
@@ -0,0 +1,148 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Antonio Sartori <antoniosartori@chromium.org>
|
||||
Date: Mon, 8 Mar 2021 10:28:40 +0000
|
||||
Subject: Strip url to origin in X-Frame-Options violation messages
|
||||
|
||||
X-Frame-Options violations are logged via a console message in the
|
||||
parent frame. To avoid leaking sensitive data to the parent frame,
|
||||
let's report as "blocked url" just the origin of the blocked frame's
|
||||
url, as we are already doing for the frame-ancestors CSP directive.
|
||||
|
||||
[M86 Merge]: ancestor_throttle.cc was moved.
|
||||
|
||||
(cherry picked from commit 93ce5606cd9a9597993ba70670b4092ab6722281)
|
||||
|
||||
Bug: 1146651
|
||||
Change-Id: If5e5ac62f7e44e714b109e6adc389f11999e0f8b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2534851
|
||||
Commit-Queue: Antonio Sartori <antoniosartori@chromium.org>
|
||||
Reviewed-by: Charlie Reis <creis@chromium.org>
|
||||
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#828651}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2731577
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1563}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ConsoleMessagesForBlockedLoadsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/ConsoleMessagesForBlockedLoadsTest.java
|
||||
index 7394abb2e639a8f3b25cca0a568135cd4e8bd0d8..c746763be2a77a87a52e9ef31bbbd25de7ba03ae 100644
|
||||
--- a/android_webview/javatests/src/org/chromium/android_webview/test/ConsoleMessagesForBlockedLoadsTest.java
|
||||
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/ConsoleMessagesForBlockedLoadsTest.java
|
||||
@@ -94,7 +94,7 @@ public class ConsoleMessagesForBlockedLoadsTest {
|
||||
mActivityTestRule.loadUrlSync(
|
||||
mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl);
|
||||
AwConsoleMessage errorMessage = getSingleErrorMessage();
|
||||
- assertNotEquals(errorMessage.message().indexOf(iframeUrl), -1);
|
||||
+ assertNotEquals(errorMessage.message().indexOf(mWebServer.getBaseUrl()), -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
diff --git a/content/browser/frame_host/ancestor_throttle.cc b/content/browser/frame_host/ancestor_throttle.cc
|
||||
index 8630ace7189d465cea8360a55acf899fa801f15e..75269311d73c1d9b881bc40f320265772b074d63 100644
|
||||
--- a/content/browser/frame_host/ancestor_throttle.cc
|
||||
+++ b/content/browser/frame_host/ancestor_throttle.cc
|
||||
@@ -239,12 +239,20 @@ void AncestorThrottle::ParseXFrameOptionsError(const std::string& value,
|
||||
"Refused to display '%s' in a frame because it set multiple "
|
||||
"'X-Frame-Options' headers with conflicting values "
|
||||
"('%s'). Falling back to 'deny'.",
|
||||
- navigation_handle()->GetURL().spec().c_str(), value.c_str());
|
||||
+ url::Origin::Create(navigation_handle()->GetURL())
|
||||
+ .GetURL()
|
||||
+ .spec()
|
||||
+ .c_str(),
|
||||
+ value.c_str());
|
||||
} else {
|
||||
message = base::StringPrintf(
|
||||
"Invalid 'X-Frame-Options' header encountered when loading '%s': "
|
||||
"'%s' is not a recognized directive. The header will be ignored.",
|
||||
- navigation_handle()->GetURL().spec().c_str(), value.c_str());
|
||||
+ url::Origin::Create(navigation_handle()->GetURL())
|
||||
+ .GetURL()
|
||||
+ .spec()
|
||||
+ .c_str(),
|
||||
+ value.c_str());
|
||||
}
|
||||
|
||||
// Log a console error in the parent of the current RenderFrameHost (as
|
||||
@@ -265,11 +273,19 @@ void AncestorThrottle::ConsoleErrorXFrameOptions(
|
||||
std::string message = base::StringPrintf(
|
||||
"Refused to display '%s' in a frame because it set 'X-Frame-Options' "
|
||||
"to '%s'.",
|
||||
- navigation_handle()->GetURL().spec().c_str(),
|
||||
+ url::Origin::Create(navigation_handle()->GetURL())
|
||||
+ .GetURL()
|
||||
+ .spec()
|
||||
+ .c_str(),
|
||||
disposition == HeaderDisposition::DENY ? "deny" : "sameorigin");
|
||||
|
||||
// Log a console error in the parent of the current RenderFrameHost (as
|
||||
// the current RenderFrameHost itself doesn't yet have a document).
|
||||
+ //
|
||||
+ // TODO(https://crbug.com/1146651): We should not leak any information at all
|
||||
+ // to the parent frame. Send a message directly to Devtools instead (without
|
||||
+ // passing through a renderer): that can also contain more information (like
|
||||
+ // the full blocked url).
|
||||
auto* frame = static_cast<RenderFrameHostImpl*>(
|
||||
navigation_handle()->GetRenderFrameHost());
|
||||
ParentForAncestorThrottle(frame)->AddMessageToConsole(
|
||||
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
|
||||
index d81076da5ef7701475ef1158b528d02d3992ff0d..10d1a58f143906a77df33ae8da3cc1df7605c07b 100644
|
||||
--- a/content/browser/site_per_process_browsertest.cc
|
||||
+++ b/content/browser/site_per_process_browsertest.cc
|
||||
@@ -7109,12 +7109,26 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
|
||||
"document.querySelector('iframe').onload = "
|
||||
" function() { document.title = 'loaded'; };"));
|
||||
|
||||
+ // The blocked url reported in the console message should only contain the
|
||||
+ // origin, in order to avoid sensitive data being leaked to the parent frame.
|
||||
+ //
|
||||
+ // TODO(https://crbug.com/1146651): We should not leak any information at all
|
||||
+ // to the parent frame. Instead, we should send a message directly to Devtools
|
||||
+ // (without passing through a renderer): that can also contain more
|
||||
+ // information (like the full blocked url).
|
||||
+ GURL reported_blocked_url = embedded_test_server()->GetURL("b.com", "/");
|
||||
const struct {
|
||||
const char* url;
|
||||
bool use_error_page;
|
||||
+ std::string expected_console_message;
|
||||
} kTestCases[] = {
|
||||
- {"/frame-ancestors-none.html", false},
|
||||
- {"/x-frame-options-deny.html", true},
|
||||
+ {"/frame-ancestors-none.html", false,
|
||||
+ "Refused to frame '" + reported_blocked_url.spec() +
|
||||
+ "' because an ancestor violates the following Content Security "
|
||||
+ "Policy directive: \"frame-ancestors 'none'\".\n"},
|
||||
+ {"/x-frame-options-deny.html", true,
|
||||
+ "Refused to display '" + reported_blocked_url.spec() +
|
||||
+ "' in a frame because it set 'X-Frame-Options' to 'deny'."},
|
||||
};
|
||||
|
||||
for (const auto& test : kTestCases) {
|
||||
@@ -7123,6 +7137,9 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
|
||||
base::string16 expected_title(base::UTF8ToUTF16("loaded"));
|
||||
TitleWatcher title_watcher(shell()->web_contents(), expected_title);
|
||||
|
||||
+ WebContentsConsoleObserver console_observer(shell()->web_contents());
|
||||
+ console_observer.SetPattern("Refused to*");
|
||||
+
|
||||
// Navigate the subframe to a blocked URL.
|
||||
TestNavigationObserver load_observer(shell()->web_contents());
|
||||
EXPECT_TRUE(ExecuteScript(
|
||||
@@ -7150,6 +7167,8 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
|
||||
// The blocked frame should still fire a load event in its parent's process.
|
||||
EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
|
||||
|
||||
+ EXPECT_EQ(console_observer.GetMessageAt(0u), test.expected_console_message);
|
||||
+
|
||||
// Check that the current RenderFrameHost has stopped loading.
|
||||
EXPECT_FALSE(root->child_at(0)->current_frame_host()->is_loading());
|
||||
|
||||
diff --git a/third_party/blink/web_tests/http/tests/security/XFrameOptions/x-frame-options-deny-delete-frame-in-load-event-expected.txt b/third_party/blink/web_tests/http/tests/security/XFrameOptions/x-frame-options-deny-delete-frame-in-load-event-expected.txt
|
||||
index f2e5b68c997ca33da841aa7ba5795ef3b96fa02f..f7eea4a189ae8913921444428e26389dfd4de4da 100644
|
||||
--- a/third_party/blink/web_tests/http/tests/security/XFrameOptions/x-frame-options-deny-delete-frame-in-load-event-expected.txt
|
||||
+++ b/third_party/blink/web_tests/http/tests/security/XFrameOptions/x-frame-options-deny-delete-frame-in-load-event-expected.txt
|
||||
@@ -1,2 +1,2 @@
|
||||
-CONSOLE ERROR: Refused to display 'http://127.0.0.1:8000/security/XFrameOptions/resources/x-frame-options-deny.cgi' in a frame because it set 'X-Frame-Options' to 'deny'.
|
||||
+CONSOLE ERROR: Refused to display 'http://127.0.0.1:8000/' in a frame because it set 'X-Frame-Options' to 'deny'.
|
||||
Test that if an iframe is denied, we don't crash if the load event detaches the frame.
|
||||
224
patches/chromium/cherry-pick-3910c9f5cde6.patch
Normal file
224
patches/chromium/cherry-pick-3910c9f5cde6.patch
Normal file
@@ -0,0 +1,224 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Raymond Toy <rtoy@chromium.org>
|
||||
Date: Tue, 2 Mar 2021 15:15:29 +0000
|
||||
Subject: Convert AudioParam NaN values to the default value
|
||||
|
||||
If any output value of an AudioParam (including the intrinsic values
|
||||
and any inputs to the AudioParam), should be NaN, replace the NaN
|
||||
value with the associated defaultValue.
|
||||
|
||||
This causes some slowdowns so SIMD/NEON code was added to mitigate the
|
||||
degradation. There is still some slowdown, but the worst case is now
|
||||
about 7% slower on x86 and 10% on arm. Generally, the slowdown is less
|
||||
than 2% and 5%, respectively. (Perversely, some results got faster,
|
||||
and the differences are statistically significant.)
|
||||
|
||||
Full details can be found at
|
||||
https://docs.google.com/spreadsheets/d/1EhbLHm-9cUoEO5aj1vYemVBLQ3Dh4dCJPPLTfZPrZt4/edit?usp=sharing
|
||||
|
||||
Manually tested the test case from the bug and the issue no longer
|
||||
occurs.
|
||||
|
||||
(cherry picked from commit ab1862017b5717271a28376659944dddc602195c)
|
||||
|
||||
(cherry picked from commit eb0c0353bf245885797d8ce0d1b864d88a381fbb)
|
||||
|
||||
Bug: 1170531
|
||||
Change-Id: I00d902b40a9ef9da990c6d68b664b1dcfc31b091
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2658724
|
||||
Commit-Queue: Raymond Toy <rtoy@chromium.org>
|
||||
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#851733}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2686369
|
||||
Reviewed-by: Raymond Toy <rtoy@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4389@{#880}
|
||||
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2727697
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1551}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/audio_param.cc b/third_party/blink/renderer/modules/webaudio/audio_param.cc
|
||||
index c5d329479a412d52ee39167ff841b1cea417a217..135588f56ebceabd3e0a12f9f506955bb58b20ca 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/audio_param.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/audio_param.cc
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "third_party/blink/renderer/modules/webaudio/audio_param.h"
|
||||
|
||||
+#include "build/build_config.h"
|
||||
#include "third_party/blink/renderer/core/inspector/console_message.h"
|
||||
#include "third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h"
|
||||
#include "third_party/blink/renderer/modules/webaudio/audio_node.h"
|
||||
@@ -235,6 +236,49 @@ void AudioParamHandler::CalculateSampleAccurateValues(
|
||||
CalculateFinalValues(values, number_of_values, IsAudioRate());
|
||||
}
|
||||
|
||||
+// Replace NaN values in |values| with |default_value|.
|
||||
+static void HandleNaNValues(float* values,
|
||||
+ unsigned number_of_values,
|
||||
+ float default_value) {
|
||||
+ unsigned k = 0;
|
||||
+#if defined(ARCH_CPU_X86_FAMILY)
|
||||
+ if (number_of_values >= 4) {
|
||||
+ __m128 defaults = _mm_set1_ps(default_value);
|
||||
+ for (k = 0; k < number_of_values; k += 4) {
|
||||
+ __m128 v = _mm_loadu_ps(values + k);
|
||||
+ // cmpuord returns all 1's if v is NaN for each elmeent of v.
|
||||
+ __m128 isnan = _mm_cmpunord_ps(v, v);
|
||||
+ // Replace NaN parts with default.
|
||||
+ __m128 result = _mm_and_ps(isnan, defaults);
|
||||
+ // Merge in the parts that aren't NaN
|
||||
+ result = _mm_or_ps(_mm_andnot_ps(isnan, v), result);
|
||||
+ _mm_storeu_ps(values + k, result);
|
||||
+ }
|
||||
+ }
|
||||
+#elif defined(CPU_ARM_NEON)
|
||||
+ if (number_of_values >= 4) {
|
||||
+ uint32x4_t defaults = static_cast<uint32x4_t>(vdupq_n_f32(default_value));
|
||||
+ for (k = 0; k < number_of_values; k += 4) {
|
||||
+ float32x4_t v = vld1q_f32(values + k);
|
||||
+ // Returns true (all ones) if v is not NaN
|
||||
+ uint32x4_t is_not_nan = vceqq_f32(v, v);
|
||||
+ // Get the parts that are not NaN
|
||||
+ uint32x4_t result = vandq_u32(is_not_nan, v);
|
||||
+ // Replace the parts that are NaN with the default and merge with previous
|
||||
+ // result. (Note: vbic_u32(x, y) = x and not y)
|
||||
+ result = vorrq_u32(result, vbicq_u32(defaults, is_not_nan));
|
||||
+ vst1q_f32(values + k, static_cast<float32x4_t>(result));
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ for (; k < number_of_values; ++k) {
|
||||
+ if (std::isnan(values[k])) {
|
||||
+ values[k] = default_value;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void AudioParamHandler::CalculateFinalValues(float* values,
|
||||
unsigned number_of_values,
|
||||
bool sample_accurate) {
|
||||
@@ -297,10 +341,21 @@ void AudioParamHandler::CalculateFinalValues(float* values,
|
||||
}
|
||||
}
|
||||
|
||||
- // Clamp the values now to the nominal range
|
||||
float min_value = MinValue();
|
||||
float max_value = MaxValue();
|
||||
|
||||
+ if (NumberOfRenderingConnections() > 0) {
|
||||
+ // AudioParams by themselves don't produce NaN because of the finite min
|
||||
+ // and max values. But an input to an AudioParam could have NaNs.
|
||||
+ //
|
||||
+ // NaN values in AudioParams must be replaced by the AudioParam's
|
||||
+ // defaultValue. Then these values must be clamped to lie in the nominal
|
||||
+ // range between the AudioParam's minValue and maxValue.
|
||||
+ //
|
||||
+ // See https://webaudio.github.io/web-audio-api/#computation-of-value.
|
||||
+ HandleNaNValues(values, number_of_values, DefaultValue());
|
||||
+ }
|
||||
+
|
||||
vector_math::Vclip(values, 1, &min_value, &max_value, values, 1,
|
||||
number_of_values);
|
||||
}
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/nan-param.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/nan-param.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e9b8f0accbd1b0359275615f3ef12bd7e9317c4f
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/nan-param.html
|
||||
@@ -0,0 +1,92 @@
|
||||
+<!doctype html>
|
||||
+<html>
|
||||
+ <head>
|
||||
+ <title>Test Flushing of NaN to Zero in AudioParams</title>
|
||||
+ <script src="/resources/testharness.js"></script>
|
||||
+ <script src="/resources/testharnessreport.js"></script>
|
||||
+ <script src="/webaudio/resources/audit-util.js"></script>
|
||||
+ <script src="/webaudio/resources/audit.js"></script>
|
||||
+ </head>
|
||||
+
|
||||
+ <body>
|
||||
+ <script>
|
||||
+ let audit = Audit.createTaskRunner();
|
||||
+
|
||||
+ // See
|
||||
+ // https://webaudio.github.io/web-audio-api/#computation-of-value.
|
||||
+ //
|
||||
+ // The computed value must replace NaN values in the output with
|
||||
+ // the default value of the param.
|
||||
+ audit.define('AudioParam NaN', async (task, should) => {
|
||||
+ // For testing, we only need a small number of frames; and
|
||||
+ // a low sample rate is perfectly fine. Use two channels.
|
||||
+ // The first channel is for the AudioParam output. The
|
||||
+ // second channel is for the AudioParam input.
|
||||
+ let context = new OfflineAudioContext(
|
||||
+ {numberOfChannels: 2, length: 256, sampleRate: 8192});
|
||||
+ let merger = new ChannelMergerNode(
|
||||
+ context, {numberOfInputs: context.destination.channelCount});
|
||||
+ merger.connect(context.destination);
|
||||
+
|
||||
+ // A constant source with a huge value.
|
||||
+ let mod = new ConstantSourceNode(context, {offset: 1e30});
|
||||
+
|
||||
+ // Gain nodes with a huge positive gain and huge negative
|
||||
+ // gain. Combined with the huge offset in |mod|, the
|
||||
+ // output of the gain nodes are +Infinity and -Infinity.
|
||||
+ let gainPos = new GainNode(context, {gain: 1e30});
|
||||
+ let gainNeg = new GainNode(context, {gain: -1e30});
|
||||
+
|
||||
+ mod.connect(gainPos);
|
||||
+ mod.connect(gainNeg);
|
||||
+
|
||||
+ // Connect these to the second merger channel. This is a
|
||||
+ // sanity check that the AudioParam input really is NaN.
|
||||
+ gainPos.connect(merger, 0, 1);
|
||||
+ gainNeg.connect(merger, 0, 1);
|
||||
+
|
||||
+ // Source whose AudioParam is connected to the graph
|
||||
+ // that produces NaN values. Use a non-default value offset
|
||||
+ // just in case something is wrong we get default for some
|
||||
+ // other reason.
|
||||
+ let src = new ConstantSourceNode(context, {offset: 100});
|
||||
+
|
||||
+ gainPos.connect(src.offset);
|
||||
+ gainNeg.connect(src.offset);
|
||||
+
|
||||
+ // AudioParam output goes to channel 1 of the destination.
|
||||
+ src.connect(merger, 0, 0);
|
||||
+
|
||||
+ // Let's go!
|
||||
+ mod.start();
|
||||
+ src.start();
|
||||
+
|
||||
+ let buffer = await context.startRendering();
|
||||
+
|
||||
+ let input = buffer.getChannelData(1);
|
||||
+ let output = buffer.getChannelData(0);
|
||||
+
|
||||
+ // Have to test manually for NaN values in the input because
|
||||
+ // NaN fails all comparisons.
|
||||
+ let isNaN = true;
|
||||
+ for (let k = 0; k < input.length; ++k) {
|
||||
+ if (!Number.isNaN(input[k])) {
|
||||
+ isNaN = false;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ should(isNaN, 'AudioParam input contains only NaN').beTrue();
|
||||
+
|
||||
+ // Output of the AudioParam should have all NaN values
|
||||
+ // replaced by the default.
|
||||
+ should(output, 'AudioParam output')
|
||||
+ .beConstantValueOf(src.offset.defaultValue);
|
||||
+
|
||||
+ task.done();
|
||||
+ });
|
||||
+
|
||||
+ audit.run();
|
||||
+ </script>
|
||||
+ </body>
|
||||
+</html>
|
||||
61
patches/chromium/cherry-pick-3abc372c9c00.patch
Normal file
61
patches/chromium/cherry-pick-3abc372c9c00.patch
Normal file
@@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xiaocheng Hu <xiaochengh@chromium.org>
|
||||
Date: Tue, 3 Nov 2020 23:00:29 +0000
|
||||
Subject: Apply markup sanitizer in CompositeEditCommand::MoveParagraphs()
|
||||
|
||||
CompositeEditCommand::MoveParagraphs() serailizes part of the DOM and
|
||||
then re-parse it and insert it at some other place of the document. This
|
||||
is essentially a copy-and-paste, and can be exploited in the same way
|
||||
how copy-and-paste is exploited. So we should also sanitize markup in
|
||||
the function.
|
||||
|
||||
(cherry picked from commit c529cbcc1bb0f72af944c30f03c2b3b435317bc7)
|
||||
|
||||
Bug: 1141350
|
||||
Change-Id: I25c1dfc61c20b9134b23e057c5a3a0f56c190b5c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2500633
|
||||
Commit-Queue: Yoshifumi Inoue <yosin@chromium.org>
|
||||
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#821098}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2518088
|
||||
Reviewed-by: Xiaocheng Hu <xiaochengh@chromium.org>
|
||||
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4280@{#1099}
|
||||
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
|
||||
index 08a19440da1bff652481c3cedae2f1edb2b58246..0ba9af6cff6dd6eaa373a0f4dca37226aee85ca0 100644
|
||||
--- a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
|
||||
+++ b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
|
||||
@@ -1507,19 +1507,18 @@ void CompositeEditCommand::MoveParagraphs(
|
||||
// FIXME: This is an inefficient way to preserve style on nodes in the
|
||||
// paragraph to move. It shouldn't matter though, since moved paragraphs will
|
||||
// usually be quite small.
|
||||
- DocumentFragment* fragment =
|
||||
- start_of_paragraph_to_move.DeepEquivalent() !=
|
||||
- end_of_paragraph_to_move.DeepEquivalent()
|
||||
- ? CreateFragmentFromMarkup(
|
||||
- GetDocument(),
|
||||
- CreateMarkup(start.ParentAnchoredEquivalent(),
|
||||
- end.ParentAnchoredEquivalent(),
|
||||
- CreateMarkupOptions::Builder()
|
||||
- .SetShouldConvertBlocksToInlines(true)
|
||||
- .SetConstrainingAncestor(constraining_ancestor)
|
||||
- .Build()),
|
||||
- "", kDisallowScriptingAndPluginContent)
|
||||
- : nullptr;
|
||||
+ DocumentFragment* fragment = nullptr;
|
||||
+ if (start_of_paragraph_to_move.DeepEquivalent() !=
|
||||
+ end_of_paragraph_to_move.DeepEquivalent()) {
|
||||
+ const String paragraphs_markup = CreateMarkup(
|
||||
+ start.ParentAnchoredEquivalent(), end.ParentAnchoredEquivalent(),
|
||||
+ CreateMarkupOptions::Builder()
|
||||
+ .SetShouldConvertBlocksToInlines(true)
|
||||
+ .SetConstrainingAncestor(constraining_ancestor)
|
||||
+ .Build());
|
||||
+ fragment = CreateSanitizedFragmentFromMarkupWithContext(
|
||||
+ GetDocument(), paragraphs_markup, 0, paragraphs_markup.length(), "");
|
||||
+ }
|
||||
|
||||
// A non-empty paragraph's style is moved when we copy and move it. We don't
|
||||
// move anything if we're given an empty paragraph, but an empty paragraph can
|
||||
46
patches/chromium/cherry-pick-3c80bb2a594f.patch
Normal file
46
patches/chromium/cherry-pick-3c80bb2a594f.patch
Normal file
@@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jana Grill <janagrill@google.com>
|
||||
Date: Wed, 14 Apr 2021 08:40:10 +0000
|
||||
Subject: Forbid script execution while updating the paint lifecycle.
|
||||
|
||||
(cherry picked from commit 5425d3b100fab533ea9ddc2ed8fbfc4870db0587)
|
||||
|
||||
Bug: 1196781
|
||||
Change-Id: Idc8d24792d5c413691977b09ca821de4e13887ad
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2812000
|
||||
Commit-Queue: Adrian Taylor <adetaylor@chromium.org>
|
||||
Commit-Queue: Robert Flack <flackr@chromium.org>
|
||||
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#870275}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2821879
|
||||
Reviewed-by: Robert Flack <flackr@chromium.org>
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Jana Grill <janagrill@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1601}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
|
||||
index 9a4c7a5249424b021759bf7895dd3f343b9641e6..37054d34157e7f4b4d65b022cdb83c832deb26a8 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
|
||||
@@ -2648,11 +2648,14 @@ void LocalFrameView::RunPaintLifecyclePhase() {
|
||||
for (PaintLayerScrollableArea* area : *animating_scrollable_areas)
|
||||
area->UpdateCompositorScrollAnimations();
|
||||
}
|
||||
- frame_view.GetLayoutView()
|
||||
- ->GetDocument()
|
||||
- .GetDocumentAnimations()
|
||||
- .UpdateAnimations(DocumentLifecycle::kPaintClean,
|
||||
- paint_artifact_compositor_.get());
|
||||
+ {
|
||||
+ ScriptForbiddenScope forbid_script;
|
||||
+ frame_view.GetLayoutView()
|
||||
+ ->GetDocument()
|
||||
+ .GetDocumentAnimations()
|
||||
+ .UpdateAnimations(DocumentLifecycle::kPaintClean,
|
||||
+ paint_artifact_compositor_.get());
|
||||
+ }
|
||||
});
|
||||
|
||||
// Initialize animation properties in the newly created paint property
|
||||
56
patches/chromium/cherry-pick-3ca3d70c7af5.patch
Normal file
56
patches/chromium/cherry-pick-3ca3d70c7af5.patch
Normal file
@@ -0,0 +1,56 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yuri Wiitala <miu@chromium.org>
|
||||
Date: Thu, 10 Dec 2020 18:07:39 +0000
|
||||
Subject: Minor UI logic changes to prevent a UAF bug when starting tab
|
||||
capture.
|
||||
|
||||
See discussion in crbug 1155426 for details. Changes:
|
||||
|
||||
MediaStreamCaptureIndicator::UIDelegate: Ignore multiple calls to
|
||||
OnStarted().
|
||||
|
||||
TabSharingUIViews: Unconditionally execute clean-up tasks in destructor.
|
||||
|
||||
Bug: 1155426
|
||||
Change-Id: I392fba38118ce51744ba36b4dec19ebfe39f1fbe
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2581028
|
||||
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
|
||||
Reviewed-by: Marina Ciocea <marinaciocea@chromium.org>
|
||||
Commit-Queue: Yuri Wiitala <miu@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#835736}
|
||||
|
||||
diff --git a/chrome/browser/media/webrtc/media_stream_capture_indicator.cc b/chrome/browser/media/webrtc/media_stream_capture_indicator.cc
|
||||
index ce93d308a3d1099d9edbeea88ce8d05e60158117..99203ebb36edc21697518d172d67831deed8ba04 100644
|
||||
--- a/chrome/browser/media/webrtc/media_stream_capture_indicator.cc
|
||||
+++ b/chrome/browser/media/webrtc/media_stream_capture_indicator.cc
|
||||
@@ -186,7 +186,12 @@ class MediaStreamCaptureIndicator::UIDelegate : public content::MediaStreamUI {
|
||||
gfx::NativeViewId OnStarted(
|
||||
base::OnceClosure stop_callback,
|
||||
content::MediaStreamUI::SourceCallback source_callback) override {
|
||||
- DCHECK(!started_);
|
||||
+ if (started_) {
|
||||
+ // Ignore possibly-compromised renderers that might call
|
||||
+ // MediaStreamDispatcherHost::OnStreamStarted() more than once.
|
||||
+ // See: https://crbug.com/1155426
|
||||
+ return 0;
|
||||
+ }
|
||||
started_ = true;
|
||||
|
||||
if (device_usage_) {
|
||||
diff --git a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc
|
||||
index 1582ccedd3fac5368e7adf94ec222e5d85b18aab..35e4f3e93c41f52fb50599da4050c0f3c25dd0d4 100644
|
||||
--- a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc
|
||||
+++ b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc
|
||||
@@ -134,8 +134,10 @@ TabSharingUIViews::TabSharingUIViews(const content::DesktopMediaID& media_id,
|
||||
}
|
||||
|
||||
TabSharingUIViews::~TabSharingUIViews() {
|
||||
- if (!infobars_.empty())
|
||||
- StopSharing();
|
||||
+ // Unconditionally call StopSharing(), to ensure all clean-up has been
|
||||
+ // performed if tasks race (e.g., OnStarted() is called after
|
||||
+ // OnInfoBarRemoved()). See: https://crbug.com/1155426
|
||||
+ StopSharing();
|
||||
}
|
||||
|
||||
gfx::NativeViewId TabSharingUIViews::OnStarted(
|
||||
100
patches/chromium/cherry-pick-406ae3e8a9a8.patch
Normal file
100
patches/chromium/cherry-pick-406ae3e8a9a8.patch
Normal file
@@ -0,0 +1,100 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Rockot <rockot@google.com>
|
||||
Date: Tue, 20 Apr 2021 15:46:33 +0000
|
||||
Subject: M86-LTS: Mojo: Properly validate broadcast events
|
||||
|
||||
This corrects broadcast event deserialization by adding a missing
|
||||
validation step when decoding the outer message header.
|
||||
|
||||
(cherry picked from commit 6740adb28374ddeee13febfd5e5d20cb8a365979)
|
||||
|
||||
Fixed: 1195308
|
||||
Change-Id: Ia67a20e48614e7ef00b1b32f7f4e5f20235be310
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2808678
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#870238}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2837712
|
||||
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Auto-Submit: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
|
||||
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1614}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/mojo/core/node_channel.cc b/mojo/core/node_channel.cc
|
||||
index 061ea1026e95d1b1f80a762ce377aebdd97e1b42..07e3b8b21f7ef70b64d214ec03e0dd1eb807fad6 100644
|
||||
--- a/mojo/core/node_channel.cc
|
||||
+++ b/mojo/core/node_channel.cc
|
||||
@@ -191,13 +191,16 @@ Channel::MessagePtr NodeChannel::CreateEventMessage(size_t capacity,
|
||||
}
|
||||
|
||||
// static
|
||||
-void NodeChannel::GetEventMessageData(Channel::Message* message,
|
||||
+bool NodeChannel::GetEventMessageData(Channel::Message& message,
|
||||
void** data,
|
||||
size_t* num_data_bytes) {
|
||||
- // NOTE: OnChannelMessage guarantees that we never accept a Channel::Message
|
||||
- // with a payload of fewer than |sizeof(Header)| bytes.
|
||||
- *data = reinterpret_cast<Header*>(message->mutable_payload()) + 1;
|
||||
- *num_data_bytes = message->payload_size() - sizeof(Header);
|
||||
+ // NOTE: Callers must guarantee that the payload in `message` must be at least
|
||||
+ // large enough to hold a Header.
|
||||
+ if (message.payload_size() < sizeof(Header))
|
||||
+ return false;
|
||||
+ *data = reinterpret_cast<Header*>(message.mutable_payload()) + 1;
|
||||
+ *num_data_bytes = message.payload_size() - sizeof(Header);
|
||||
+ return true;
|
||||
}
|
||||
|
||||
void NodeChannel::Start() {
|
||||
diff --git a/mojo/core/node_channel.h b/mojo/core/node_channel.h
|
||||
index 58ab42bd01fc856856d171985dac50934d4e00b2..7ae08e3e73110667f0eafe0fe4f70242bfeece39 100644
|
||||
--- a/mojo/core/node_channel.h
|
||||
+++ b/mojo/core/node_channel.h
|
||||
@@ -90,7 +90,9 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeChannel
|
||||
void** payload,
|
||||
size_t num_handles);
|
||||
|
||||
- static void GetEventMessageData(Channel::Message* message,
|
||||
+ // Retrieves address and size of an Event message's underlying message data.
|
||||
+ // Returns `false` if the message is not a valid Event message.
|
||||
+ static bool GetEventMessageData(Channel::Message& message,
|
||||
void** data,
|
||||
size_t* num_data_bytes);
|
||||
|
||||
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc
|
||||
index c333ed64f71f0dfe5d0012b07bcedccfd94cd5e9..a8b8520729510408dc822532271d0ff4a36a7151 100644
|
||||
--- a/mojo/core/node_controller.cc
|
||||
+++ b/mojo/core/node_controller.cc
|
||||
@@ -76,7 +76,9 @@ ports::ScopedEvent DeserializeEventMessage(
|
||||
Channel::MessagePtr channel_message) {
|
||||
void* data;
|
||||
size_t size;
|
||||
- NodeChannel::GetEventMessageData(channel_message.get(), &data, &size);
|
||||
+ bool valid = NodeChannel::GetEventMessageData(*channel_message, &data, &size);
|
||||
+ if (!valid)
|
||||
+ return nullptr;
|
||||
auto event = ports::Event::Deserialize(data, size);
|
||||
if (!event)
|
||||
return nullptr;
|
||||
diff --git a/mojo/core/user_message_impl.cc b/mojo/core/user_message_impl.cc
|
||||
index 2f1665e55cf0af69c58c21f2e0d602a93e79052e..a6b35b2cd812bb0da7026b088aa0d96acbbc6a2f 100644
|
||||
--- a/mojo/core/user_message_impl.cc
|
||||
+++ b/mojo/core/user_message_impl.cc
|
||||
@@ -415,7 +415,14 @@ Channel::MessagePtr UserMessageImpl::FinalizeEventMessage(
|
||||
if (channel_message) {
|
||||
void* data;
|
||||
size_t size;
|
||||
- NodeChannel::GetEventMessageData(channel_message.get(), &data, &size);
|
||||
+ // The `channel_message` must either be produced locally or must have
|
||||
+ // already been validated by the caller, as is done for example by
|
||||
+ // NodeController::DeserializeEventMessage before
|
||||
+ // NodeController::OnBroadcast re-serializes each copy of the message it
|
||||
+ // received.
|
||||
+ bool result =
|
||||
+ NodeChannel::GetEventMessageData(*channel_message, &data, &size);
|
||||
+ DCHECK(result);
|
||||
message_event->Serialize(data);
|
||||
}
|
||||
|
||||
326
patches/chromium/cherry-pick-4794770cf175.patch
Normal file
326
patches/chromium/cherry-pick-4794770cf175.patch
Normal file
@@ -0,0 +1,326 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Rice <ricea@chromium.org>
|
||||
Date: Fri, 4 Dec 2020 10:19:12 +0000
|
||||
Subject: Correctly handle detach during (de)compression
|
||||
|
||||
Sometimes CompressionStream and DecompressionStream enqueue multiple
|
||||
output chunks for a single input chunk. When this happens, JavaScript
|
||||
code can detach the input ArrayBuffer while the stream is processing it.
|
||||
This will cause an error when zlib tries to read the buffer again
|
||||
afterwards.
|
||||
|
||||
To prevent this, buffer output chunks until the entire input chunk has
|
||||
been processed, and then enqueue them all at once.
|
||||
|
||||
Bug: 1151298
|
||||
Change-Id: I03fca26fc641d54b09067e3994b76ee8efca6839
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2567539
|
||||
Commit-Queue: Adam Rice <ricea@chromium.org>
|
||||
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#833659}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/compression/deflate_transformer.cc b/third_party/blink/renderer/modules/compression/deflate_transformer.cc
|
||||
index e663e563d58e90cdce5185636d1b1aa75491195c..e806b84afbb6cd82c53832e0c0b455ae0767a34a 100644
|
||||
--- a/third_party/blink/renderer/modules/compression/deflate_transformer.cc
|
||||
+++ b/third_party/blink/renderer/modules/compression/deflate_transformer.cc
|
||||
@@ -111,6 +111,10 @@ void DeflateTransformer::Deflate(const uint8_t* start,
|
||||
// Zlib treats this pointer as const, so this cast is safe.
|
||||
stream_.next_in = const_cast<uint8_t*>(start);
|
||||
|
||||
+ // enqueue() may execute JavaScript which may invalidate the input buffer. So
|
||||
+ // accumulate all the output before calling enqueue().
|
||||
+ HeapVector<Member<DOMUint8Array>, 1u> buffers;
|
||||
+
|
||||
do {
|
||||
stream_.avail_out = out_buffer_.size();
|
||||
stream_.next_out = out_buffer_.data();
|
||||
@@ -120,16 +124,21 @@ void DeflateTransformer::Deflate(const uint8_t* start,
|
||||
|
||||
wtf_size_t bytes = out_buffer_.size() - stream_.avail_out;
|
||||
if (bytes) {
|
||||
- controller->enqueue(
|
||||
- script_state_,
|
||||
- ScriptValue::From(script_state_,
|
||||
- DOMUint8Array::Create(out_buffer_.data(), bytes)),
|
||||
- exception_state);
|
||||
- if (exception_state.HadException()) {
|
||||
- return;
|
||||
- }
|
||||
+ buffers.push_back(DOMUint8Array::Create(out_buffer_.data(), bytes));
|
||||
}
|
||||
} while (stream_.avail_out == 0);
|
||||
+
|
||||
+ DCHECK_EQ(stream_.avail_in, 0u);
|
||||
+
|
||||
+ // JavaScript may be executed inside this loop, however it is safe because
|
||||
+ // |buffers| is a local variable that JavaScript cannot modify.
|
||||
+ for (DOMUint8Array* buffer : buffers) {
|
||||
+ controller->enqueue(script_state_, ScriptValue::From(script_state_, buffer),
|
||||
+ exception_state);
|
||||
+ if (exception_state.HadException()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
void DeflateTransformer::Trace(Visitor* visitor) const {
|
||||
diff --git a/third_party/blink/renderer/modules/compression/inflate_transformer.cc b/third_party/blink/renderer/modules/compression/inflate_transformer.cc
|
||||
index f348a5086e4254bc972dd321109d9fbf676f1d5e..29667b5752250466cd71542ab8868d6e14961e81 100644
|
||||
--- a/third_party/blink/renderer/modules/compression/inflate_transformer.cc
|
||||
+++ b/third_party/blink/renderer/modules/compression/inflate_transformer.cc
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
|
||||
#include "third_party/blink/renderer/platform/bindings/to_v8.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
|
||||
+#include "third_party/blink/renderer/platform/wtf/vector.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace blink {
|
||||
@@ -93,11 +94,15 @@ ScriptPromise InflateTransformer::Flush(
|
||||
TransformStreamDefaultController* controller,
|
||||
ExceptionState& exception_state) {
|
||||
DCHECK(!was_flush_called_);
|
||||
+ was_flush_called_ = true;
|
||||
Inflate(nullptr, 0u, IsFinished(true), controller, exception_state);
|
||||
inflateEnd(&stream_);
|
||||
- was_flush_called_ = true;
|
||||
out_buffer_.clear();
|
||||
|
||||
+ if (exception_state.HadException()) {
|
||||
+ return ScriptPromise();
|
||||
+ }
|
||||
+
|
||||
if (!reached_end_) {
|
||||
exception_state.ThrowTypeError("Compressed input was truncated.");
|
||||
}
|
||||
@@ -121,12 +126,22 @@ void InflateTransformer::Inflate(const uint8_t* start,
|
||||
// Zlib treats this pointer as const, so this cast is safe.
|
||||
stream_.next_in = const_cast<uint8_t*>(start);
|
||||
|
||||
+ // enqueue() may execute JavaScript which may invalidate the input buffer. So
|
||||
+ // accumulate all the output before calling enqueue().
|
||||
+ HeapVector<Member<DOMUint8Array>, 1u> buffers;
|
||||
+
|
||||
do {
|
||||
stream_.avail_out = out_buffer_.size();
|
||||
stream_.next_out = out_buffer_.data();
|
||||
const int err = inflate(&stream_, finished ? Z_FINISH : Z_NO_FLUSH);
|
||||
if (err != Z_OK && err != Z_STREAM_END && err != Z_BUF_ERROR) {
|
||||
DCHECK_NE(err, Z_STREAM_ERROR);
|
||||
+
|
||||
+ EnqueueBuffers(controller, std::move(buffers), exception_state);
|
||||
+ if (exception_state.HadException()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (err == Z_DATA_ERROR) {
|
||||
exception_state.ThrowTypeError(
|
||||
String("The compressed data was not valid: ") + stream_.msg + ".");
|
||||
@@ -138,25 +153,44 @@ void InflateTransformer::Inflate(const uint8_t* start,
|
||||
|
||||
wtf_size_t bytes = out_buffer_.size() - stream_.avail_out;
|
||||
if (bytes) {
|
||||
- controller->enqueue(
|
||||
- script_state_,
|
||||
- ScriptValue::From(script_state_,
|
||||
- DOMUint8Array::Create(out_buffer_.data(), bytes)),
|
||||
- exception_state);
|
||||
- if (exception_state.HadException()) {
|
||||
- return;
|
||||
- }
|
||||
+ buffers.push_back(DOMUint8Array::Create(out_buffer_.data(), bytes));
|
||||
}
|
||||
|
||||
if (err == Z_STREAM_END) {
|
||||
reached_end_ = true;
|
||||
- if (stream_.next_in < start + length) {
|
||||
+ const bool junk_found = stream_.avail_in > 0;
|
||||
+
|
||||
+ EnqueueBuffers(controller, std::move(buffers), exception_state);
|
||||
+ if (exception_state.HadException()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (junk_found) {
|
||||
exception_state.ThrowTypeError(
|
||||
"Junk found after end of compressed data.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
} while (stream_.avail_out == 0);
|
||||
+
|
||||
+ DCHECK_EQ(stream_.avail_in, 0u);
|
||||
+
|
||||
+ EnqueueBuffers(controller, std::move(buffers), exception_state);
|
||||
+}
|
||||
+
|
||||
+void InflateTransformer::EnqueueBuffers(
|
||||
+ TransformStreamDefaultController* controller,
|
||||
+ HeapVector<Member<DOMUint8Array>, 1u> buffers,
|
||||
+ ExceptionState& exception_state) {
|
||||
+ // JavaScript may be executed inside this loop, however it is safe because
|
||||
+ // |buffers| is a local variable that JavaScript cannot modify.
|
||||
+ for (DOMUint8Array* buffer : buffers) {
|
||||
+ controller->enqueue(script_state_, ScriptValue::From(script_state_, buffer),
|
||||
+ exception_state);
|
||||
+ if (exception_state.HadException()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
void InflateTransformer::Trace(Visitor* visitor) const {
|
||||
diff --git a/third_party/blink/renderer/modules/compression/inflate_transformer.h b/third_party/blink/renderer/modules/compression/inflate_transformer.h
|
||||
index 290e91808dfcc16ed7ff6ec9e6e42eb412dfc969..c5df437f1684e6ca1201d9b3d32dff19903a0b5e 100644
|
||||
--- a/third_party/blink/renderer/modules/compression/inflate_transformer.h
|
||||
+++ b/third_party/blink/renderer/modules/compression/inflate_transformer.h
|
||||
@@ -41,6 +41,10 @@ class InflateTransformer final : public TransformStreamTransformer {
|
||||
TransformStreamDefaultController*,
|
||||
ExceptionState&);
|
||||
|
||||
+ void EnqueueBuffers(TransformStreamDefaultController*,
|
||||
+ HeapVector<Member<DOMUint8Array>, 1u> buffers,
|
||||
+ ExceptionState&);
|
||||
+
|
||||
Member<ScriptState> script_state_;
|
||||
|
||||
z_stream stream_;
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/compression/compression-with-detach.tentative.any.js b/third_party/blink/web_tests/external/wpt/compression/compression-with-detach.tentative.any.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..786bba21c800ca9f067a6d033f0345a52bfbb218
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/compression/compression-with-detach.tentative.any.js
|
||||
@@ -0,0 +1,55 @@
|
||||
+// META: global=window,worker
|
||||
+// META: script=resources/concatenate-stream.js
|
||||
+
|
||||
+'use strict';
|
||||
+
|
||||
+const kInputLength = 500000;
|
||||
+
|
||||
+function createLargeRandomInput() {
|
||||
+ const buffer = new ArrayBuffer(kInputLength);
|
||||
+ // The getRandomValues API will only let us get 65536 bytes at a time, so call
|
||||
+ // it multiple times.
|
||||
+ const kChunkSize = 65536;
|
||||
+ for (let offset = 0; offset < kInputLength; offset += kChunkSize) {
|
||||
+ const length =
|
||||
+ offset + kChunkSize > kInputLength ? kInputLength - offset : kChunkSize;
|
||||
+ const view = new Uint8Array(buffer, offset, length);
|
||||
+ crypto.getRandomValues(view);
|
||||
+ }
|
||||
+ return new Uint8Array(buffer);
|
||||
+}
|
||||
+
|
||||
+function decompress(view) {
|
||||
+ const ds = new DecompressionStream('deflate');
|
||||
+ const writer = ds.writable.getWriter();
|
||||
+ writer.write(view);
|
||||
+ writer.close();
|
||||
+ return concatenateStream(ds.readable);
|
||||
+}
|
||||
+
|
||||
+promise_test(async () => {
|
||||
+ const input = createLargeRandomInput();
|
||||
+ const inputCopy = input.slice(0, input.byteLength);
|
||||
+ const cs = new CompressionStream('deflate');
|
||||
+ const writer = cs.writable.getWriter();
|
||||
+ writer.write(input);
|
||||
+ writer.close();
|
||||
+ // Object.prototype.then will be looked up synchronously when the promise
|
||||
+ // returned by read() is resolved.
|
||||
+ Object.defineProperty(Object.prototype, 'then', {
|
||||
+ get() {
|
||||
+ // Cause input to become detached and unreferenced.
|
||||
+ try {
|
||||
+ postMessage(undefined, 'nowhere', [input.buffer]);
|
||||
+ } catch (e) {
|
||||
+ // It's already detached.
|
||||
+ }
|
||||
+ }
|
||||
+ });
|
||||
+ const output = await concatenateStream(cs.readable);
|
||||
+ // Perform the comparison as strings since this is reasonably fast even when
|
||||
+ // JITted JavaScript is running under an emulator.
|
||||
+ assert_equals(
|
||||
+ inputCopy.toString(), (await decompress(output)).toString(),
|
||||
+ 'decompressing the output should return the input');
|
||||
+}, 'data should be correctly compressed even if input is detached partway');
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/compression/decompression-with-detach.tentative.any.js b/third_party/blink/web_tests/external/wpt/compression/decompression-with-detach.tentative.any.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a2f8bda09148f0d323022b1f93be78d83c4aa654
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/compression/decompression-with-detach.tentative.any.js
|
||||
@@ -0,0 +1,41 @@
|
||||
+// META: global=window,worker
|
||||
+// META: script=resources/concatenate-stream.js
|
||||
+
|
||||
+'use strict';
|
||||
+
|
||||
+const kInputLength = 1000000;
|
||||
+
|
||||
+async function createLargeCompressedInput() {
|
||||
+ const cs = new CompressionStream('deflate');
|
||||
+ // The input has to be large enough that it won't fit in a single chunk when
|
||||
+ // decompressed.
|
||||
+ const writer = cs.writable.getWriter();
|
||||
+ writer.write(new Uint8Array(kInputLength));
|
||||
+ writer.close();
|
||||
+ return concatenateStream(cs.readable);
|
||||
+}
|
||||
+
|
||||
+promise_test(async () => {
|
||||
+ const input = await createLargeCompressedInput();
|
||||
+ const ds = new DecompressionStream('deflate');
|
||||
+ const writer = ds.writable.getWriter();
|
||||
+ writer.write(input);
|
||||
+ writer.close();
|
||||
+ // Object.prototype.then will be looked up synchronously when the promise
|
||||
+ // returned by read() is resolved.
|
||||
+ Object.defineProperty(Object.prototype, 'then', {
|
||||
+ get() {
|
||||
+ // Cause input to become detached and unreferenced.
|
||||
+ try {
|
||||
+ postMessage(undefined, 'nowhere', [input.buffer]);
|
||||
+ } catch (e) {
|
||||
+ // It's already detached.
|
||||
+ }
|
||||
+ }
|
||||
+ });
|
||||
+ const output = await concatenateStream(ds.readable);
|
||||
+ // If output successfully decompressed and gave the right length, we can be
|
||||
+ // reasonably confident that no data corruption happened.
|
||||
+ assert_equals(
|
||||
+ output.byteLength, kInputLength, 'output should be the right length');
|
||||
+}, 'data should be correctly decompressed even if input is detached partway');
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/compression/resources/concatenate-stream.js b/third_party/blink/web_tests/external/wpt/compression/resources/concatenate-stream.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a35bb1416e754893e331c0089d97720ae3b5af8e
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/compression/resources/concatenate-stream.js
|
||||
@@ -0,0 +1,25 @@
|
||||
+'use strict';
|
||||
+
|
||||
+// Read all the chunks from a stream that returns BufferSource objects and
|
||||
+// concatenate them into a single Uint8Array.
|
||||
+async function concatenateStream(readableStream) {
|
||||
+ const reader = readableStream.getReader();
|
||||
+ let totalSize = 0;
|
||||
+ const buffers = [];
|
||||
+ while (true) {
|
||||
+ const { value, done } = await reader.read();
|
||||
+ if (done) {
|
||||
+ break;
|
||||
+ }
|
||||
+ buffers.push(value);
|
||||
+ totalSize += value.byteLength;
|
||||
+ }
|
||||
+ reader.releaseLock();
|
||||
+ const concatenated = new Uint8Array(totalSize);
|
||||
+ let offset = 0;
|
||||
+ for (const buffer of buffers) {
|
||||
+ concatenated.set(buffer, offset);
|
||||
+ offset += buffer.byteLength;
|
||||
+ }
|
||||
+ return concatenated;
|
||||
+}
|
||||
45
patches/chromium/cherry-pick-5651fb858b75.patch
Normal file
45
patches/chromium/cherry-pick-5651fb858b75.patch
Normal file
@@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Harald Alvestrand <hta@chromium.org>
|
||||
Date: Thu, 11 Mar 2021 18:54:23 +0000
|
||||
Subject: Iterate more carefully over DTLS transports at close
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Ensure that even if the set of DTLS transports is modified during
|
||||
callbacks called from close, the process will be well-defined.
|
||||
|
||||
(cherry picked from commit 4f62c7bb28b0ce77b773a611c6ba02b361db1c85)
|
||||
|
||||
Bug: chromium:1167357
|
||||
Change-Id: I712280e7382a647027912178156127831b437f75
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2639893
|
||||
Reviewed-by: Henrik Boström <hbos@chromium.org>
|
||||
Commit-Queue: Harald Alvestrand <hta@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#845122}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2752880
|
||||
Reviewed-by: Adrian Taylor <adetaylor@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4389@{#1521}
|
||||
Cr-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
|
||||
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 1503444ac2931a4205afe990f2e2dac11206de48..5d0b7e9cbe1f3459057b50879ab88d5a2ae12c20 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
|
||||
@@ -3438,8 +3438,14 @@ void RTCPeerConnection::CloseInternal() {
|
||||
if (sctp_transport_) {
|
||||
sctp_transport_->Close();
|
||||
}
|
||||
- for (auto& dtls_transport_iter : dtls_transports_by_native_transport_) {
|
||||
- dtls_transport_iter.value->Close();
|
||||
+ // Since Close() can trigger JS-level callbacks, iterate over a copy
|
||||
+ // of the transports list.
|
||||
+ auto dtls_transports_copy = dtls_transports_by_native_transport_;
|
||||
+ for (auto& dtls_transport_iter : dtls_transports_copy) {
|
||||
+ // Since "value" is a WeakPtr, check if it's still valid.
|
||||
+ if (dtls_transport_iter.value) {
|
||||
+ dtls_transport_iter.value->Close();
|
||||
+ }
|
||||
}
|
||||
|
||||
feature_handle_for_scheduler_.reset();
|
||||
37
patches/chromium/cherry-pick-5ffbb7ed173a.patch
Normal file
37
patches/chromium/cherry-pick-5ffbb7ed173a.patch
Normal file
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Darwin Huang <huangdarwin@chromium.org>
|
||||
Date: Fri, 13 Nov 2020 10:07:05 +0000
|
||||
Subject: Pepper: Ensure weak pointer is still valid before use (M86).
|
||||
|
||||
TBR=bbudge@chromium.org
|
||||
(cherry picked from commit f24c213293752250db05e11c5e4b77adce002d38)
|
||||
|
||||
Bug: 1146675
|
||||
Change-Id: I382dcb5c0b09a26e3c397ebef46947f626e2aef9
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2527065
|
||||
Reviewed-by: Bill Budge <bbudge@chromium.org>
|
||||
Commit-Queue: Darwin Huang <huangdarwin@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#825558}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2536757
|
||||
Reviewed-by: Darwin Huang <huangdarwin@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1448}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/content/browser/renderer_host/pepper/pepper_file_io_host.cc b/content/browser/renderer_host/pepper/pepper_file_io_host.cc
|
||||
index 28fba2fc56ddb7f42f3390db99999998ba912867..74bb7c539f8f05971b020e1d370098f5825e0ac2 100644
|
||||
--- a/content/browser/renderer_host/pepper/pepper_file_io_host.cc
|
||||
+++ b/content/browser/renderer_host/pepper/pepper_file_io_host.cc
|
||||
@@ -248,7 +248,12 @@ void PepperFileIOHost::GotUIThreadStuffForInternalFileSystems(
|
||||
return;
|
||||
}
|
||||
|
||||
- DCHECK(file_system_host_.get());
|
||||
+ if (!file_system_host_.get()) {
|
||||
+ reply_context.params.set_result(PP_ERROR_FAILED);
|
||||
+ SendOpenErrorReply(reply_context);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
DCHECK(file_system_host_->GetFileSystemOperationRunner());
|
||||
|
||||
file_system_host_->GetFileSystemOperationRunner()->OpenFile(
|
||||
48
patches/chromium/cherry-pick-6a6361c9f31c.patch
Normal file
48
patches/chromium/cherry-pick-6a6361c9f31c.patch
Normal file
@@ -0,0 +1,48 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Palak Agarwal <agpalak@chromium.org>
|
||||
Date: Wed, 31 Mar 2021 16:10:26 +0000
|
||||
Subject: WebContents bug fix: Device capture only if web contents is valid
|
||||
|
||||
(cherry picked from commit a462be0883486431086c5f07cdafbd3607005a59)
|
||||
|
||||
(cherry picked from commit e6f11cafde08981e47ba77e71abf99a271f7a042)
|
||||
|
||||
Bug: 1181228
|
||||
Change-Id: I0a4c9718a3c0ccb52cefa4565b9787e6912554c9
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2752235
|
||||
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
|
||||
Commit-Queue: Palak Agarwal <agpalak@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#863828}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2782122
|
||||
Auto-Submit: Guido Urdaneta <guidou@chromium.org>
|
||||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4389@{#1586}
|
||||
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2795101
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
|
||||
Auto-Submit: Artem Sumaneev <asumaneev@google.com>
|
||||
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1585}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
|
||||
index e3f7e784f0339581a1c8a50301f8dbfd465abbfd..1f0811610e155715cc5cd72bbaa7e703728a1fe5 100644
|
||||
--- a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
|
||||
+++ b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
|
||||
@@ -248,6 +248,14 @@ void DesktopCaptureAccessHandler::ProcessScreenCaptureAccessRequest(
|
||||
const bool display_notification =
|
||||
display_notification_ && ShouldDisplayNotification(extension);
|
||||
|
||||
+ if (!content::WebContents::FromRenderFrameHost(
|
||||
+ content::RenderFrameHost::FromID(request.render_process_id,
|
||||
+ request.render_frame_id))) {
|
||||
+ std::move(callback).Run(
|
||||
+ devices, blink::mojom::MediaStreamRequestResult::INVALID_STATE,
|
||||
+ std::move(ui));
|
||||
+ return;
|
||||
+ }
|
||||
ui = GetDevicesForDesktopCapture(
|
||||
web_contents, &devices, screen_id,
|
||||
blink::mojom::MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE,
|
||||
82
patches/chromium/cherry-pick-6b84dc72351b.patch
Normal file
82
patches/chromium/cherry-pick-6b84dc72351b.patch
Normal file
@@ -0,0 +1,82 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brendon Tiszka <btiszka@gmail.com>
|
||||
Date: Tue, 20 Apr 2021 15:45:03 +0000
|
||||
Subject: M86-LTS: Ensure that BrowserContext is not used after it has been
|
||||
freed
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Previously, it was possible for the BrowserContext to be destroyed
|
||||
before ReportAnchorElementMetricsOnClick attempted to access it.
|
||||
|
||||
The fix uses the fact that NavigationPredictor extends
|
||||
WebContentsObserver and checks that web_contents is still alive
|
||||
before dereferencing BrowserContext. WebContents will always
|
||||
outlive BrowserContext.
|
||||
|
||||
R=lukasza@chromium.org, ryansturm@chromium.org
|
||||
|
||||
(cherry picked from commit 7313a810ae0b1361cbe8453bc5496654dee24c76)
|
||||
|
||||
Bug: 1197904
|
||||
Change-Id: Iee4f126e92670a84d57c7a4ec7d6f702fb975c7e
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2821639
|
||||
Reviewed-by: Ryan Sturm <ryansturm@chromium.org>
|
||||
Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org>
|
||||
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#872021}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2838328
|
||||
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Auto-Submit: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
|
||||
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1613}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/AUTHORS b/AUTHORS
|
||||
index 3aa101a8d38a899fefcca149e4ac8e658188e590..cccc1f6d1407183806e78cb99e56abe7bd93de82 100644
|
||||
--- a/AUTHORS
|
||||
+++ b/AUTHORS
|
||||
@@ -145,6 +145,7 @@ Bobby Powers <bobbypowers@gmail.com>
|
||||
Branden Archer <bma4@zips.uakron.edu>
|
||||
Brendan Kirby <brendan.kirby@imgtec.com>
|
||||
Brendan Long <self@brendanlong.com>
|
||||
+Brendon Tiszka <btiszka@gmail.com>
|
||||
Brian Clifton <clifton@brave.com>
|
||||
Brian G. Merrell <bgmerrell@gmail.com>
|
||||
Brian Konzman, SJ <b.g.konzman@gmail.com>
|
||||
diff --git a/chrome/browser/navigation_predictor/navigation_predictor.cc b/chrome/browser/navigation_predictor/navigation_predictor.cc
|
||||
index 495bb165a30f2b1bf690e6d0724ad8f347a76d44..b62a97501565555493f4db82ce4a1ababff19eb6 100644
|
||||
--- a/chrome/browser/navigation_predictor/navigation_predictor.cc
|
||||
+++ b/chrome/browser/navigation_predictor/navigation_predictor.cc
|
||||
@@ -506,6 +506,9 @@ void NavigationPredictor::ReportAnchorElementMetricsOnClick(
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
DCHECK(base::FeatureList::IsEnabled(blink::features::kNavigationPredictor));
|
||||
|
||||
+ if (!web_contents())
|
||||
+ return;
|
||||
+
|
||||
if (browser_context_->IsOffTheRecord())
|
||||
return;
|
||||
|
||||
@@ -652,6 +655,9 @@ void NavigationPredictor::ReportAnchorElementMetricsOnLoad(
|
||||
// Each document should only report metrics once when page is loaded.
|
||||
DCHECK(navigation_scores_map_.empty());
|
||||
|
||||
+ if (!web_contents())
|
||||
+ return;
|
||||
+
|
||||
if (browser_context_->IsOffTheRecord())
|
||||
return;
|
||||
|
||||
@@ -897,6 +903,9 @@ void NavigationPredictor::MaybeTakeActionOnLoad(
|
||||
}
|
||||
|
||||
void NavigationPredictor::MaybePrefetch() {
|
||||
+ if (!web_contents())
|
||||
+ return;
|
||||
+
|
||||
// If prefetches aren't allowed here, this URL has already
|
||||
// been prefetched, or the current tab is hidden,
|
||||
// we shouldn't prefetch again.
|
||||
71
patches/chromium/cherry-pick-6e8856624cbb.patch
Normal file
71
patches/chromium/cherry-pick-6e8856624cbb.patch
Normal file
@@ -0,0 +1,71 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Koji Ishii <kojii@chromium.org>
|
||||
Date: Thu, 11 Mar 2021 17:45:46 +0000
|
||||
Subject: Mark additional RootInlineBox dirty when culled inline box is removed
|
||||
|
||||
When a |LayoutInline| is removed, |LineBoxList::
|
||||
DirtyLinesFromChangedChild| tries to mark affected
|
||||
|RootInlineBox| dirty.
|
||||
|
||||
When the |LayoutInline| to be removed is culled, it tries to
|
||||
find the |RootInlineBox| from its previous siblings, then look
|
||||
for its previous and next |RootInlineBox|es.
|
||||
|
||||
Occasionally, the next next line of the previous sibling is
|
||||
wrapped at the |LayoutInline|, and that its |LineBreakObj()|
|
||||
holds the reference to the |LayoutInline|. This patch marks
|
||||
such |RootInlineBox| dirty.
|
||||
|
||||
(cherry picked from commit 2dbdabb28d647c8ee20cbe36e3c957e74aff663b)
|
||||
|
||||
Bug: 1186287
|
||||
Change-Id: I8ca73ebb4f5e4f13e997662fffd803d6a74ef49a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2748756
|
||||
Auto-Submit: Koji Ishii <kojii@chromium.org>
|
||||
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
|
||||
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#861724}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2749769
|
||||
Commit-Queue: Krishna Govind <govind@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4389@{#1518}
|
||||
Cr-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/layout/line/line_box_list.cc b/third_party/blink/renderer/core/layout/line/line_box_list.cc
|
||||
index 9d9d861f00cb9784041796acb91604d64dab1cb7..ed929849f721fbae25fd8c1106c95e563aca289b 100644
|
||||
--- a/third_party/blink/renderer/core/layout/line/line_box_list.cc
|
||||
+++ b/third_party/blink/renderer/core/layout/line/line_box_list.cc
|
||||
@@ -359,14 +359,32 @@ void LineBoxList::DirtyLinesFromChangedChild(LineLayoutItem container,
|
||||
// findNextLineBreak. findNextLineBreak, despite the name, actually returns
|
||||
// the first LayoutObject after the BR. <rdar://problem/3849947> "Typing
|
||||
// after pasting line does not appear until after window resize."
|
||||
- if (RootInlineBox* prev_root_box = box->PrevRootBox())
|
||||
+ if (RootInlineBox* prev_root_box = box->PrevRootBox()) {
|
||||
prev_root_box->MarkDirty();
|
||||
+#if DCHECK_IS_ON()
|
||||
+ for (; prev_root_box; prev_root_box = prev_root_box->PrevRootBox()) {
|
||||
+ DCHECK(prev_root_box->IsDirty() ||
|
||||
+ prev_root_box->LineBreakObj() != child);
|
||||
+ }
|
||||
+#endif
|
||||
+ }
|
||||
// If |child| or any of its immediately previous siblings with culled
|
||||
// lineboxes is the object after a line-break in |box| or the linebox after
|
||||
// it then that means |child| actually sits on the linebox after |box| (or
|
||||
// is its line-break object) and so we need to dirty it as well.
|
||||
- if (RootInlineBox* next_root_box = box->NextRootBox())
|
||||
+ if (RootInlineBox* next_root_box = box->NextRootBox()) {
|
||||
next_root_box->MarkDirty();
|
||||
+
|
||||
+ next_root_box = next_root_box->NextRootBox();
|
||||
+ if (next_root_box && next_root_box->LineBreakObj() == child)
|
||||
+ next_root_box->MarkDirty();
|
||||
+#if DCHECK_IS_ON()
|
||||
+ for (; next_root_box; next_root_box = next_root_box->NextRootBox()) {
|
||||
+ DCHECK(next_root_box->IsDirty() ||
|
||||
+ next_root_box->LineBreakObj() != child);
|
||||
+ }
|
||||
+#endif
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
67
patches/chromium/cherry-pick-76cb1cc32baa.patch
Normal file
67
patches/chromium/cherry-pick-76cb1cc32baa.patch
Normal file
@@ -0,0 +1,67 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sergei Glazunov <glazunov@google.com>
|
||||
Date: Fri, 12 Feb 2021 16:37:12 +0000
|
||||
Subject: Use a copy for transferring non detachable buffers
|
||||
|
||||
Currently, |DOMArrayBuffer::Transfer()| makes a copy, but still uses
|
||||
the original buffer for transferring, thus making it possible to share a
|
||||
regular ArrayBuffer (not SAB) with multiple threads.
|
||||
|
||||
(cherry picked from commit 0d289da12075592372940a366ad565b9a13d57ce)
|
||||
|
||||
Bug: 1177341
|
||||
Change-Id: Idb48deb1698fe555f32531bc04b55dd3e1fb0a06
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2690630
|
||||
Reviewed-by: Bill Budge <bbudge@chromium.org>
|
||||
Reviewed-by: Andreas Haas <ahaas@chromium.org>
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Commit-Queue: Sergei Glazunov <glazunov@google.com>
|
||||
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#853272}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2691251
|
||||
Reviewed-by: Krishna Govind <govind@chromium.org>
|
||||
Commit-Queue: Krishna Govind <govind@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4389@{#980}
|
||||
Cr-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
|
||||
index 17fcf0f9034d09a53376ebb380c98589d52de8f4..c456d15f2f5084d7592326e151c1a478bc2ac1fc 100644
|
||||
--- a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
|
||||
+++ b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
|
||||
@@ -47,6 +47,13 @@ bool DOMArrayBuffer::Transfer(v8::Isolate* isolate,
|
||||
DOMArrayBuffer::Create(Content()->Data(), ByteLengthAsSizeT());
|
||||
}
|
||||
|
||||
+ return to_transfer->TransferDetachable(isolate, result);
|
||||
+}
|
||||
+
|
||||
+bool DOMArrayBuffer::TransferDetachable(v8::Isolate* isolate,
|
||||
+ ArrayBufferContents& result) {
|
||||
+ DCHECK(IsDetachable(isolate));
|
||||
+
|
||||
if (IsDetached()) {
|
||||
result.Detach();
|
||||
return false;
|
||||
@@ -62,7 +69,7 @@ bool DOMArrayBuffer::Transfer(v8::Isolate* isolate,
|
||||
|
||||
Vector<v8::Local<v8::ArrayBuffer>, 4> buffer_handles;
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
- AccumulateArrayBuffersForAllWorlds(isolate, to_transfer, buffer_handles);
|
||||
+ AccumulateArrayBuffersForAllWorlds(isolate, this, buffer_handles);
|
||||
|
||||
for (const auto& buffer_handle : buffer_handles)
|
||||
buffer_handle->Detach();
|
||||
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h
|
||||
index 00ba385dafcfd476805e39e4c138cdac8f071ef6..e9a85d38d4d46d26a41cf4d394a92d1a7b511c02 100644
|
||||
--- a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h
|
||||
+++ b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h
|
||||
@@ -78,6 +78,9 @@ class CORE_EXPORT DOMArrayBuffer final : public DOMArrayBufferBase {
|
||||
|
||||
v8::Local<v8::Value> Wrap(v8::Isolate*,
|
||||
v8::Local<v8::Object> creation_context) override;
|
||||
+
|
||||
+ private:
|
||||
+ bool TransferDetachable(v8::Isolate*, ArrayBufferContents& result);
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
197
patches/chromium/cherry-pick-79440c3a0675.patch
Normal file
197
patches/chromium/cherry-pick-79440c3a0675.patch
Normal file
@@ -0,0 +1,197 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hongchan Choi <hongchan@chromium.org>
|
||||
Date: Tue, 8 Dec 2020 01:42:34 +0000
|
||||
Subject: Fail gracefully if |parameter| object has an invalid array topology
|
||||
|
||||
AudioWorkletProcessor::CopyParamValueMapToObject() assumed the array
|
||||
topology is always valid (DCHECK), but if the user code actively mangles
|
||||
the parameter descriptor getter the array to return invalid content
|
||||
this assumption becomes invalid.
|
||||
|
||||
The fix is to fail gracefully when the object type or the array content
|
||||
is not correct.
|
||||
|
||||
Bug: 1151069
|
||||
Test: The repro case does not reproduce any more after 1 hour run.
|
||||
Change-Id: I3f8decd3721e9b00ba201e2f76751e4bc941e05d
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2569788
|
||||
Reviewed-by: Raymond Toy <rtoy@chromium.org>
|
||||
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#834503}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
|
||||
index 9ac9bcc91967e2228516e6cdc7065b83316c25e7..3518f24ea248862ea9d96ab8e6bbfecfe001fb33 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
|
||||
@@ -107,8 +107,13 @@ bool AudioWorkletProcessor::Process(
|
||||
DCHECK(!params_.IsEmpty());
|
||||
DCHECK(params_.NewLocal(isolate)->IsObject());
|
||||
|
||||
- // Copies |param_value_map| to the internal |params_| object;
|
||||
- CopyParamValueMapToObject(isolate, context, *param_value_map, params_);
|
||||
+ // Copies |param_value_map| to the internal |params_| object. This operation
|
||||
+ // could fail if the getter of parameterDescriptors is overridden by user code
|
||||
+ // and returns incompatible data. (crbug.com/1151069)
|
||||
+ if (!CopyParamValueMapToObject(isolate, context, *param_value_map, params_)) {
|
||||
+ SetErrorState(AudioWorkletProcessorErrorState::kProcessError);
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
// Performs the user-defined AudioWorkletProcessor.process() function.
|
||||
v8::TryCatch try_catch(isolate);
|
||||
@@ -444,6 +449,7 @@ bool AudioWorkletProcessor::CloneParamValueMapToObject(
|
||||
break;
|
||||
}
|
||||
}
|
||||
+ DCHECK(array_size == 1 || array_size == param_float_array->size());
|
||||
|
||||
v8::Local<v8::ArrayBuffer> array_buffer =
|
||||
v8::ArrayBuffer::New(isolate, array_size * sizeof(float));
|
||||
@@ -482,18 +488,23 @@ bool AudioWorkletProcessor::CopyParamValueMapToObject(
|
||||
|
||||
v8::Local<v8::Value> param_array_value;
|
||||
if (!params_object->Get(context, V8String(isolate, param_name))
|
||||
- .ToLocal(¶m_array_value)) {
|
||||
+ .ToLocal(¶m_array_value) ||
|
||||
+ !param_array_value->IsFloat32Array()) {
|
||||
return false;
|
||||
}
|
||||
- DCHECK(param_array_value->IsFloat32Array());
|
||||
+
|
||||
v8::Local<v8::Float32Array> float32_array =
|
||||
param_array_value.As<v8::Float32Array>();
|
||||
+ size_t array_length = float32_array->Length();
|
||||
+
|
||||
+ // The |float32_array| is neither 1 nor 128 frames, or the array buffer is
|
||||
+ // trasnferred/detached, do not proceed.
|
||||
+ if ((array_length != 1 && array_length != param_array->size()) ||
|
||||
+ float32_array->Buffer()->ByteLength() == 0)
|
||||
+ return false;
|
||||
|
||||
- // The Float32Array is either 1 or 128 frames, but it always should be
|
||||
- // less than equal to the size of the given AudioFloatArray.
|
||||
- DCHECK_LE(float32_array->Length(), param_array->size());
|
||||
memcpy(float32_array->Buffer()->GetContents().Data(), param_array->Data(),
|
||||
- float32_array->Length() * sizeof(float));
|
||||
+ array_length * sizeof(float));
|
||||
}
|
||||
|
||||
return true;
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-param-getter-overridden.https.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-param-getter-overridden.https.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e3fb6e533df8ccaa88564f836239e0c9e9c1d5e4
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-param-getter-overridden.https.html
|
||||
@@ -0,0 +1,59 @@
|
||||
+<!DOCTYPE html>
|
||||
+<html>
|
||||
+ <head>
|
||||
+ <title>
|
||||
+ Test if AudioWorkletProcessor with invalid parameters array getter
|
||||
+ </title>
|
||||
+ <script src="/resources/testharness.js"></script>
|
||||
+ <script src="/resources/testharnessreport.js"></script>
|
||||
+ <script src="/webaudio/resources/audit.js"></script>
|
||||
+ </head>
|
||||
+ <body>
|
||||
+ <script id="layout-test-code">
|
||||
+ let audit = Audit.createTaskRunner();
|
||||
+
|
||||
+ // Arbitrarily determined. Any numbers should work.
|
||||
+ let sampleRate = 16000;
|
||||
+ let renderLength = 1280;
|
||||
+ let context;
|
||||
+ let filePath = 'processors/invalid-param-array-processor.js';
|
||||
+
|
||||
+ audit.define('Initializing AudioWorklet and Context', async (task) => {
|
||||
+ context = new OfflineAudioContext(1, renderLength, sampleRate);
|
||||
+ await context.audioWorklet.addModule(filePath);
|
||||
+ task.done();
|
||||
+ });
|
||||
+
|
||||
+ audit.define('Verifying AudioParam in AudioWorkletNode',
|
||||
+ async (task, should) => {
|
||||
+ let buffer = context.createBuffer(1, 2, context.sampleRate);
|
||||
+ buffer.getChannelData(0)[0] = 1;
|
||||
+
|
||||
+ let source = new AudioBufferSourceNode(context);
|
||||
+ source.buffer = buffer;
|
||||
+ source.loop = true;
|
||||
+ source.start();
|
||||
+
|
||||
+ let workletNode1 =
|
||||
+ new AudioWorkletNode(context, 'invalid-param-array-1');
|
||||
+ let workletNode2 =
|
||||
+ new AudioWorkletNode(context, 'invalid-param-array-2');
|
||||
+ workletNode1.connect(workletNode2).connect(context.destination);
|
||||
+
|
||||
+ // Manually invoke the param getter.
|
||||
+ source.connect(workletNode2.parameters.get('invalidParam'));
|
||||
+
|
||||
+ const renderedBuffer = await context.startRendering();
|
||||
+
|
||||
+ // |workletNode2| should be no-op after the parameter getter is
|
||||
+ // invoked. Therefore, the rendered result should be silent.
|
||||
+ should(renderedBuffer.getChannelData(0), 'The rendered buffer')
|
||||
+ .beConstantValueOf(0);
|
||||
+ task.done();
|
||||
+ }
|
||||
+ );
|
||||
+
|
||||
+ audit.run();
|
||||
+ </script>
|
||||
+ </body>
|
||||
+</html>
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/invalid-param-array-processor.js b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/invalid-param-array-processor.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e4a5dc39ba16b282e254eba84e8038ae59a6471d
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/invalid-param-array-processor.js
|
||||
@@ -0,0 +1,47 @@
|
||||
+/**
|
||||
+ * @class InvalidParamArrayProcessor
|
||||
+ * @extends AudioWorkletProcessor
|
||||
+ *
|
||||
+ * This processor intentionally returns an array with an invalid size when the
|
||||
+ * processor's getter is queried.
|
||||
+ */
|
||||
+let singleton = undefined;
|
||||
+let secondFetch = false;
|
||||
+let useDescriptor = false;
|
||||
+let processCounter = 0;
|
||||
+
|
||||
+class InvalidParamArrayProcessor extends AudioWorkletProcessor {
|
||||
+ static get parameterDescriptors() {
|
||||
+ if (useDescriptor)
|
||||
+ return [{name: 'invalidParam'}];
|
||||
+ useDescriptor = true;
|
||||
+ return [];
|
||||
+ }
|
||||
+
|
||||
+ constructor() {
|
||||
+ super();
|
||||
+ if (singleton === undefined)
|
||||
+ singleton = this;
|
||||
+ return singleton;
|
||||
+ }
|
||||
+
|
||||
+ process(inputs, outputs, parameters) {
|
||||
+ const output = outputs[0];
|
||||
+ for (let channel = 0; channel < output.length; ++channel)
|
||||
+ output[channel].fill(1);
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+// This overridden getter is invoked under the hood before process() gets
|
||||
+// called. After this gets called, process() method above will be invalidated,
|
||||
+// and mark the worklet node non-functional. (i.e. in an error state)
|
||||
+Object.defineProperty(Object.prototype, 'invalidParam', {'get': () => {
|
||||
+ if (secondFetch)
|
||||
+ return new Float32Array(256);
|
||||
+ secondFetch = true;
|
||||
+ return new Float32Array(128);
|
||||
+}});
|
||||
+
|
||||
+registerProcessor('invalid-param-array-1', InvalidParamArrayProcessor);
|
||||
+registerProcessor('invalid-param-array-2', InvalidParamArrayProcessor);
|
||||
54
patches/chromium/cherry-pick-7e0e52df283c.patch
Normal file
54
patches/chromium/cherry-pick-7e0e52df283c.patch
Normal file
@@ -0,0 +1,54 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Date: Tue, 23 Feb 2021 22:17:17 +0000
|
||||
Subject: Don't store BlobStorageLimits as a reference in transport strategy.
|
||||
|
||||
Rather than storing a const reference to something of unclear lifetime,
|
||||
just make a copy. We could just copy the specific limits we need, but
|
||||
there shouldn't be many TransportStrategy instances alive at the same
|
||||
time anyway, so the cost of duplicating shouldn't be too high.
|
||||
|
||||
(cherry picked from commit 9a10c68a381d78088532953aa8e0de0a5ff47316)
|
||||
|
||||
(cherry picked from commit 7b51cb5e4e2c6cf9dcf19bd9d7599735efd48110)
|
||||
|
||||
Bug: 1180871
|
||||
Change-Id: Ie1e31728b18f02c5d35df0ac0f285eb8f70cb268
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2713912
|
||||
Reviewed-by: Olivier Yiptong <oyiptong@chromium.org>
|
||||
Reviewed-by: Darwin Huang <huangdarwin@chromium.org>
|
||||
Reviewed-by: Victor Costan <pwnall@chromium.org>
|
||||
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#856503}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2713891
|
||||
Reviewed-by: Krishna Govind <govind@chromium.org>
|
||||
Reviewed-by: Srinivas Sista <srinivassista@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4425@{#2}
|
||||
Cr-Original-Branched-From: 4a7d24ec28ccb96c5a1cfd7b4b40b17070f2c396-refs/heads/master@{#856252}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2713958
|
||||
Commit-Queue: Krishna Govind <govind@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4389@{#1327}
|
||||
Cr-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
|
||||
diff --git a/storage/browser/blob/blob_transport_strategy.cc b/storage/browser/blob/blob_transport_strategy.cc
|
||||
index eb66014792246254db1c825b61bd18e3190970de..5ae41639f149f8ff3ead9633d3aa834ac05a8e5f 100644
|
||||
--- a/storage/browser/blob/blob_transport_strategy.cc
|
||||
+++ b/storage/browser/blob/blob_transport_strategy.cc
|
||||
@@ -239,7 +239,7 @@ class DataPipeTransportStrategy : public BlobTransportStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
- const BlobStorageLimits& limits_;
|
||||
+ const BlobStorageLimits limits_;
|
||||
base::circular_deque<base::OnceClosure> requests_;
|
||||
|
||||
mojo::ScopedDataPipeConsumerHandle consumer_handle_;
|
||||
@@ -336,7 +336,7 @@ class FileTransportStrategy : public BlobTransportStrategy {
|
||||
std::move(result_callback_).Run(BlobStatus::DONE);
|
||||
}
|
||||
|
||||
- const BlobStorageLimits& limits_;
|
||||
+ const BlobStorageLimits limits_;
|
||||
|
||||
// State used to assign bytes elements to individual files.
|
||||
// The index of the first file that still has available space.
|
||||
78
patches/chromium/cherry-pick-861253f1de98.patch
Normal file
78
patches/chromium/cherry-pick-861253f1de98.patch
Normal file
@@ -0,0 +1,78 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Rice <ricea@chromium.org>
|
||||
Date: Sat, 5 Dec 2020 03:19:09 +0000
|
||||
Subject: Update the restricted port list
|
||||
|
||||
Add ports 69, 137, 161, 554, 1719, 1720, 1723, 6566 to the restricted
|
||||
ports list to match Firefox. See
|
||||
https://hg.mozilla.org/mozilla-central/file/tip/netwerk/base/nsIOService.cpp.
|
||||
|
||||
Leave out port 10080 for now as it seems likely to cause compatibility
|
||||
problems.
|
||||
|
||||
BUG=1148309
|
||||
|
||||
Change-Id: I16f9a61068dbe35334fd5ca2bf55b3ab0287df74
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2562905
|
||||
Reviewed-by: David Schinazi <dschinazi@chromium.org>
|
||||
Commit-Queue: Adam Rice <ricea@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#832169}
|
||||
(cherry picked from commit c36c5078c41bd1a9e2455d747d69ac1703d977d3)
|
||||
|
||||
TBR=ricea@chromium.org
|
||||
|
||||
Change-Id: I9cc989e46ac63b3c656eb2eaed825add9b8346f8
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2574877
|
||||
Reviewed-by: Adam Rice <ricea@chromium.org>
|
||||
Commit-Queue: Adam Rice <ricea@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4324@{#611}
|
||||
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
|
||||
diff --git a/net/base/port_util.cc b/net/base/port_util.cc
|
||||
index 72af86dd6acf2db65a14b2f1bb2e3a241a1d043d..12bfd9a36a0e8e9331420c597faf670477100e47 100644
|
||||
--- a/net/base/port_util.cc
|
||||
+++ b/net/base/port_util.cc
|
||||
@@ -37,6 +37,7 @@ const int kRestrictedPorts[] = {
|
||||
42, // name
|
||||
43, // nicname
|
||||
53, // domain
|
||||
+ 69, // tftp
|
||||
77, // priv-rjs
|
||||
79, // finger
|
||||
87, // ttylink
|
||||
@@ -54,8 +55,10 @@ const int kRestrictedPorts[] = {
|
||||
119, // nntp
|
||||
123, // NTP
|
||||
135, // loc-srv /epmap
|
||||
+ 137, // netbios
|
||||
139, // netbios
|
||||
143, // imap2
|
||||
+ 161, // snmp
|
||||
179, // BGP
|
||||
389, // ldap
|
||||
427, // SLP (Also used by Apple Filing Protocol)
|
||||
@@ -70,6 +73,7 @@ const int kRestrictedPorts[] = {
|
||||
532, // netnews
|
||||
540, // uucp
|
||||
548, // AFP (Apple Filing Protocol)
|
||||
+ 554, // rtsp
|
||||
556, // remotefs
|
||||
563, // nntp+ssl
|
||||
587, // smtp (rfc6409)
|
||||
@@ -77,12 +81,16 @@ const int kRestrictedPorts[] = {
|
||||
636, // ldap+ssl
|
||||
993, // ldap+ssl
|
||||
995, // pop3+ssl
|
||||
+ 1719, // h323gatestat
|
||||
+ 1720, // h323hostcall
|
||||
+ 1723, // pptp
|
||||
2049, // nfs
|
||||
3659, // apple-sasl / PasswordServer
|
||||
4045, // lockd
|
||||
5060, // sip
|
||||
5061, // sips
|
||||
6000, // X11
|
||||
+ 6566, // sane-port
|
||||
6665, // Alternate IRC [Apple addition]
|
||||
6666, // Alternate IRC [Apple addition]
|
||||
6667, // Standard IRC [Apple addition]
|
||||
143
patches/chromium/cherry-pick-8c3eb9d1c409.patch
Normal file
143
patches/chromium/cherry-pick-8c3eb9d1c409.patch
Normal file
@@ -0,0 +1,143 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Scott Violet <sky@chromium.org>
|
||||
Date: Wed, 31 Mar 2021 13:28:05 +0000
|
||||
Subject: x11/ozone: fix two edge cases
|
||||
|
||||
WindowTreeHost::OnHostMovedInPixels() may trigger a nested message
|
||||
loop (tab dragging), which when the stack unravels means this may
|
||||
be deleted. This adds an early out if this happens.
|
||||
|
||||
X11WholeScreenMoveLoop has a similar issue, in so far as notifying
|
||||
the delegate may delete this.
|
||||
|
||||
BUG=1185482
|
||||
TEST=WindowTreeHostPlatform.DeleteHostFromOnHostMovedInPixels
|
||||
|
||||
(cherry picked from commit 5e3a738b1204941aab9f15c0eb3d06e20fefd96e)
|
||||
|
||||
(cherry picked from commit 8ad84a8e7882275fb32f938fd0adc04d1a2a5773)
|
||||
|
||||
Change-Id: Ieca1c90b3e4358da50b332abe2941fdbb50c5c25
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2743555
|
||||
Reviewed-by: Thomas Anderson <thomasanderson@chromium.org>
|
||||
Commit-Queue: Scott Violet <sky@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#860852}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2779886
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4389@{#1583}
|
||||
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2794391
|
||||
Reviewed-by: Scott Violet <sky@chromium.org>
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1583}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/ui/aura/window_tree_host_platform.cc b/ui/aura/window_tree_host_platform.cc
|
||||
index 917b45bf3f8554c63886af30b1483cd97670299c..c9053e7c7e7abb1cdbaf114028579a0484b1d4a9 100644
|
||||
--- a/ui/aura/window_tree_host_platform.cc
|
||||
+++ b/ui/aura/window_tree_host_platform.cc
|
||||
@@ -214,13 +214,21 @@ void WindowTreeHostPlatform::OnBoundsChanged(const gfx::Rect& new_bounds) {
|
||||
float current_scale = compositor()->device_scale_factor();
|
||||
float new_scale = ui::GetScaleFactorForNativeView(window());
|
||||
gfx::Rect old_bounds = bounds_in_pixels_;
|
||||
+ auto weak_ref = GetWeakPtr();
|
||||
bounds_in_pixels_ = new_bounds;
|
||||
- if (bounds_in_pixels_.origin() != old_bounds.origin())
|
||||
+ if (bounds_in_pixels_.origin() != old_bounds.origin()) {
|
||||
OnHostMovedInPixels(bounds_in_pixels_.origin());
|
||||
+ // Changing the bounds may destroy this.
|
||||
+ if (!weak_ref)
|
||||
+ return;
|
||||
+ }
|
||||
if (bounds_in_pixels_.size() != old_bounds.size() ||
|
||||
current_scale != new_scale) {
|
||||
pending_size_ = gfx::Size();
|
||||
OnHostResizedInPixels(bounds_in_pixels_.size());
|
||||
+ // Changing the size may destroy this.
|
||||
+ if (!weak_ref)
|
||||
+ return;
|
||||
}
|
||||
DCHECK_GT(on_bounds_changed_recursion_depth_, 0);
|
||||
if (--on_bounds_changed_recursion_depth_ == 0) {
|
||||
diff --git a/ui/aura/window_tree_host_platform_unittest.cc b/ui/aura/window_tree_host_platform_unittest.cc
|
||||
index eda14e2f0cdf5015f366aa70ea68ae2a2c2b431e..4de039c88af8a6f0ac03df2f772cfea2dfe3514f 100644
|
||||
--- a/ui/aura/window_tree_host_platform_unittest.cc
|
||||
+++ b/ui/aura/window_tree_host_platform_unittest.cc
|
||||
@@ -34,7 +34,7 @@ class TestWindowTreeHost : public WindowTreeHostPlatform {
|
||||
// OnHostWill/DidProcessBoundsChange. Additionally, this triggers a bounds
|
||||
// change from within OnHostResized(). Such a scenario happens in production
|
||||
// code.
|
||||
-class TestWindowTreeHostObserver : public aura::WindowTreeHostObserver {
|
||||
+class TestWindowTreeHostObserver : public WindowTreeHostObserver {
|
||||
public:
|
||||
TestWindowTreeHostObserver(WindowTreeHostPlatform* host,
|
||||
ui::PlatformWindow* platform_window)
|
||||
@@ -51,7 +51,7 @@ class TestWindowTreeHostObserver : public aura::WindowTreeHostObserver {
|
||||
return on_host_will_process_bounds_change_count_;
|
||||
}
|
||||
|
||||
- // aura::WindowTreeHostObserver:
|
||||
+ // WindowTreeHostObserver:
|
||||
void OnHostResized(WindowTreeHost* host) override {
|
||||
if (!should_change_bounds_in_on_resized_)
|
||||
return;
|
||||
@@ -92,5 +92,41 @@ TEST_F(WindowTreeHostPlatformTest, HostWillProcessBoundsChangeRecursion) {
|
||||
EXPECT_EQ(1, observer.on_host_will_process_bounds_change_count());
|
||||
}
|
||||
|
||||
+// Deletes WindowTreeHostPlatform from OnHostMovedInPixels().
|
||||
+class DeleteHostWindowTreeHostObserver : public WindowTreeHostObserver {
|
||||
+ public:
|
||||
+ explicit DeleteHostWindowTreeHostObserver(
|
||||
+ std::unique_ptr<TestWindowTreeHost> host)
|
||||
+ : host_(std::move(host)) {
|
||||
+ host_->AddObserver(this);
|
||||
+ }
|
||||
+ ~DeleteHostWindowTreeHostObserver() override = default;
|
||||
+
|
||||
+ TestWindowTreeHost* host() { return host_.get(); }
|
||||
+
|
||||
+ // WindowTreeHostObserver:
|
||||
+ void OnHostMovedInPixels(WindowTreeHost* host,
|
||||
+ const gfx::Point& new_origin_in_pixels) override {
|
||||
+ host_->RemoveObserver(this);
|
||||
+ host_.reset();
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ std::unique_ptr<TestWindowTreeHost> host_;
|
||||
+
|
||||
+ DISALLOW_COPY_AND_ASSIGN(DeleteHostWindowTreeHostObserver);
|
||||
+};
|
||||
+
|
||||
+// Verifies WindowTreeHostPlatform can be safely deleted when calling
|
||||
+// OnHostMovedInPixels().
|
||||
+// Regression test for https://crbug.com/1185482
|
||||
+TEST_F(WindowTreeHostPlatformTest, DeleteHostFromOnHostMovedInPixels) {
|
||||
+ std::unique_ptr<TestWindowTreeHost> host =
|
||||
+ std::make_unique<TestWindowTreeHost>();
|
||||
+ DeleteHostWindowTreeHostObserver observer(std::move(host));
|
||||
+ observer.host()->SetBoundsInPixels(gfx::Rect(1, 2, 3, 4));
|
||||
+ EXPECT_EQ(nullptr, observer.host());
|
||||
+}
|
||||
+
|
||||
} // namespace
|
||||
} // namespace aura
|
||||
diff --git a/ui/base/x/x11_whole_screen_move_loop.cc b/ui/base/x/x11_whole_screen_move_loop.cc
|
||||
index 39f4d0c12aa1feb1702c3f4aa4ba0f62be591197..2bbb1f035b0db8de218ce629cc16aab91cf8519b 100644
|
||||
--- a/ui/base/x/x11_whole_screen_move_loop.cc
|
||||
+++ b/ui/base/x/x11_whole_screen_move_loop.cc
|
||||
@@ -62,9 +62,13 @@ X11WholeScreenMoveLoop::~X11WholeScreenMoveLoop() = default;
|
||||
void X11WholeScreenMoveLoop::DispatchMouseMovement() {
|
||||
if (!last_motion_in_screen_)
|
||||
return;
|
||||
+ auto weak_ref = weak_factory_.GetWeakPtr();
|
||||
delegate_->OnMouseMovement(last_motion_in_screen_->root_location(),
|
||||
last_motion_in_screen_->flags(),
|
||||
last_motion_in_screen_->time_stamp());
|
||||
+ // The delegate may delete this during dispatch.
|
||||
+ if (!weak_ref)
|
||||
+ return;
|
||||
last_motion_in_screen_.reset();
|
||||
}
|
||||
|
||||
110
patches/chromium/cherry-pick-9afec1792cfc.patch
Normal file
110
patches/chromium/cherry-pick-9afec1792cfc.patch
Normal file
@@ -0,0 +1,110 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xiaocheng Hu <xiaochengh@chromium.org>
|
||||
Date: Wed, 3 Feb 2021 14:56:15 +0000
|
||||
Subject: Move FontPreloadManager to Oilpan
|
||||
|
||||
Currently, TimerBase cannot correctly track the lifetime of objects
|
||||
embedded in GC-ed objects, like FontPreloadManager which is embedded in
|
||||
Document. This causes some memory safety issues.
|
||||
|
||||
This patch moves FontPreloadManager to Oilpan to avoid the issue.
|
||||
|
||||
(cherry picked from commit d31bbf2910ee44e4a206d926ddae6827d16a2754)
|
||||
|
||||
(cherry picked from commit cdab130053839ffae4a02d00812c1c3a0ecf01bd)
|
||||
|
||||
Bug: 1154965
|
||||
Change-Id: I490b416abc6a997034baaa7994cd3a50bca7e055
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2611755
|
||||
Reviewed-by: Kentaro Hara <haraken@chromium.org>
|
||||
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#841039}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2653946
|
||||
Commit-Queue: Kentaro Hara <haraken@chromium.org>
|
||||
Auto-Submit: Xiaocheng Hu <xiaochengh@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4324@{#2045}
|
||||
Cr-Original-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2665939
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1536}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
|
||||
index 2fea6ad5cb19e42dbb51a6432ce119b935c23d8f..f84f12cfa8ea70051bcdc82e723816d4ae266b5d 100644
|
||||
--- a/third_party/blink/renderer/core/dom/document.cc
|
||||
+++ b/third_party/blink/renderer/core/dom/document.cc
|
||||
@@ -791,7 +791,7 @@ Document::Document(const DocumentInit& initializer,
|
||||
MakeGarbageCollected<DisplayLockDocumentState>(this)),
|
||||
permission_service_(GetExecutionContext()),
|
||||
has_trust_tokens_answerer_(GetExecutionContext()),
|
||||
- font_preload_manager_(*this) {
|
||||
+ font_preload_manager_(MakeGarbageCollected<FontPreloadManager>(*this)) {
|
||||
GetOriginTrialContext()->BindExecutionContext(GetExecutionContext());
|
||||
|
||||
if (dom_window_) {
|
||||
@@ -6892,7 +6892,7 @@ void Document::BeginLifecycleUpdatesIfRenderingReady() {
|
||||
return;
|
||||
if (!HaveRenderBlockingResourcesLoaded())
|
||||
return;
|
||||
- font_preload_manager_.WillBeginRendering();
|
||||
+ font_preload_manager_->WillBeginRendering();
|
||||
View()->BeginLifecycleUpdates();
|
||||
}
|
||||
|
||||
@@ -7660,7 +7660,7 @@ bool Document::HaveScriptBlockingStylesheetsLoaded() const {
|
||||
bool Document::HaveRenderBlockingResourcesLoaded() const {
|
||||
return HaveImportsLoaded() &&
|
||||
style_engine_->HaveRenderBlockingStylesheetsLoaded() &&
|
||||
- !font_preload_manager_.HasPendingRenderBlockingFonts();
|
||||
+ !font_preload_manager_->HasPendingRenderBlockingFonts();
|
||||
}
|
||||
|
||||
Locale& Document::GetCachedLocale(const AtomicString& locale) {
|
||||
@@ -8503,7 +8503,7 @@ void Document::ClearUseCounterForTesting(mojom::WebFeature feature) {
|
||||
}
|
||||
|
||||
void Document::FontPreloadingFinishedOrTimedOut() {
|
||||
- DCHECK(!font_preload_manager_.HasPendingRenderBlockingFonts());
|
||||
+ DCHECK(!font_preload_manager_->HasPendingRenderBlockingFonts());
|
||||
if (IsA<HTMLDocument>(this) && body()) {
|
||||
// For HTML, we resume only when we're past the body tag, so that we should
|
||||
// have something to paint now.
|
||||
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
|
||||
index b197ad6e06c6ba1b609607a78aa798f1cc397a3e..b092be4c8bd55567c14d81c9bee343da432747a0 100644
|
||||
--- a/third_party/blink/renderer/core/dom/document.h
|
||||
+++ b/third_party/blink/renderer/core/dom/document.h
|
||||
@@ -1647,7 +1647,7 @@ class CORE_EXPORT Document : public ContainerNode,
|
||||
unsigned new_length);
|
||||
void NotifyChangeChildren(const ContainerNode& container);
|
||||
|
||||
- FontPreloadManager& GetFontPreloadManager() { return font_preload_manager_; }
|
||||
+ FontPreloadManager& GetFontPreloadManager() { return *font_preload_manager_; }
|
||||
void FontPreloadingFinishedOrTimedOut();
|
||||
|
||||
void IncrementAsyncScriptCount() { async_script_count_++; }
|
||||
@@ -2230,7 +2230,7 @@ class CORE_EXPORT Document : public ContainerNode,
|
||||
HeapHashSet<Member<ScriptPromiseResolver>>
|
||||
pending_has_trust_tokens_resolvers_;
|
||||
|
||||
- FontPreloadManager font_preload_manager_;
|
||||
+ Member<FontPreloadManager> font_preload_manager_;
|
||||
|
||||
int async_script_count_ = 0;
|
||||
bool first_paint_recorded_ = false;
|
||||
diff --git a/third_party/blink/renderer/core/loader/font_preload_manager.h b/third_party/blink/renderer/core/loader/font_preload_manager.h
|
||||
index 3e98fc931a205b7e20b119e7af5a5bbac1eee2b5..631f0f95e7e70d3e1bf73c78f725fdf756a721eb 100644
|
||||
--- a/third_party/blink/renderer/core/loader/font_preload_manager.h
|
||||
+++ b/third_party/blink/renderer/core/loader/font_preload_manager.h
|
||||
@@ -20,9 +20,8 @@ class ResourceFinishObserver;
|
||||
// API) and notifies the relevant document, so that it can manage the first
|
||||
// rendering timing to work with preloaded fonts.
|
||||
// Design doc: https://bit.ly/36E8UKB
|
||||
-class CORE_EXPORT FontPreloadManager final {
|
||||
- DISALLOW_NEW();
|
||||
-
|
||||
+class CORE_EXPORT FontPreloadManager final
|
||||
+ : public GarbageCollected<FontPreloadManager> {
|
||||
public:
|
||||
explicit FontPreloadManager(Document&);
|
||||
~FontPreloadManager() = default;
|
||||
195
patches/chromium/cherry-pick-9ec949913373.patch
Normal file
195
patches/chromium/cherry-pick-9ec949913373.patch
Normal file
@@ -0,0 +1,195 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Rockot <rockot@google.com>
|
||||
Date: Tue, 12 Jan 2021 18:36:22 +0000
|
||||
Subject: Mojo: Fix UAF on NodeChannel
|
||||
|
||||
TBR=rockot@google.com
|
||||
|
||||
(cherry picked from commit 9c8a98b3983dd1c7828ceae2fc8a5a2e9bad1f68)
|
||||
|
||||
(cherry picked from commit 06fe641d21bda1b5869a46e59b13873762ce1324)
|
||||
|
||||
Fixed: 1162198
|
||||
Change-Id: Ief850903a7e6ba3d7c5c0129704d1f80aa3467ce
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2612085
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Reviewed-by: Ken Rockot <rockot@google.com>
|
||||
Reviewed-by: Robert Sesek <rsesek@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#840942}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2621996
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4324@{#1637}
|
||||
Cr-Original-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2623929
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1517}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/mojo/core/BUILD.gn b/mojo/core/BUILD.gn
|
||||
index c42daf24d62b3a1c8479466d1bc4efe753099136..a7f574455ac02b656a451257cdc11a2968dd5b68 100644
|
||||
--- a/mojo/core/BUILD.gn
|
||||
+++ b/mojo/core/BUILD.gn
|
||||
@@ -309,6 +309,7 @@ source_set("test_sources") {
|
||||
"data_pipe_unittest.cc",
|
||||
"invitation_unittest.cc",
|
||||
"multiprocess_message_pipe_unittest.cc",
|
||||
+ "node_controller_unittest.cc",
|
||||
"platform_wrapper_unittest.cc",
|
||||
]
|
||||
}
|
||||
diff --git a/mojo/core/core.cc b/mojo/core/core.cc
|
||||
index 6d06ab1fdee75c8fc8670ff7a35923aa90c4bf8c..5eed4e1be13df656897c60378dde8ec024e81a59 100644
|
||||
--- a/mojo/core/core.cc
|
||||
+++ b/mojo/core/core.cc
|
||||
@@ -137,7 +137,7 @@ void Core::SetIOTaskRunner(
|
||||
NodeController* Core::GetNodeController() {
|
||||
base::AutoLock lock(node_controller_lock_);
|
||||
if (!node_controller_)
|
||||
- node_controller_.reset(new NodeController(this));
|
||||
+ node_controller_ = std::make_unique<NodeController>();
|
||||
return node_controller_.get();
|
||||
}
|
||||
|
||||
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc
|
||||
index ff93f0c3a6b2bf4a340e027ee803b9006152f031..c7646fa4dc5c5062e8a8a620e55839301af51bed 100644
|
||||
--- a/mojo/core/node_controller.cc
|
||||
+++ b/mojo/core/node_controller.cc
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "mojo/core/broker.h"
|
||||
#include "mojo/core/broker_host.h"
|
||||
#include "mojo/core/configuration.h"
|
||||
-#include "mojo/core/core.h"
|
||||
#include "mojo/core/request_context.h"
|
||||
#include "mojo/core/user_message_impl.h"
|
||||
#include "mojo/public/cpp/platform/named_platform_channel.h"
|
||||
@@ -146,10 +145,8 @@ class ThreadDestructionObserver
|
||||
|
||||
NodeController::~NodeController() = default;
|
||||
|
||||
-NodeController::NodeController(Core* core)
|
||||
- : core_(core),
|
||||
- name_(GetRandomNodeName()),
|
||||
- node_(new ports::Node(name_, this)) {
|
||||
+NodeController::NodeController()
|
||||
+ : name_(GetRandomNodeName()), node_(new ports::Node(name_, this)) {
|
||||
DVLOG(1) << "Initializing node " << name_;
|
||||
}
|
||||
|
||||
@@ -587,10 +584,17 @@ void NodeController::AddPeer(const ports::NodeName& name,
|
||||
}
|
||||
}
|
||||
|
||||
-void NodeController::DropPeer(const ports::NodeName& name,
|
||||
+void NodeController::DropPeer(const ports::NodeName& node_name,
|
||||
NodeChannel* channel) {
|
||||
DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
|
||||
|
||||
+ // NOTE: Either the `peers_` erasure or the `pending_invitations_` erasure
|
||||
+ // below, if executed, may drop the last reference to the named NodeChannel
|
||||
+ // and thus result in its deletion. The passed `node_name` argument may be
|
||||
+ // owned by that same NodeChannel, so we make a copy of it here to avoid
|
||||
+ // potentially unsafe references further below.
|
||||
+ ports::NodeName name = node_name;
|
||||
+
|
||||
{
|
||||
base::AutoLock lock(peers_lock_);
|
||||
auto it = peers_.find(name);
|
||||
diff --git a/mojo/core/node_controller.h b/mojo/core/node_controller.h
|
||||
index 9494de5b809e0216fde750960cd5f86c2f14b46e..6f9f0680062db679587ab1846c768846f0fbcb13 100644
|
||||
--- a/mojo/core/node_controller.h
|
||||
+++ b/mojo/core/node_controller.h
|
||||
@@ -52,11 +52,10 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
|
||||
};
|
||||
|
||||
// |core| owns and out-lives us.
|
||||
- explicit NodeController(Core* core);
|
||||
+ NodeController();
|
||||
~NodeController() override;
|
||||
|
||||
const ports::NodeName& name() const { return name_; }
|
||||
- Core* core() const { return core_; }
|
||||
ports::Node* node() const { return node_.get(); }
|
||||
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner() const {
|
||||
return io_task_runner_;
|
||||
@@ -135,6 +134,8 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
|
||||
base::span<const unsigned char> data);
|
||||
static void DeserializeMessageAsEventForFuzzer(Channel::MessagePtr message);
|
||||
|
||||
+ scoped_refptr<NodeChannel> GetBrokerChannel();
|
||||
+
|
||||
private:
|
||||
friend Core;
|
||||
|
||||
@@ -176,7 +177,6 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
|
||||
|
||||
scoped_refptr<NodeChannel> GetPeerChannel(const ports::NodeName& name);
|
||||
scoped_refptr<NodeChannel> GetInviterChannel();
|
||||
- scoped_refptr<NodeChannel> GetBrokerChannel();
|
||||
|
||||
void AddPeer(const ports::NodeName& name,
|
||||
scoped_refptr<NodeChannel> channel,
|
||||
@@ -254,7 +254,6 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
|
||||
void ForceDisconnectProcessForTestingOnIOThread(base::ProcessId process_id);
|
||||
|
||||
// These are safe to access from any thread as long as the Node is alive.
|
||||
- Core* const core_;
|
||||
const ports::NodeName name_;
|
||||
const std::unique_ptr<ports::Node> node_;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
|
||||
@@ -319,7 +318,7 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
|
||||
AtomicFlag shutdown_callback_flag_;
|
||||
|
||||
// All other fields below must only be accessed on the I/O thread, i.e., the
|
||||
- // thread on which core_->io_task_runner() runs tasks.
|
||||
+ // thread on which `io_task_runner_` runs tasks.
|
||||
|
||||
// Channels to invitees during handshake.
|
||||
NodeMap pending_invitations_;
|
||||
diff --git a/mojo/core/node_controller_unittest.cc b/mojo/core/node_controller_unittest.cc
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..316e162376323f27f83868d6b943c40e395511bb
|
||||
--- /dev/null
|
||||
+++ b/mojo/core/node_controller_unittest.cc
|
||||
@@ -0,0 +1,42 @@
|
||||
+// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+#include "base/logging.h"
|
||||
+#include "mojo/core/core.h"
|
||||
+#include "mojo/core/test/mojo_test_base.h"
|
||||
+#include "mojo/public/c/system/types.h"
|
||||
+#include "testing/gtest/include/gtest/gtest.h"
|
||||
+
|
||||
+namespace mojo {
|
||||
+namespace core {
|
||||
+namespace {
|
||||
+
|
||||
+using NodeControllerTest = test::MojoTestBase;
|
||||
+
|
||||
+TEST_F(NodeControllerTest, AcceptInvitationFailure) {
|
||||
+ // Spawn a child process that will send an invalid AcceptInvitation
|
||||
+ // NodeChannel message. This is a regression test for
|
||||
+ // https://crbug.com/1162198.
|
||||
+ RunTestClient("SendInvalidAcceptInvitation",
|
||||
+ [&](MojoHandle h) { WriteMessage(h, "hi"); });
|
||||
+}
|
||||
+
|
||||
+DEFINE_TEST_CLIENT_TEST_WITH_PIPE(SendInvalidAcceptInvitation,
|
||||
+ NodeControllerTest,
|
||||
+ h) {
|
||||
+ // A little communication to synchronize against Mojo bringup. By the time
|
||||
+ // this read completes, we must have an internal NodeController with the
|
||||
+ // parent test process connected as its broker.
|
||||
+ EXPECT_EQ("hi", ReadMessage(h));
|
||||
+
|
||||
+ // Send an unexpected AcceptInvitation message to the parent process. This
|
||||
+ // exercises the regression code path in the parent process.
|
||||
+ NodeController* controller = Core::Get()->GetNodeController();
|
||||
+ scoped_refptr<NodeChannel> channel = controller->GetBrokerChannel();
|
||||
+ channel->AcceptInvitation(ports::NodeName{0, 0}, ports::NodeName{0, 0});
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+} // namespace core
|
||||
+} // namespace mojo
|
||||
73
patches/chromium/cherry-pick-a4faa754a9ef.patch
Normal file
73
patches/chromium/cherry-pick-a4faa754a9ef.patch
Normal file
@@ -0,0 +1,73 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Harald Alvestrand <hta@chromium.org>
|
||||
Date: Tue, 2 Mar 2021 17:33:49 +0000
|
||||
Subject: Fix GetP2PSocketManager ownership
|
||||
|
||||
Let it return a mojo::SharedRemote<> instead of a raw pointer - this is
|
||||
a decoration around a shared_refptr.
|
||||
|
||||
(cherry picked from commit 82cdc0781ceb4c22ef5903cf3115bea518a5523b)
|
||||
|
||||
(cherry picked from commit 6ed1c0c425e03172c77ba0f1465fe3ade79f2b2a)
|
||||
|
||||
Bug: chromium:1172054
|
||||
Change-Id: I49bd22a0dc949bf869744d2ad25c1afcaea7fdbc
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2692532
|
||||
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
|
||||
Commit-Queue: Harald Alvestrand <hta@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#854050}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2709590
|
||||
Reviewed-by: Harald Alvestrand <hta@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4389@{#1280}
|
||||
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2726713
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1555}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc b/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc
|
||||
index 29884a255f24556f4dc8b41b22304938a4f0d775..72ec477f57871b460adf83ea9e1a4bd217d5eebe 100644
|
||||
--- a/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc
|
||||
+++ b/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc
|
||||
@@ -36,7 +36,7 @@ void P2PSocketDispatcher::RemoveNetworkListObserver(
|
||||
network_list_observers_->RemoveObserver(network_list_observer);
|
||||
}
|
||||
|
||||
-network::mojom::blink::P2PSocketManager*
|
||||
+mojo::SharedRemote<network::mojom::blink::P2PSocketManager>
|
||||
P2PSocketDispatcher::GetP2PSocketManager() {
|
||||
base::AutoLock lock(p2p_socket_manager_lock_);
|
||||
if (!p2p_socket_manager_) {
|
||||
@@ -56,7 +56,7 @@ P2PSocketDispatcher::GetP2PSocketManager() {
|
||||
*main_task_runner_.get(), FROM_HERE,
|
||||
CrossThreadBindOnce(&P2PSocketDispatcher::RequestInterfaceIfNecessary,
|
||||
scoped_refptr<P2PSocketDispatcher>(this)));
|
||||
- return p2p_socket_manager_.get();
|
||||
+ return p2p_socket_manager_;
|
||||
}
|
||||
|
||||
void P2PSocketDispatcher::NetworkListChanged(
|
||||
diff --git a/third_party/blink/renderer/platform/p2p/socket_dispatcher.h b/third_party/blink/renderer/platform/p2p/socket_dispatcher.h
|
||||
index c250d2af99d5291f34a7e3bfdb63fcbb70a5bd73..84e9c34c0896db5039d9cf8f51167d69ceec9be2 100644
|
||||
--- a/third_party/blink/renderer/platform/p2p/socket_dispatcher.h
|
||||
+++ b/third_party/blink/renderer/platform/p2p/socket_dispatcher.h
|
||||
@@ -66,7 +66,8 @@ class PLATFORM_EXPORT P2PSocketDispatcher
|
||||
void RemoveNetworkListObserver(
|
||||
blink::NetworkListObserver* network_list_observer) override;
|
||||
|
||||
- network::mojom::blink::P2PSocketManager* GetP2PSocketManager();
|
||||
+ mojo::SharedRemote<network::mojom::blink::P2PSocketManager>
|
||||
+ GetP2PSocketManager();
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<P2PSocketDispatcher>;
|
||||
@@ -95,7 +96,7 @@ class PLATFORM_EXPORT P2PSocketDispatcher
|
||||
mojo::PendingReceiver<network::mojom::blink::P2PSocketManager>
|
||||
p2p_socket_manager_receiver_;
|
||||
mojo::SharedRemote<network::mojom::blink::P2PSocketManager>
|
||||
- p2p_socket_manager_;
|
||||
+ p2p_socket_manager_ GUARDED_BY(p2p_socket_manager_lock_);
|
||||
base::Lock p2p_socket_manager_lock_;
|
||||
|
||||
// Cached from last |NetworkListChanged| call.
|
||||
171
patches/chromium/cherry-pick-b3dc4c4b349d.patch
Normal file
171
patches/chromium/cherry-pick-b3dc4c4b349d.patch
Normal file
@@ -0,0 +1,171 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hongchan Choi <hongchan@chromium.org>
|
||||
Date: Tue, 2 Mar 2021 15:17:19 +0000
|
||||
Subject: Introduce AudioBuffers for user access in ScriptProcessorNode
|
||||
|
||||
This CL adds new AudioBuffers for the access from the user code.
|
||||
|
||||
(cherry picked from commit b9e60ddc7606689e508f295077656389380288ba)
|
||||
|
||||
(cherry picked from commit c281886ca9ff22f6e75c8c1967dab9bf18b9942d)
|
||||
|
||||
(cherry picked from commit 33861dcf6d15415b6abf2152440906fafb74a27a)
|
||||
|
||||
Bug: 1177465
|
||||
Test: The local ASAN build doesn't reproduce on given POCs.
|
||||
Change-Id: Id9a3505ddb9ab61b4442385d0b830ef56f65f797
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2718543
|
||||
Auto-Submit: Hongchan Choi <hongchan@chromium.org>
|
||||
Reviewed-by: Raymond Toy <rtoy@chromium.org>
|
||||
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Original-Original-Original-Commit-Position: refs/heads/master@{#857817}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2719239
|
||||
Reviewed-by: Krishna Govind <govind@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/branch-heads/4429@{#2}
|
||||
Cr-Original-Original-Branched-From: 19b974fae7ec51a60e2f1044d81e2e1b32be179b-refs/heads/master@{#857666}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2721252
|
||||
Reviewed-by: Adrian Taylor <adetaylor@google.com>
|
||||
Commit-Queue: Krishna Govind <govind@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4324@{#2250}
|
||||
Cr-Original-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2727696
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1553}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
|
||||
index 6e80b23a32dd1895a0d51d08ee16c8cb2d44fc55..d46e17440a9f3c2de488432bf3efdba5ac01f193 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
|
||||
@@ -42,6 +42,28 @@
|
||||
|
||||
namespace blink {
|
||||
|
||||
+namespace {
|
||||
+
|
||||
+bool IsAudioBufferDetached(AudioBuffer* buffer) {
|
||||
+ bool is_buffer_detached = false;
|
||||
+ for (unsigned channel = 0; channel < buffer->numberOfChannels(); ++channel) {
|
||||
+ if (buffer->getChannelData(channel)->buffer()->IsDetached()) {
|
||||
+ is_buffer_detached = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return is_buffer_detached;
|
||||
+}
|
||||
+
|
||||
+bool BufferTopologyMatches(AudioBuffer* buffer_1, AudioBuffer* buffer_2) {
|
||||
+ return (buffer_1->numberOfChannels() == buffer_2->numberOfChannels()) &&
|
||||
+ (buffer_1->length() == buffer_2->length()) &&
|
||||
+ (buffer_1->sampleRate() == buffer_2->sampleRate());
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
ScriptProcessorHandler::ScriptProcessorHandler(
|
||||
AudioNode& node,
|
||||
float sample_rate,
|
||||
@@ -335,6 +357,12 @@ ScriptProcessorNode::ScriptProcessorNode(BaseAudioContext& context,
|
||||
input_buffers_.push_back(input_buffer);
|
||||
output_buffers_.push_back(output_buffer);
|
||||
}
|
||||
+
|
||||
+ external_input_buffer_ = AudioBuffer::Create(
|
||||
+ number_of_input_channels, buffer_size, sample_rate);
|
||||
+ external_output_buffer_ = AudioBuffer::Create(
|
||||
+ number_of_output_channels, buffer_size, sample_rate);
|
||||
+
|
||||
SetHandler(ScriptProcessorHandler::Create(
|
||||
*this, sample_rate, buffer_size, number_of_input_channels,
|
||||
number_of_output_channels, input_buffers_, output_buffers_));
|
||||
@@ -476,11 +504,62 @@ uint32_t ScriptProcessorNode::bufferSize() const {
|
||||
|
||||
void ScriptProcessorNode::DispatchEvent(double playback_time,
|
||||
uint32_t double_buffer_index) {
|
||||
- AudioBuffer* input_buffer = input_buffers_.at(double_buffer_index).Get();
|
||||
- AudioBuffer* output_buffer = output_buffers_.at(double_buffer_index).Get();
|
||||
- DCHECK(output_buffer);
|
||||
+ DCHECK(IsMainThread());
|
||||
+
|
||||
+ AudioBuffer* backing_input_buffer =
|
||||
+ input_buffers_.at(double_buffer_index).Get();
|
||||
+
|
||||
+ // The backing buffer can be nullptr, when the number of input channels is 0.
|
||||
+ if (backing_input_buffer) {
|
||||
+ // Also the author code might have transferred |external_input_buffer| to
|
||||
+ // other threads or replaced it with a different AudioBuffer object. Then
|
||||
+ // re-create a new buffer instance.
|
||||
+ if (IsAudioBufferDetached(external_input_buffer_) ||
|
||||
+ !BufferTopologyMatches(backing_input_buffer,
|
||||
+ external_input_buffer_)) {
|
||||
+ external_input_buffer_ = AudioBuffer::Create(
|
||||
+ backing_input_buffer->numberOfChannels(),
|
||||
+ backing_input_buffer->length(),
|
||||
+ backing_input_buffer->sampleRate());
|
||||
+ }
|
||||
+
|
||||
+ for (unsigned channel = 0;
|
||||
+ channel < backing_input_buffer->numberOfChannels(); ++channel) {
|
||||
+ const float* source = static_cast<float*>(
|
||||
+ backing_input_buffer->getChannelData(channel)->buffer()->Data());
|
||||
+ float* destination = static_cast<float*>(
|
||||
+ external_input_buffer_->getChannelData(channel)->buffer()->Data());
|
||||
+ memcpy(destination, source,
|
||||
+ backing_input_buffer->length() * sizeof(float));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
AudioNode::DispatchEvent(*AudioProcessingEvent::Create(
|
||||
- input_buffer, output_buffer, playback_time));
|
||||
+ external_input_buffer_, external_output_buffer_, playback_time));
|
||||
+
|
||||
+ AudioBuffer* backing_output_buffer =
|
||||
+ output_buffers_.at(double_buffer_index).Get();
|
||||
+
|
||||
+ if (backing_output_buffer) {
|
||||
+ if (IsAudioBufferDetached(external_output_buffer_) ||
|
||||
+ !BufferTopologyMatches(backing_output_buffer,
|
||||
+ external_output_buffer_)) {
|
||||
+ external_output_buffer_ = AudioBuffer::Create(
|
||||
+ backing_output_buffer->numberOfChannels(),
|
||||
+ backing_output_buffer->length(),
|
||||
+ backing_output_buffer->sampleRate());
|
||||
+ }
|
||||
+
|
||||
+ for (unsigned channel = 0;
|
||||
+ channel < backing_output_buffer->numberOfChannels(); ++channel) {
|
||||
+ const float* source = static_cast<float*>(
|
||||
+ external_output_buffer_->getChannelData(channel)->buffer()->Data());
|
||||
+ float* destination = static_cast<float*>(
|
||||
+ backing_output_buffer->getChannelData(channel)->buffer()->Data());
|
||||
+ memcpy(destination, source,
|
||||
+ backing_output_buffer->length() * sizeof(float));
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
bool ScriptProcessorNode::HasPendingActivity() const {
|
||||
@@ -499,6 +578,8 @@ bool ScriptProcessorNode::HasPendingActivity() const {
|
||||
void ScriptProcessorNode::Trace(Visitor* visitor) const {
|
||||
visitor->Trace(input_buffers_);
|
||||
visitor->Trace(output_buffers_);
|
||||
+ visitor->Trace(external_input_buffer_);
|
||||
+ visitor->Trace(external_output_buffer_);
|
||||
AudioNode::Trace(visitor);
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node.h b/third_party/blink/renderer/modules/webaudio/script_processor_node.h
|
||||
index a93dbacc70709c063b452be3e5fe4b56fcaf7c4a..ea5ad1c326d6eb202ba6b8eba0ac5b5d0f1f61b1 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/script_processor_node.h
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_node.h
|
||||
@@ -169,6 +169,8 @@ class ScriptProcessorNode final
|
||||
private:
|
||||
HeapVector<Member<AudioBuffer>> input_buffers_;
|
||||
HeapVector<Member<AudioBuffer>> output_buffers_;
|
||||
+ Member<AudioBuffer> external_input_buffer_;
|
||||
+ Member<AudioBuffer> external_output_buffer_;
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
163
patches/chromium/cherry-pick-b772b48067c4.patch
Normal file
163
patches/chromium/cherry-pick-b772b48067c4.patch
Normal file
@@ -0,0 +1,163 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Christoph Schwering <schwering@google.com>
|
||||
Date: Thu, 4 Mar 2021 17:21:46 +0000
|
||||
Subject: Limit preview and filling only for non-state fields.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The number of times a value is filled into different fields is limited.
|
||||
The exception are state fields because websites sometimes have one
|
||||
state select box for each country and display the relevant select
|
||||
box once the respective country has been selected.
|
||||
|
||||
This CL simplifies this mechanism and makes it more explicit by
|
||||
encoding the type-dependent limits in TypeValueFormFillingLimit().
|
||||
As a side effect, the limits apply not just to filled fields but also
|
||||
unfilled fields of the same type.
|
||||
|
||||
(cherry picked from commit 18d3f86206e88156e2eb20c1f691b3b40a779150)
|
||||
|
||||
Bug: 1075734, 1084903
|
||||
Change-Id: Icc5e8e082850ed44d9c7fbbc911d03a95033d81f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2557977
|
||||
Commit-Queue: Matthias Körber <koerber@google.com>
|
||||
Reviewed-by: Matthias Körber <koerber@google.com>
|
||||
Auto-Submit: Christoph Schwering <schwering@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#830778}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2731409
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1560}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
|
||||
index 4e8321b85e329139012a5026b044d2c070750151..ded9c514894eee34a34eb562b08e7484673dfc4a 100644
|
||||
--- a/components/autofill/core/browser/autofill_manager.cc
|
||||
+++ b/components/autofill/core/browser/autofill_manager.cc
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "base/check_op.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/containers/adapters.h"
|
||||
+#include "base/containers/flat_map.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/guid.h"
|
||||
@@ -424,9 +425,15 @@ const char* SubmissionSourceToString(SubmissionSource source) {
|
||||
|
||||
// Returns how many fields with type |field_type| may be filled in a form at
|
||||
// maximum.
|
||||
-int TypeValueFormFillingLimit(ServerFieldType field_type) {
|
||||
- return field_type == CREDIT_CARD_NUMBER ? kCreditCardTypeValueFormFillingLimit
|
||||
- : kTypeValueFormFillingLimit;
|
||||
+size_t TypeValueFormFillingLimit(ServerFieldType field_type) {
|
||||
+ switch (field_type) {
|
||||
+ case CREDIT_CARD_NUMBER:
|
||||
+ return kCreditCardTypeValueFormFillingLimit;
|
||||
+ case ADDRESS_HOME_STATE:
|
||||
+ return kStateTypeValueFormFillingLimit;
|
||||
+ default:
|
||||
+ return kTypeValueFormFillingLimit;
|
||||
+ }
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -1757,7 +1764,8 @@ void AutofillManager::FillOrPreviewDataModelForm(
|
||||
|
||||
// Count the number of times the value of a specific type was filled into the
|
||||
// form.
|
||||
- std::map<ServerFieldType, int> type_filling_count;
|
||||
+ base::flat_map<ServerFieldType, size_t> type_filling_count;
|
||||
+ type_filling_count.reserve(form_structure->field_count());
|
||||
|
||||
for (size_t i = 0; i < form_structure->field_count(); ++i) {
|
||||
std::string field_number = base::StringPrintf("Field %zu", i);
|
||||
@@ -1841,7 +1849,7 @@ void AutofillManager::FillOrPreviewDataModelForm(
|
||||
|
||||
// A field with a specific type is only allowed to be filled a limited
|
||||
// number of times given by |TypeValueFormFillingLimit(field_type)|.
|
||||
- if (type_filling_count[field_type] >=
|
||||
+ if (++type_filling_count[field_type] >
|
||||
TypeValueFormFillingLimit(field_type)) {
|
||||
buffer << Tr{} << field_number
|
||||
<< "Skipped: field-type filling-limit reached";
|
||||
@@ -1877,10 +1885,6 @@ void AutofillManager::FillOrPreviewDataModelForm(
|
||||
bool has_value_after = !result.fields[i].value.empty();
|
||||
bool is_autofilled_after = result.fields[i].is_autofilled;
|
||||
|
||||
- // If the field was actually filled, increment the filling counter.
|
||||
- if (is_autofilled_after)
|
||||
- type_filling_count[field_type]++;
|
||||
-
|
||||
buffer << Tr{} << field_number
|
||||
<< base::StringPrintf(
|
||||
"Fillable - has value: %d->%d; autofilled: %d->%d. %s",
|
||||
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
|
||||
index 79f827e5c8ea473d8c6e9bcef42d58427e278fc7..fd5973da9c997dc4c74489dd112b541f86d9bf57 100644
|
||||
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
|
||||
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
|
||||
@@ -2903,6 +2903,14 @@ TEST_F(AutofillManagerTest, OnlyCountFilledSelectionBoxesForTypeFillingLimit) {
|
||||
form.fields.push_back(field);
|
||||
}
|
||||
|
||||
+ // Create a selection box for the state that hat the correct entry to be
|
||||
+ // filled with user data. Note, TN is the official abbreviation for Tennessee.
|
||||
+ for (int i = 0; i < 20; ++i) {
|
||||
+ test::CreateTestSelectField("Country", "country", "", {"DE", "FR", "US"},
|
||||
+ {"DE", "FR", "US"}, 3, &field);
|
||||
+ form.fields.push_back(field);
|
||||
+ }
|
||||
+
|
||||
std::vector<FormData> forms(1, form);
|
||||
FormsSeen(forms);
|
||||
|
||||
@@ -2939,17 +2947,18 @@ TEST_F(AutofillManagerTest, OnlyCountFilledSelectionBoxesForTypeFillingLimit) {
|
||||
response_data.fields[4 + i]);
|
||||
}
|
||||
|
||||
- // Verify that the next 8 selection boxes are correctly filled again.
|
||||
- for (int i = 0; i < 8; i++) {
|
||||
+ // Verify that the remaining selection boxes are correctly filled again
|
||||
+ // because there's no limit on filling ADDRESS_HOME_STATE fields.
|
||||
+ for (int i = 0; i < 20; i++) {
|
||||
ExpectFilledField("State", "state", "TN", "select-one",
|
||||
response_data.fields[24 + i]);
|
||||
}
|
||||
|
||||
- // Verify that the last 12 boxes are not filled because the filling limit for
|
||||
- // the state type is already reached.
|
||||
- for (int i = 0; i < 12; i++) {
|
||||
- ExpectFilledField("State", "state", "", "select-one",
|
||||
- response_data.fields[32 + i]);
|
||||
+ // Verify that only the first 9 of the remaining selection boxes are
|
||||
+ // correctly filled due to the limit on filling ADDRESS_HOME_COUNTRY fields.
|
||||
+ for (int i = 0; i < 20; i++) {
|
||||
+ ExpectFilledField("Country", "country", i < 9 ? "US" : "", "select-one",
|
||||
+ response_data.fields[44 + i]);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/components/autofill/core/common/autofill_constants.h b/components/autofill/core/common/autofill_constants.h
|
||||
index 84c5b916b0330ab8305db7b1831b42fa42843708..2d6ade5e6bea81ec4383d0345863514e1b551ea8 100644
|
||||
--- a/components/autofill/core/common/autofill_constants.h
|
||||
+++ b/components/autofill/core/common/autofill_constants.h
|
||||
@@ -68,12 +68,14 @@ const int64_t kAutocompleteRetentionPolicyPeriodInDays = 14 * 31;
|
||||
|
||||
// Limits the number of times the value of a specific type can be filled into a
|
||||
// form.
|
||||
-constexpr int kTypeValueFormFillingLimit = 9;
|
||||
-
|
||||
// Credit card numbers are sometimes distributed between up to 19 individual
|
||||
-// fields. Therefore, credit cards need a higher limit compared to
|
||||
-// |kTypeValueFormFillingLimit|.
|
||||
-constexpr int kCreditCardTypeValueFormFillingLimit = 19;
|
||||
+// fields. Therefore, credit cards need a higher limit.
|
||||
+// State fields are effecectively unlimited because there are sometimes hidden
|
||||
+// fields select boxes, each with a list of states for one specific countries,
|
||||
+// which are displayed only upon country selection.
|
||||
+constexpr size_t kTypeValueFormFillingLimit = 9;
|
||||
+constexpr size_t kCreditCardTypeValueFormFillingLimit = 19;
|
||||
+constexpr size_t kStateTypeValueFormFillingLimit = 1000;
|
||||
|
||||
} // namespace autofill
|
||||
|
||||
70
patches/chromium/cherry-pick-c6d6f7aee733.patch
Normal file
70
patches/chromium/cherry-pick-c6d6f7aee733.patch
Normal file
@@ -0,0 +1,70 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lukasz Anforowicz <lukasza@chromium.org>
|
||||
Date: Thu, 4 Mar 2021 17:07:16 +0000
|
||||
Subject: M86-LTS: Destroy `url_loader_factories_` before other NetworkContext
|
||||
fields
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
[M86 Merge]: Fixed conflict in network_context.h.
|
||||
|
||||
(cherry picked from commit f2b091f02593c67fd67db936452f363102b8d035)
|
||||
|
||||
(cherry picked from commit ffeb0731f83f8c4fa72776b658df45f0e6da041c)
|
||||
|
||||
Bug: 1174943
|
||||
Change-Id: I7488c7779f51a3f0d82ecad3d65446032c065b26
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2679230
|
||||
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
|
||||
Reviewed-by: Matt Menke <mmenke@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#852311}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2692489
|
||||
Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4389@{#986}
|
||||
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2731372
|
||||
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1559}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/services/network/network_context.h b/services/network/network_context.h
|
||||
index 0d9c4cce09db485b5e750921eed703c75ffdf15a..3a88fd24b421411f086a31db34c07ed0f175d14f 100644
|
||||
--- a/services/network/network_context.h
|
||||
+++ b/services/network/network_context.h
|
||||
@@ -604,13 +604,6 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
|
||||
std::set<std::unique_ptr<ProxyLookupRequest>, base::UniquePtrComparator>
|
||||
proxy_lookup_requests_;
|
||||
|
||||
- // This must be below |url_request_context_| so that the URLRequestContext
|
||||
- // outlives all the URLLoaderFactories and URLLoaders that depend on it;
|
||||
- // for the same reason, it must also be below |network_context_|.
|
||||
- std::set<std::unique_ptr<cors::CorsURLLoaderFactory>,
|
||||
- base::UniquePtrComparator>
|
||||
- url_loader_factories_;
|
||||
-
|
||||
std::set<std::unique_ptr<QuicTransport>, base::UniquePtrComparator>
|
||||
quic_transports_;
|
||||
|
||||
@@ -721,6 +714,19 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
|
||||
// HttpAuthHandle via |NetworkContext::CreateHttpAuthHandlerFactory|.
|
||||
net::HttpAuthPreferences http_auth_merged_preferences_;
|
||||
|
||||
+ // CorsURLLoaderFactory assumes that fields owned by the NetworkContext always
|
||||
+ // live longer than the factory. Therefore we want the factories to be
|
||||
+ // destroyed before other fields above. In particular:
|
||||
+ // - This must be below |url_request_context_| so that the URLRequestContext
|
||||
+ // outlives all the URLLoaderFactories and URLLoaders that depend on it;
|
||||
+ // for the same reason, it must also be below |network_context_|.
|
||||
+ // - This must be below |loader_count_per_process_| that is touched by
|
||||
+ // CorsURLLoaderFactory::DestroyURLLoader (see also
|
||||
+ // https://crbug.com/1174943).
|
||||
+ std::set<std::unique_ptr<cors::CorsURLLoaderFactory>,
|
||||
+ base::UniquePtrComparator>
|
||||
+ url_loader_factories_;
|
||||
+
|
||||
base::WeakPtrFactory<NetworkContext> weak_factory_{this};
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NetworkContext);
|
||||
110
patches/chromium/cherry-pick-d74ba931c4b7.patch
Normal file
110
patches/chromium/cherry-pick-d74ba931c4b7.patch
Normal file
@@ -0,0 +1,110 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Date: Wed, 13 Jan 2021 21:27:05 +0000
|
||||
Subject: content-visibility: Don't adjust position of a locked hittest result
|
||||
node.
|
||||
|
||||
This patch ensures that if we have a hittest result that has a locked
|
||||
node, we don't try to recurse into its subtree. This can happen when we
|
||||
do a PositionWithAffinity check.
|
||||
|
||||
R=chrishtr@chromium.org
|
||||
|
||||
(cherry picked from commit 8483cf6944e38203c3b247163c54cfa105e89c56)
|
||||
|
||||
(cherry picked from commit 3f7b67374a1121b6756ccfd2e4e414987f167489)
|
||||
|
||||
Bug: 1162131
|
||||
Change-Id: I357bd7032c6c2b6c9405bf26c49a36bda22d6a0d
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2611453
|
||||
Reviewed-by: Chris Harrelson <chrishtr@chromium.org>
|
||||
Commit-Queue: vmpstr <vmpstr@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#840727}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2618603
|
||||
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
|
||||
Reviewed-by: Krishna Govind <govind@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4324@{#1566}
|
||||
Cr-Original-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2618982
|
||||
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1520}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/layout/hit_test_result.cc b/third_party/blink/renderer/core/layout/hit_test_result.cc
|
||||
index 1359aa6bdd532028d8280b093a4381a70e4a7577..9d02cabafa3b8acc19ae2c0007c0eb6b86f1fb5d 100644
|
||||
--- a/third_party/blink/renderer/core/layout/hit_test_result.cc
|
||||
+++ b/third_party/blink/renderer/core/layout/hit_test_result.cc
|
||||
@@ -21,12 +21,14 @@
|
||||
|
||||
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
|
||||
|
||||
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
|
||||
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
|
||||
#include "third_party/blink/renderer/core/dom/pseudo_element.h"
|
||||
#include "third_party/blink/renderer/core/dom/shadow_root.h"
|
||||
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
|
||||
#include "third_party/blink/renderer/core/editing/frame_selection.h"
|
||||
#include "third_party/blink/renderer/core/editing/position_with_affinity.h"
|
||||
+#include "third_party/blink/renderer/core/editing/text_affinity.h"
|
||||
#include "third_party/blink/renderer/core/editing/visible_units.h"
|
||||
#include "third_party/blink/renderer/core/frame/local_frame.h"
|
||||
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
|
||||
@@ -144,6 +146,20 @@ PositionWithAffinity HitTestResult::GetPosition() const {
|
||||
LayoutObject* layout_object = GetLayoutObject();
|
||||
if (!layout_object)
|
||||
return PositionWithAffinity();
|
||||
+
|
||||
+ // We should never have a layout object that is within a locked subtree.
|
||||
+ CHECK(!DisplayLockUtilities::NearestLockedExclusiveAncestor(*layout_object));
|
||||
+
|
||||
+ // If the layout object is blocked by display lock, we return the beginning of
|
||||
+ // the node as the position. This is because we don't paint contents of the
|
||||
+ // element. Furthermore, any caret adjustments below can access layout-dirty
|
||||
+ // state in the subtree of this object.
|
||||
+ if (layout_object->PaintBlockedByDisplayLock(
|
||||
+ DisplayLockLifecycleTarget::kChildren)) {
|
||||
+ return PositionWithAffinity(Position(*inner_node_, 0),
|
||||
+ TextAffinity::kDefault);
|
||||
+ }
|
||||
+
|
||||
if (inner_possibly_pseudo_node_->IsPseudoElement() &&
|
||||
inner_possibly_pseudo_node_->GetPseudoId() == kPseudoIdBefore) {
|
||||
return PositionWithAffinity(MostForwardCaretPosition(
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-080.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-080.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d3cea5fb83767ddfc236850097387644e0f74c8e
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-080.html
|
||||
@@ -0,0 +1,31 @@
|
||||
+<!doctype HTML>
|
||||
+<html id=html>
|
||||
+<meta charset="utf8">
|
||||
+<title>Content Visibility: caret position with html hidden</title>
|
||||
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
|
||||
+<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
|
||||
+<meta name="assert" content="caretRangeFromPoint works even if html has content-visibility hidden">
|
||||
+
|
||||
+<script src="/resources/testharness.js"></script>
|
||||
+<script src="/resources/testharnessreport.js"></script>
|
||||
+
|
||||
+<meter></meter>
|
||||
+<iframe></iframe>
|
||||
+<style>
|
||||
+* {
|
||||
+ all: initial;
|
||||
+ content-visibility: hidden;
|
||||
+}
|
||||
+</style>
|
||||
+
|
||||
+<script>
|
||||
+test(() => {
|
||||
+ const range = document.caretRangeFromPoint();
|
||||
+ assert_not_equals(range, null, "range exists");
|
||||
+ assert_equals(range.startContainer, html, "startContainer is html");
|
||||
+ assert_equals(range.startOffset, 0, "startOffset is zero");
|
||||
+ assert_equals(range.endContainer, html, "endContainer is html");
|
||||
+ assert_equals(range.endOffset, 0, "endOffset is zero");
|
||||
+}, "Caret range from point");
|
||||
+</script>
|
||||
+</html>
|
||||
39
patches/chromium/cherry-pick-d866af575997.patch
Normal file
39
patches/chromium/cherry-pick-d866af575997.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Raymond Toy <rtoy@chromium.org>
|
||||
Date: Mon, 7 Dec 2020 17:55:30 +0000
|
||||
Subject: Clear handlers when the base context goes away.
|
||||
|
||||
Previously, in BaseAudioContext::Clear() we called
|
||||
GetDeferredTaskHandler().ClearHandlersToBeDeleted(). But this was
|
||||
also called in DeferredTaskHandler::ContextWillBeDestroyed(), which is
|
||||
called in BaseAudioContext::~BaseAudioContext().
|
||||
|
||||
There's no need to call this twice while handling the audio context
|
||||
going away.
|
||||
|
||||
Manually verified that the tests from issue 1125635 and 1153658 work,
|
||||
and the deadlock in issue 1136571 is gone.
|
||||
|
||||
Bug: 1150065, 1153658
|
||||
Change-Id: Iee15c31dc637bf82d66bfd79d5238b1f80813153
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2575418
|
||||
Commit-Queue: Raymond Toy <rtoy@chromium.org>
|
||||
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#834265}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
|
||||
index e203973a516c630af3decaddc1080ab9697c634a..cd16a1f31fb4d8469f35a8c5e08c51d15efb0cf8 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
|
||||
@@ -142,9 +142,8 @@ void BaseAudioContext::Initialize() {
|
||||
|
||||
void BaseAudioContext::Clear() {
|
||||
destination_node_.Clear();
|
||||
- // The audio rendering thread is dead. Nobody will schedule AudioHandler
|
||||
- // deletion. Let's do it ourselves.
|
||||
- GetDeferredTaskHandler().ClearHandlersToBeDeleted();
|
||||
+ // Make a note that we've cleared out the context so that there's no pending
|
||||
+ // activity.
|
||||
is_cleared_ = true;
|
||||
}
|
||||
|
||||
132
patches/chromium/cherry-pick-d8d64b7cd244.patch
Normal file
132
patches/chromium/cherry-pick-d8d64b7cd244.patch
Normal file
@@ -0,0 +1,132 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xianzhu Wang <wangxianzhu@chromium.org>
|
||||
Date: Mon, 16 Nov 2020 17:26:33 +0000
|
||||
Subject: Ensure change type for OverflowControlsClip is returned
|
||||
|
||||
This at least ensures that we will update the paint properites for the
|
||||
composited overflow control layers in pre-CompositeAfterPaint to avoid
|
||||
stale properties on the layers.
|
||||
|
||||
The test doesn't actually reproduce the bug because any test simpler
|
||||
than the bug case couldn't reproduce the bug as the update would be
|
||||
triggered in other code paths (any style change, layout change, etc.).
|
||||
|
||||
Anyway this CL does fix the bug case.
|
||||
|
||||
TBR=wangxianzhu@chromium.org
|
||||
|
||||
(cherry picked from commit c20bb9897ef6d26a46391a4dc1658c5d33e0c100)
|
||||
|
||||
(cherry picked from commit cfb81e677a508871f56d8bec958d0b585298ae0c)
|
||||
|
||||
Bug: 1137603
|
||||
Change-Id: I5cca970bcf8cda6085527f79a97f269c4e3e9986
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2500264
|
||||
Reviewed-by: Stefan Zager <szager@chromium.org>
|
||||
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#820986}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2536910
|
||||
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4240@{#1446}
|
||||
Cr-Original-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2540592
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Jana Grill <janagrill@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240_112@{#26}
|
||||
Cr-Branched-From: 427c00d3874b6abcf4c4c2719768835fc3ef26d6-refs/branch-heads/4240@{#1291}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc
|
||||
index e991dfac93cfa90f46b92e00c4f29318736bc7ba..b42f1d6bd9b04f293034ee97c8eaa7aa10390ac9 100644
|
||||
--- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc
|
||||
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc
|
||||
@@ -174,4 +174,56 @@ TEST_F(CompositingLayerPropertyUpdaterTest,
|
||||
}
|
||||
}
|
||||
|
||||
+TEST_F(CompositingLayerPropertyUpdaterTest, OverflowControlsClip) {
|
||||
+ SetBodyInnerHTML(R"HTML(
|
||||
+ <style>
|
||||
+ ::-webkit-scrollbar { width: 20px; }
|
||||
+ #container {
|
||||
+ width: 5px;
|
||||
+ height: 100px;
|
||||
+ }
|
||||
+ #target {
|
||||
+ overflow: scroll;
|
||||
+ will-change: transform;
|
||||
+ width: 100%;
|
||||
+ height: 100%;
|
||||
+ }
|
||||
+ </style>
|
||||
+ <div id="container">
|
||||
+ <div id="target"></div>
|
||||
+ </div>
|
||||
+ )HTML");
|
||||
+
|
||||
+ // Initially the vertical scrollbar overflows the narrow border box.
|
||||
+ auto* container = GetDocument().getElementById("container");
|
||||
+ auto* target = ToLayoutBox(GetLayoutObjectByElementId("target"));
|
||||
+ auto* scrollbar_layer =
|
||||
+ target->GetScrollableArea()->GraphicsLayerForVerticalScrollbar();
|
||||
+ auto target_state = target->FirstFragment().LocalBorderBoxProperties();
|
||||
+ auto scrollbar_state = target_state;
|
||||
+ auto* overflow_controls_clip =
|
||||
+ target->FirstFragment().PaintProperties()->OverflowControlsClip();
|
||||
+ ASSERT_TRUE(overflow_controls_clip);
|
||||
+ scrollbar_state.SetClip(*overflow_controls_clip);
|
||||
+ EXPECT_EQ(scrollbar_state, scrollbar_layer->GetPropertyTreeState());
|
||||
+
|
||||
+ // Widen target to make the vertical scrollbar contained by the border box.
|
||||
+ container->setAttribute(html_names::kStyleAttr, "width: 100px");
|
||||
+ UpdateAllLifecyclePhasesForTest();
|
||||
+ LOG(ERROR) << target->Size();
|
||||
+ EXPECT_FALSE(
|
||||
+ target->FirstFragment().PaintProperties()->OverflowControlsClip());
|
||||
+ EXPECT_EQ(target_state, scrollbar_layer->GetPropertyTreeState());
|
||||
+
|
||||
+ // Narrow down target back.
|
||||
+ container->removeAttribute(html_names::kStyleAttr);
|
||||
+ UpdateAllLifecyclePhasesForTest();
|
||||
+ scrollbar_state = target_state;
|
||||
+ overflow_controls_clip =
|
||||
+ target->FirstFragment().PaintProperties()->OverflowControlsClip();
|
||||
+ ASSERT_TRUE(overflow_controls_clip);
|
||||
+ scrollbar_state.SetClip(*overflow_controls_clip);
|
||||
+ EXPECT_EQ(scrollbar_state, scrollbar_layer->GetPropertyTreeState());
|
||||
+}
|
||||
+
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
|
||||
index 0702a0fc65a69ab1da2cceeb4e6dcb9be30c8d3b..527024f5b1e9c71d7ad5311805c81c3587a7dc32 100644
|
||||
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
|
||||
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
|
||||
@@ -1554,21 +1554,21 @@ void FragmentPaintPropertyTreeBuilder::UpdateOverflowControlsClip() {
|
||||
|
||||
if (NeedsOverflowControlsClip()) {
|
||||
// Clip overflow controls to the border box rect. Not wrapped with
|
||||
- // OnUpdateClip() because this clip doesn't affect descendants.
|
||||
+ // OnUpdateClip() because this clip doesn't affect descendants. Wrap with
|
||||
+ // OnUpdate() to let PrePaintTreeWalk see the change. This may cause
|
||||
+ // unnecessary subtree update, but is not a big deal because it is rare.
|
||||
const auto& clip_rect = PhysicalRect(context_.current.paint_offset,
|
||||
ToLayoutBox(object_).Size());
|
||||
- properties_->UpdateOverflowControlsClip(
|
||||
+ OnUpdate(properties_->UpdateOverflowControlsClip(
|
||||
*context_.current.clip,
|
||||
ClipPaintPropertyNode::State(context_.current.transform,
|
||||
FloatRoundedRect(FloatRect(clip_rect)),
|
||||
- ToSnappedClipRect(clip_rect)));
|
||||
+ ToSnappedClipRect(clip_rect))));
|
||||
} else {
|
||||
- properties_->ClearOverflowControlsClip();
|
||||
+ OnClear(properties_->ClearOverflowControlsClip());
|
||||
}
|
||||
|
||||
- // No need to set force_subtree_update_reasons and clip_changed because
|
||||
- // OverflowControlsClip applies to overflow controls only, not descendants.
|
||||
- // We also don't walk into custom scrollbars in PrePaintTreeWalk and
|
||||
+ // We don't walk into custom scrollbars in PrePaintTreeWalk because
|
||||
// LayoutObjects under custom scrollbars don't support paint properties.
|
||||
}
|
||||
|
||||
81
patches/chromium/cherry-pick-da9b5ec032ad.patch
Normal file
81
patches/chromium/cherry-pick-da9b5ec032ad.patch
Normal file
@@ -0,0 +1,81 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniele Castagna <dcastagna@chromium.org>
|
||||
Date: Mon, 14 Dec 2020 23:03:31 +0000
|
||||
Subject: viz: Destroy |gpu_memory_buffer_factory_| on IOThread
|
||||
|
||||
|gpu_memory_buffer_factory_| weak pointers are checked on the
|
||||
IOThread.
|
||||
Weak pointers should be invalidated on the same thread that
|
||||
checks them.
|
||||
|
||||
This CL moves the destruction of |gpu_memory_buffer_factory_|
|
||||
on the IOThread to avoid possible use after free issues.
|
||||
|
||||
Bug: 1152645
|
||||
|
||||
Change-Id: I0d42814f0e435a3746728515da1f32d08a1252cf
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2563077
|
||||
Commit-Queue: Daniele Castagna <dcastagna@chromium.org>
|
||||
Reviewed-by: Andres Calderon Jaramillo <andrescj@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#836827}
|
||||
|
||||
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc
|
||||
index 98cdbff9bf021f9665abdb339a25753b2e7b4807..6ab1e86035089b748eb636cc5e654702ee19fd9e 100644
|
||||
--- a/components/viz/service/gl/gpu_service_impl.cc
|
||||
+++ b/components/viz/service/gl/gpu_service_impl.cc
|
||||
@@ -428,16 +428,18 @@ GpuServiceImpl::~GpuServiceImpl() {
|
||||
GetLogMessageManager()->ShutdownLogging();
|
||||
|
||||
// Destroy the receiver on the IO thread.
|
||||
- base::WaitableEvent wait;
|
||||
- auto destroy_receiver_task = base::BindOnce(
|
||||
- [](mojo::Receiver<mojom::GpuService>* receiver,
|
||||
- base::WaitableEvent* wait) {
|
||||
- receiver->reset();
|
||||
- wait->Signal();
|
||||
- },
|
||||
- &receiver_, &wait);
|
||||
- if (io_runner_->PostTask(FROM_HERE, std::move(destroy_receiver_task)))
|
||||
- wait.Wait();
|
||||
+ {
|
||||
+ base::WaitableEvent wait;
|
||||
+ auto destroy_receiver_task = base::BindOnce(
|
||||
+ [](mojo::Receiver<mojom::GpuService>* receiver,
|
||||
+ base::WaitableEvent* wait) {
|
||||
+ receiver->reset();
|
||||
+ wait->Signal();
|
||||
+ },
|
||||
+ &receiver_, base::Unretained(&wait));
|
||||
+ if (io_runner_->PostTask(FROM_HERE, std::move(destroy_receiver_task)))
|
||||
+ wait.Wait();
|
||||
+ }
|
||||
|
||||
if (watchdog_thread_)
|
||||
watchdog_thread_->OnGpuProcessTearDown();
|
||||
@@ -445,6 +447,26 @@ GpuServiceImpl::~GpuServiceImpl() {
|
||||
media_gpu_channel_manager_.reset();
|
||||
gpu_channel_manager_.reset();
|
||||
|
||||
+ // Destroy |gpu_memory_buffer_factory_| on the IO thread since its weakptrs
|
||||
+ // are checked there.
|
||||
+ {
|
||||
+ base::WaitableEvent wait;
|
||||
+ auto destroy_gmb_factory = base::BindOnce(
|
||||
+ [](std::unique_ptr<gpu::GpuMemoryBufferFactory> gmb_factory,
|
||||
+ base::WaitableEvent* wait) {
|
||||
+ gmb_factory.reset();
|
||||
+ wait->Signal();
|
||||
+ },
|
||||
+ std::move(gpu_memory_buffer_factory_), base::Unretained(&wait));
|
||||
+
|
||||
+ if (io_runner_->PostTask(FROM_HERE, std::move(destroy_gmb_factory))) {
|
||||
+ // |gpu_memory_buffer_factory_| holds a raw pointer to
|
||||
+ // |vulkan_context_provider_|. Waiting here enforces the correct order
|
||||
+ // of destruction.
|
||||
+ wait.Wait();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
// Scheduler must be destroyed before sync point manager is destroyed.
|
||||
scheduler_.reset();
|
||||
owned_sync_point_manager_.reset();
|
||||
121
patches/chromium/cherry-pick-dea071d8b30f.patch
Normal file
121
patches/chromium/cherry-pick-dea071d8b30f.patch
Normal file
@@ -0,0 +1,121 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hongchan Choi <hongchan@chromium.org>
|
||||
Date: Tue, 2 Mar 2021 15:15:59 +0000
|
||||
Subject: Prevent accessing shared buffers from audio rendering thread
|
||||
|
||||
The shared buffer in ScriptProcessorNode can be accessed by the
|
||||
audio rendering thread when it is held by the main thread.
|
||||
|
||||
The solution suggested here is simply to expand the scope of
|
||||
the mutex to minimize the code change. This is a deprecated
|
||||
feature in Web Audio, so making significant changes is not
|
||||
sensible. By locking the entire scope of Process() call, this
|
||||
area would be immune to the similar problems in the future.
|
||||
|
||||
(cherry picked from commit 60987aa224f369fc0ea38c56e498389440921356)
|
||||
|
||||
(cherry picked from commit aeb6bc551b607e0c80c232ed4817c0ff5e9a7784)
|
||||
|
||||
Bug: 1174582
|
||||
Test: The repro case doesn't crash on ASAN.
|
||||
Change-Id: I2b292f94be65e6ec26c6eb0e0ed32b3fb2d88466
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2681193
|
||||
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
|
||||
Reviewed-by: Raymond Toy <rtoy@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#852240}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2715585
|
||||
Commit-Queue: Krishna Govind <govind@chromium.org>
|
||||
Reviewed-by: Srinivas Sista <srinivassista@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4324@{#2238}
|
||||
Cr-Original-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2726911
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1552}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
|
||||
index b1ca691b07b53b927a92753906f7f25edebac919..6e80b23a32dd1895a0d51d08ee16c8cb2d44fc55 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
|
||||
@@ -110,6 +110,14 @@ void ScriptProcessorHandler::Initialize() {
|
||||
}
|
||||
|
||||
void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
|
||||
+ // The main thread might be accessing the shared buffers. If so, silience
|
||||
+ // the output and return.
|
||||
+ MutexTryLocker try_locker(process_event_lock_);
|
||||
+ if (!try_locker.Locked()) {
|
||||
+ Output(0).Bus()->Zero();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
// Discussion about inputs and outputs:
|
||||
// As in other AudioNodes, ScriptProcessorNode uses an AudioBus for its input
|
||||
// and output (see inputBus and outputBus below). Additionally, there is a
|
||||
@@ -181,47 +189,26 @@ void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
|
||||
buffer_read_write_index_ =
|
||||
(buffer_read_write_index_ + frames_to_process) % BufferSize();
|
||||
|
||||
- // m_bufferReadWriteIndex will wrap back around to 0 when the current input
|
||||
- // and output buffers are full.
|
||||
- // When this happens, fire an event and swap buffers.
|
||||
+ // Fire an event and swap buffers when |buffer_read_write_index_| wraps back
|
||||
+ // around to 0. It means the current input and output buffers are full.
|
||||
if (!buffer_read_write_index_) {
|
||||
- // Avoid building up requests on the main thread to fire process events when
|
||||
- // they're not being handled. This could be a problem if the main thread is
|
||||
- // very busy doing other things and is being held up handling previous
|
||||
- // requests. The audio thread can't block on this lock, so we call
|
||||
- // tryLock() instead.
|
||||
- MutexTryLocker try_locker(process_event_lock_);
|
||||
- if (!try_locker.Locked()) {
|
||||
- // We're late in handling the previous request. The main thread must be
|
||||
- // very busy. The best we can do is clear out the buffer ourself here.
|
||||
- shared_output_buffer->Zero();
|
||||
+ if (Context()->HasRealtimeConstraint()) {
|
||||
+ // For a realtime context, fire an event and do not wait.
|
||||
+ PostCrossThreadTask(
|
||||
+ *task_runner_, FROM_HERE,
|
||||
+ CrossThreadBindOnce(&ScriptProcessorHandler::FireProcessEvent,
|
||||
+ AsWeakPtr(), double_buffer_index_));
|
||||
} else {
|
||||
- // With the realtime context, execute the script code asynchronously
|
||||
- // and do not wait.
|
||||
- if (Context()->HasRealtimeConstraint()) {
|
||||
- // Fire the event on the main thread with the appropriate buffer
|
||||
- // index.
|
||||
- PostCrossThreadTask(
|
||||
- *task_runner_, FROM_HERE,
|
||||
- CrossThreadBindOnce(&ScriptProcessorHandler::FireProcessEvent,
|
||||
- AsWeakPtr(), double_buffer_index_));
|
||||
- } else {
|
||||
- // If this node is in the offline audio context, use the
|
||||
- // waitable event to synchronize to the offline rendering thread.
|
||||
- std::unique_ptr<base::WaitableEvent> waitable_event =
|
||||
- std::make_unique<base::WaitableEvent>();
|
||||
-
|
||||
- PostCrossThreadTask(
|
||||
- *task_runner_, FROM_HERE,
|
||||
- CrossThreadBindOnce(
|
||||
- &ScriptProcessorHandler::FireProcessEventForOfflineAudioContext,
|
||||
- AsWeakPtr(), double_buffer_index_,
|
||||
- CrossThreadUnretained(waitable_event.get())));
|
||||
-
|
||||
- // Okay to block the offline audio rendering thread since it is
|
||||
- // not the actual audio device thread.
|
||||
- waitable_event->Wait();
|
||||
- }
|
||||
+ // For an offline context, wait until the script execution is finished.
|
||||
+ std::unique_ptr<base::WaitableEvent> waitable_event =
|
||||
+ std::make_unique<base::WaitableEvent>();
|
||||
+ PostCrossThreadTask(
|
||||
+ *task_runner_, FROM_HERE,
|
||||
+ CrossThreadBindOnce(
|
||||
+ &ScriptProcessorHandler::FireProcessEventForOfflineAudioContext,
|
||||
+ AsWeakPtr(), double_buffer_index_,
|
||||
+ CrossThreadUnretained(waitable_event.get())));
|
||||
+ waitable_event->Wait();
|
||||
}
|
||||
|
||||
SwapBuffers();
|
||||
146
patches/chromium/cherry-pick-df438f22f7d2.patch
Normal file
146
patches/chromium/cherry-pick-df438f22f7d2.patch
Normal file
@@ -0,0 +1,146 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Artem Sumaneev <asumaneev@google.com>
|
||||
Date: Wed, 3 Feb 2021 15:00:25 +0000
|
||||
Subject: Fix navigation request reset logic
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Do not delete navigation request which has started upon receiving
|
||||
notification about beforeunload dialog being cancelled, as a) this
|
||||
navigation request is not waiting for beforeunload and b) it might have
|
||||
been this navigation request which canceled this beforeunload dialog.
|
||||
|
||||
M86 merge conflicts and resolution:
|
||||
* content/browser/frame_host/*
|
||||
In ToT files the affected under frame_host directory are moved to
|
||||
renderer_host dir. Applied patch to frame_host, no further conflicts.
|
||||
|
||||
R=alexmos@chromium.org
|
||||
BUG=1161705
|
||||
|
||||
(cherry picked from commit 23c110b5b81dc401ded5d4dcecfab65d5d88fdfa)
|
||||
|
||||
(cherry picked from commit 87550e04d9fed4bbedff4546f4161e3c02415d7e)
|
||||
|
||||
Change-Id: I7d385d4326fac6f67d17a003679471806b5ad3b2
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2624733
|
||||
Commit-Queue: Alexander Timin <altimin@chromium.org>
|
||||
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#843343}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2652791
|
||||
Commit-Queue: Alex Moshchuk <alexmos@chromium.org>
|
||||
Auto-Submit: Alexander Timin <altimin@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4324@{#2040}
|
||||
Cr-Original-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2666397
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1537}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc
|
||||
index a1c72899b940d942bccf25c617ded87081f67901..754563aa43df66edc473e58106200a4b6923716a 100644
|
||||
--- a/content/browser/frame_host/frame_tree_node.cc
|
||||
+++ b/content/browser/frame_host/frame_tree_node.cc
|
||||
@@ -578,10 +578,12 @@ void FrameTreeNode::BeforeUnloadCanceled() {
|
||||
render_manager_.speculative_frame_host();
|
||||
if (speculative_frame_host)
|
||||
speculative_frame_host->ResetLoadingState();
|
||||
- // Note: there is no need to set an error code on the NavigationHandle here
|
||||
- // as it has not been created yet. It is only created when the
|
||||
- // BeforeUnloadCompleted callback is invoked.
|
||||
- if (navigation_request_)
|
||||
+ // Note: there is no need to set an error code on the NavigationHandle as
|
||||
+ // the observers have not been notified about its creation.
|
||||
+ // We also reset navigation request only when this navigation request was
|
||||
+ // responsible for this dialog, as a new navigation request might cancel
|
||||
+ // existing unrelated dialog.
|
||||
+ if (navigation_request_ && navigation_request_->IsWaitingForBeforeUnload())
|
||||
ResetNavigationRequest(false);
|
||||
}
|
||||
|
||||
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
|
||||
index 764e1f007b44bda5191e9021be59ab21446f6e55..498a8c3d8bcbea3b411901eaca9544ac5037308e 100644
|
||||
--- a/content/browser/frame_host/navigation_request.cc
|
||||
+++ b/content/browser/frame_host/navigation_request.cc
|
||||
@@ -4899,4 +4899,8 @@ void NavigationRequest::UpdateCoopStatus(
|
||||
}
|
||||
}
|
||||
|
||||
+bool NavigationRequest::IsWaitingForBeforeUnload() {
|
||||
+ return state_ < WILL_START_NAVIGATION;
|
||||
+}
|
||||
+
|
||||
} // namespace content
|
||||
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
|
||||
index 9db96ba9e042507b465821dbb0632317f1f0de70..e6f6e83e7013bd13b504969a8ebfbf5f1428eb2f 100644
|
||||
--- a/content/browser/frame_host/navigation_request.h
|
||||
+++ b/content/browser/frame_host/navigation_request.h
|
||||
@@ -670,6 +670,10 @@ class CONTENT_EXPORT NavigationRequest
|
||||
// navigation or an error page.
|
||||
bool IsWaitingToCommit();
|
||||
|
||||
+ // Whether this navigation request waits for the result of beforeunload before
|
||||
+ // proceeding.
|
||||
+ bool IsWaitingForBeforeUnload();
|
||||
+
|
||||
private:
|
||||
friend class NavigationRequestTest;
|
||||
|
||||
diff --git a/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
|
||||
index 089a0f08c96e7cb366659c633e2fdf5f61904f4c..bf7e8c0706f7694878b817312f4b7f8339d6645e 100644
|
||||
--- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc
|
||||
+++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
|
||||
@@ -1113,6 +1113,51 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBeforeUnloadBrowserTest,
|
||||
|
||||
namespace {
|
||||
|
||||
+class OnDidStartNavigation : public WebContentsObserver {
|
||||
+ public:
|
||||
+ OnDidStartNavigation(WebContents* web_contents,
|
||||
+ base::RepeatingClosure callback)
|
||||
+ : WebContentsObserver(web_contents), callback_(callback) {}
|
||||
+
|
||||
+ void DidStartNavigation(NavigationHandle* navigation) override {
|
||||
+ callback_.Run();
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ base::RepeatingClosure callback_;
|
||||
+};
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+// This test closes beforeunload dialog due to a new navigation starting from
|
||||
+// within WebContentsObserver::DidStartNavigation. This test succeeds if it
|
||||
+// doesn't crash with a UAF while loading the second page.
|
||||
+IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBeforeUnloadBrowserTest,
|
||||
+ DidStartNavigationClosesDialog) {
|
||||
+ GURL url1 = embedded_test_server()->GetURL("a.com", "/title1.html");
|
||||
+ GURL url2 = embedded_test_server()->GetURL("b.com", "/title1.html");
|
||||
+
|
||||
+ EXPECT_TRUE(NavigateToURL(shell(), url1));
|
||||
+
|
||||
+ // This matches the behaviour of TabModalDialogManager in
|
||||
+ // components/javascript_dialogs.
|
||||
+ OnDidStartNavigation close_dialog(web_contents(),
|
||||
+ base::BindLambdaForTesting([&]() {
|
||||
+ CloseDialogAndCancel();
|
||||
+
|
||||
+ // Check that web_contents() were not
|
||||
+ // deleted.
|
||||
+ DCHECK(web_contents()->GetMainFrame());
|
||||
+ }));
|
||||
+
|
||||
+ web_contents()->GetMainFrame()->RunBeforeUnloadConfirm(true,
|
||||
+ base::DoNothing());
|
||||
+
|
||||
+ EXPECT_TRUE(NavigateToURL(shell(), url2));
|
||||
+}
|
||||
+
|
||||
+namespace {
|
||||
+
|
||||
// A helper to execute some script in a frame just before it is deleted, such
|
||||
// that no message loops are pumped and no sync IPC messages are processed
|
||||
// between script execution and the destruction of the RenderFrameHost .
|
||||
70
patches/chromium/cherry-pick-ecdec1fb0f42.patch
Normal file
70
patches/chromium/cherry-pick-ecdec1fb0f42.patch
Normal file
@@ -0,0 +1,70 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Etienne Bergeron <etienneb@chromium.org>
|
||||
Date: Fri, 13 Nov 2020 17:40:59 +0000
|
||||
Subject: Fix text eliding for single-codepoint text with BiDi
|
||||
|
||||
This CL is fixing a corner case where RenderText::Elide(...) may
|
||||
produce a text with more codepoints than the original one. This is
|
||||
an issue since the breaklists are not resized and the overflow
|
||||
will lead the render_text code to perfoarm an out-of-bound memory
|
||||
access by deferencing breaks_.end() while rendering the text. This
|
||||
is causing chrome to crash.
|
||||
|
||||
See crbug/1142020 for details.
|
||||
|
||||
The bug was happening when:
|
||||
1) The text to elide was a single codepoint
|
||||
2) The width of the glyph of the codepoint is larger than the width
|
||||
of the ellipsis glyph
|
||||
3) Eliding is set to ELIDING_TAIL
|
||||
4) The display_rect width will trigger eliding
|
||||
(smaller than codepoint width, but larger than ellipsis width)
|
||||
5) The render text is set to RTL
|
||||
|
||||
A possible solution is to adjust the breaklist but this required
|
||||
larger refactoring and cannot be a minimal patch to be merge on
|
||||
other channels.
|
||||
|
||||
TBR=msw@chromium.org
|
||||
(cherry picked from commit e54920751871321474e0b953329c8aedcc8702c3)
|
||||
|
||||
Bug: 1142020
|
||||
Change-Id: I9854651175562ec5f0d0bf7083a8da99fede0e29
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2522892
|
||||
Commit-Queue: Etienne Bergeron <etienneb@chromium.org>
|
||||
Reviewed-by: Michael Wasserman <msw@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#824878}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2537931
|
||||
Reviewed-by: Etienne Bergeron <etienneb@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1450}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
|
||||
index 383943809398a59380518f00d84275f493f008c3..2887ea638e3843e61ca2a2935f52d08fe2bbe45e 100644
|
||||
--- a/ui/gfx/render_text.cc
|
||||
+++ b/ui/gfx/render_text.cc
|
||||
@@ -2060,8 +2060,10 @@ base::string16 RenderText::Elide(const base::string16& text,
|
||||
}
|
||||
|
||||
// Append the ellipsis and the optional directional marker characters.
|
||||
+ // Do not append the BiDi marker if the only codepoint in the text is
|
||||
+ // an ellipsis.
|
||||
new_text.append(ellipsis);
|
||||
- if (trailing_text_direction != text_direction) {
|
||||
+ if (new_text.size() != 1 && trailing_text_direction != text_direction) {
|
||||
if (trailing_text_direction == base::i18n::LEFT_TO_RIGHT)
|
||||
new_text += base::i18n::kLeftToRightMark;
|
||||
else
|
||||
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
|
||||
index 2fd63b1b75fc0fdec9772a9d6b74a13423bf7221..42827f318c8b1896c021f30895072e1add742d32 100644
|
||||
--- a/ui/gfx/render_text_unittest.cc
|
||||
+++ b/ui/gfx/render_text_unittest.cc
|
||||
@@ -1901,7 +1901,7 @@ const ElideTextCase kElideTailTextCases[] = {
|
||||
{"ltr_0", L"abc", L""},
|
||||
{"rtl_3", L"\u05d0\u05d1\u05d2", L"\u05d0\u05d1\u05d2"},
|
||||
{"rtl_2", L"\u05d0\u05d1\u05d2", L"\u05d0\u2026"},
|
||||
- {"rtl_1", L"\u05d0\u05d1\u05d2", L"\u2026\x200E"},
|
||||
+ {"rtl_1", L"\u05d0\u05d1\u05d2", L"\u2026"},
|
||||
{"rtl_0", L"\u05d0\u05d1\u05d2", L""},
|
||||
{"ltr_rtl_5", L"abc\u05d0\u05d1\u05d2", L"abc\u05d0\u2026\x200F"},
|
||||
{"ltr_rtl_4", L"abc\u05d0\u05d1\u05d2", L"abc\u2026"},
|
||||
140
patches/chromium/cherry-pick-fe20b05a0e5e.patch
Normal file
140
patches/chromium/cherry-pick-fe20b05a0e5e.patch
Normal file
@@ -0,0 +1,140 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jana Grill <janagrill@google.com>
|
||||
Date: Tue, 20 Apr 2021 18:23:33 +0000
|
||||
Subject: M86-LTS: DevTools: expect PageHandler may be destroyed during
|
||||
Page.navigate
|
||||
|
||||
(cherry picked from commit ff5e70191ec701cce4f84aaa25cd676376253a8a)
|
||||
|
||||
Bug: 1188889
|
||||
Change-Id: I5c2fcca84834d66c46d77a70683212c2330177a5
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2787756
|
||||
Commit-Queue: Andrey Kosyakov <caseq@chromium.org>
|
||||
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
|
||||
Reviewed-by: Karan Bhatia <karandeepb@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#867507}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2821536
|
||||
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1618}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/chrome/browser/extensions/api/debugger/debugger_apitest.cc b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
|
||||
index 71ce5a3399db29451e990d530736460aa28eeec0..b35accc8ce46f3465624898fe18d463529498d07 100644
|
||||
--- a/chrome/browser/extensions/api/debugger/debugger_apitest.cc
|
||||
+++ b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "components/sessions/content/session_tab_helper.h"
|
||||
#include "content/public/test/browser_test.h"
|
||||
#include "content/public/test/browser_test_utils.h"
|
||||
+#include "content/public/test/no_renderer_crashes_assertion.h"
|
||||
#include "extensions/browser/extension_function.h"
|
||||
#include "extensions/common/extension.h"
|
||||
#include "extensions/common/extension_builder.h"
|
||||
@@ -353,6 +354,19 @@ IN_PROC_BROWSER_TEST_F(DebuggerExtensionApiTest,
|
||||
<< message_;
|
||||
}
|
||||
|
||||
+// Tests that navigation to a forbidden URL is properly denied and
|
||||
+// does not cause a crash.
|
||||
+// This is a regression test for https://crbug.com/1188889.
|
||||
+IN_PROC_BROWSER_TEST_F(DebuggerExtensionApiTest, DISABLED_NavigateToForbiddenUrl) {
|
||||
+ content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
|
||||
+ // We don't send a DevTools command callback before disconnecting the session,
|
||||
+ // so the extension does not receive a callback either.
|
||||
+ base::AutoReset<bool> ignore_did_respond(
|
||||
+ &ExtensionFunction::ignore_all_did_respond_for_testing_do_not_use, true);
|
||||
+ ASSERT_TRUE(RunExtensionTest("debugger_navigate_to_forbidden_url"))
|
||||
+ << message_;
|
||||
+}
|
||||
+
|
||||
class SitePerProcessDebuggerExtensionApiTest : public DebuggerExtensionApiTest {
|
||||
public:
|
||||
void SetUpCommandLine(base::CommandLine* command_line) override {
|
||||
diff --git a/chrome/test/data/extensions/api_test/debugger_navigate_to_forbidden_url/background.js b/chrome/test/data/extensions/api_test/debugger_navigate_to_forbidden_url/background.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e2ef32fffd3e5d49e7dc10d53f8c891ddb0f3872
|
||||
--- /dev/null
|
||||
+++ b/chrome/test/data/extensions/api_test/debugger_navigate_to_forbidden_url/background.js
|
||||
@@ -0,0 +1,28 @@
|
||||
+// Copyright 2021 The Chromium Authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+const protocolVersion = '1.3';
|
||||
+const DETACHED_WHILE_HANDLING = 'Detached while handling command.';
|
||||
+
|
||||
+chrome.test.runTests([
|
||||
+ async function testNavigateToForbiddenUrl() {
|
||||
+ const {openTab} = await import('/_test_resources/test_util/tabs_util.js');
|
||||
+ const tab = await openTab('about:blank');
|
||||
+ const debuggee = {tabId: tab.id};
|
||||
+ await new Promise(resolve =>
|
||||
+ chrome.debugger.attach(debuggee, protocolVersion, resolve));
|
||||
+ chrome.debugger.sendCommand(debuggee, 'Page.crash');
|
||||
+ await new Promise(resolve =>
|
||||
+ chrome.debugger.onEvent.addListener((source, method, params) => {
|
||||
+ if (method === 'Inspector.targetCrashed')
|
||||
+ resolve();
|
||||
+ }));
|
||||
+ const result = await new Promise(resolve =>
|
||||
+ chrome.debugger.sendCommand(debuggee, 'Page.navigate', {
|
||||
+ url: 'chrome://version'
|
||||
+ }, resolve));
|
||||
+ chrome.test.assertLastError(DETACHED_WHILE_HANDLING);
|
||||
+ chrome.test.succeed();
|
||||
+ }
|
||||
+]);
|
||||
diff --git a/chrome/test/data/extensions/api_test/debugger_navigate_to_forbidden_url/manifest.json b/chrome/test/data/extensions/api_test/debugger_navigate_to_forbidden_url/manifest.json
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..05db294ed7f49893431b0039a5f338d20e08f27d
|
||||
--- /dev/null
|
||||
+++ b/chrome/test/data/extensions/api_test/debugger_navigate_to_forbidden_url/manifest.json
|
||||
@@ -0,0 +1,11 @@
|
||||
+{
|
||||
+ "name": "Debugger API test for CDP-initiated navigation to forbidden URLs",
|
||||
+ "version": "1.0",
|
||||
+ "manifest_version": 2,
|
||||
+ "background": {
|
||||
+ "scripts": ["background.js"]
|
||||
+ },
|
||||
+ "permissions": [
|
||||
+ "debugger"
|
||||
+ ]
|
||||
+}
|
||||
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc
|
||||
index 630de0dd016fd3d054bcd40b22d75a242eeaa23e..a340d3e4519ada9edba279090ea11b57521ef0f4 100644
|
||||
--- a/content/browser/devtools/protocol/page_handler.cc
|
||||
+++ b/content/browser/devtools/protocol/page_handler.cc
|
||||
@@ -496,7 +496,12 @@ void PageHandler::Navigate(const std::string& url,
|
||||
params.referrer = Referrer(GURL(referrer.fromMaybe("")), policy);
|
||||
params.transition_type = type;
|
||||
params.frame_tree_node_id = frame_tree_node->frame_tree_node_id();
|
||||
+ // Handler may be destroyed while navigating if the session
|
||||
+ // gets disconnected as a result of access checks.
|
||||
+ base::WeakPtr<PageHandler> weak_self = weak_factory_.GetWeakPtr();
|
||||
frame_tree_node->navigator().GetController()->LoadURLWithParams(params);
|
||||
+ if (!weak_self)
|
||||
+ return;
|
||||
|
||||
base::UnguessableToken frame_token = frame_tree_node->devtools_frame_token();
|
||||
auto navigate_callback = navigate_callbacks_.find(frame_token);
|
||||
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
|
||||
index 52fdd0f1066699cc019c33de2517c23f12b4a616..8795c547717b206f4e459f655f6e62a7ba9229e0 100644
|
||||
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
|
||||
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
|
||||
@@ -472,8 +472,11 @@ void RenderFrameDevToolsAgentHost::UpdateFrameHost(
|
||||
if (!ShouldAllowSession(session))
|
||||
restricted_sessions.push_back(session);
|
||||
}
|
||||
- if (!restricted_sessions.empty())
|
||||
+ scoped_refptr<RenderFrameDevToolsAgentHost> protect;
|
||||
+ if (!restricted_sessions.empty()) {
|
||||
+ protect = this;
|
||||
ForceDetachRestrictedSessions(restricted_sessions);
|
||||
+ }
|
||||
|
||||
UpdateFrameAlive();
|
||||
}
|
||||
291
patches/chromium/cherry-pick-fe85e04a1797.patch
Normal file
291
patches/chromium/cherry-pick-fe85e04a1797.patch
Normal file
@@ -0,0 +1,291 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Rockot <rockot@google.com>
|
||||
Date: Wed, 31 Mar 2021 18:44:06 +0000
|
||||
Subject: Don't use BigBuffer for IPC::Message transport
|
||||
|
||||
M86 merge conflicts and resolution:
|
||||
* ipc/ipc_message_pipe_reader.cc
|
||||
Fixed extra include.
|
||||
|
||||
(cherry picked from commit 85bd7c88523545ab0e497d5e7b3e929793813358)
|
||||
|
||||
(cherry picked from commit fad3b9ffe7c7ff82909d911c573bd185aa3b3b50)
|
||||
|
||||
Fixed: 1184399
|
||||
Change-Id: Iddd91ae8d7ae63022b61c96239f5e39261dfb735
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2737012
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#860010}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2779918
|
||||
Auto-Submit: Ken Rockot <rockot@google.com>
|
||||
Reviewed-by: Adrian Taylor <adetaylor@chromium.org>
|
||||
Reviewed-by: Alex Gough <ajgo@chromium.org>
|
||||
Commit-Queue: Alex Gough <ajgo@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4389@{#1597}
|
||||
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2794488
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
|
||||
Reviewed-by: Ken Rockot <rockot@google.com>
|
||||
Auto-Submit: Artem Sumaneev <asumaneev@google.com>
|
||||
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1587}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/ipc/BUILD.gn b/ipc/BUILD.gn
|
||||
index 994d45e84502670f544742a3011a8f9381a711bc..281e84df83ae73e8c4716fda1624cb4065342c76 100644
|
||||
--- a/ipc/BUILD.gn
|
||||
+++ b/ipc/BUILD.gn
|
||||
@@ -187,10 +187,7 @@ mojom_component("mojom") {
|
||||
output_prefix = "ipc_mojom"
|
||||
macro_prefix = "IPC_MOJOM"
|
||||
sources = [ "ipc.mojom" ]
|
||||
- public_deps = [
|
||||
- "//mojo/public/interfaces/bindings",
|
||||
- "//mojo/public/mojom/base",
|
||||
- ]
|
||||
+ public_deps = [ "//mojo/public/interfaces/bindings" ]
|
||||
|
||||
cpp_typemaps = [
|
||||
{
|
||||
@@ -207,10 +204,7 @@ mojom_component("mojom") {
|
||||
"//ipc/message_view.cc",
|
||||
"//ipc/message_view.h",
|
||||
]
|
||||
- traits_public_deps = [
|
||||
- "//ipc:message_support",
|
||||
- "//mojo/public/cpp/base:shared_typemap_traits",
|
||||
- ]
|
||||
+ traits_public_deps = [ "//ipc:message_support" ]
|
||||
},
|
||||
]
|
||||
|
||||
diff --git a/ipc/ipc.mojom b/ipc/ipc.mojom
|
||||
index c66799642fbee2cef3449ff5d52cd5f187808cfe..4606022b28bca1df06ba6eb8eaac025573475b10 100644
|
||||
--- a/ipc/ipc.mojom
|
||||
+++ b/ipc/ipc.mojom
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
module IPC.mojom;
|
||||
|
||||
-import "mojo/public/mojom/base/big_buffer.mojom";
|
||||
import "mojo/public/interfaces/bindings/native_struct.mojom";
|
||||
|
||||
// A placeholder interface type since we don't yet support generic associated
|
||||
@@ -14,7 +13,7 @@ interface GenericInterface {};
|
||||
// Typemapped such that arbitrarily large IPC::Message objects can be sent and
|
||||
// received with minimal copying.
|
||||
struct Message {
|
||||
- mojo_base.mojom.BigBuffer buffer;
|
||||
+ array<uint8> bytes;
|
||||
array<mojo.native.SerializedHandle>? handles;
|
||||
};
|
||||
|
||||
@@ -24,6 +23,7 @@ interface Channel {
|
||||
SetPeerPid(int32 pid);
|
||||
|
||||
// Transmits a classical Chrome IPC message.
|
||||
+ [UnlimitedSize]
|
||||
Receive(Message message);
|
||||
|
||||
// Requests a Channel-associated interface.
|
||||
diff --git a/ipc/ipc_message_pipe_reader.cc b/ipc/ipc_message_pipe_reader.cc
|
||||
index bdc5dd680d0f9107719765334d0a1ea3e864e200..cbf0363a9d941db1ab34ae835e707b7825447659 100644
|
||||
--- a/ipc/ipc_message_pipe_reader.cc
|
||||
+++ b/ipc/ipc_message_pipe_reader.cc
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/bind_helpers.h"
|
||||
+#include "base/containers/span.h"
|
||||
#include "base/location.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/macros.h"
|
||||
@@ -62,7 +63,9 @@ bool MessagePipeReader::Send(std::unique_ptr<Message> message) {
|
||||
if (!sender_)
|
||||
return false;
|
||||
|
||||
- sender_->Receive(MessageView(*message, std::move(handles)));
|
||||
+ base::span<const uint8_t> bytes(static_cast<const uint8_t*>(message->data()),
|
||||
+ message->size());
|
||||
+ sender_->Receive(MessageView(bytes, std::move(handles)));
|
||||
DVLOG(4) << "Send " << message->type() << ": " << message->size();
|
||||
return true;
|
||||
}
|
||||
@@ -82,11 +85,12 @@ void MessagePipeReader::SetPeerPid(int32_t peer_pid) {
|
||||
}
|
||||
|
||||
void MessagePipeReader::Receive(MessageView message_view) {
|
||||
- if (!message_view.size()) {
|
||||
+ if (message_view.bytes().empty()) {
|
||||
delegate_->OnBrokenDataReceived();
|
||||
return;
|
||||
}
|
||||
- Message message(message_view.data(), message_view.size());
|
||||
+ Message message(reinterpret_cast<const char*>(message_view.bytes().data()),
|
||||
+ message_view.bytes().size());
|
||||
if (!message.IsValid()) {
|
||||
delegate_->OnBrokenDataReceived();
|
||||
return;
|
||||
diff --git a/ipc/ipc_mojo_bootstrap_unittest.cc b/ipc/ipc_mojo_bootstrap_unittest.cc
|
||||
index 47a7ad79a30165c76041075be10b9be8c13f5e75..b32941da752a54ba7317e439150982adbb9fbcad 100644
|
||||
--- a/ipc/ipc_mojo_bootstrap_unittest.cc
|
||||
+++ b/ipc/ipc_mojo_bootstrap_unittest.cc
|
||||
@@ -77,7 +77,9 @@ class PeerPidReceiver : public IPC::mojom::Channel {
|
||||
ASSERT_NE(MessageExpectation::kNotExpected, message_expectation_);
|
||||
received_message_ = true;
|
||||
|
||||
- IPC::Message message(message_view.data(), message_view.size());
|
||||
+ IPC::Message message(
|
||||
+ reinterpret_cast<const char*>(message_view.bytes().data()),
|
||||
+ message_view.bytes().size());
|
||||
bool expected_valid =
|
||||
message_expectation_ == MessageExpectation::kExpectedValid;
|
||||
EXPECT_EQ(expected_valid, message.IsValid());
|
||||
@@ -196,8 +198,7 @@ MULTIPROCESS_TEST_MAIN_WITH_SETUP(
|
||||
|
||||
uint8_t data = 0;
|
||||
sender->Receive(
|
||||
- IPC::MessageView(mojo_base::BigBufferView(base::make_span(&data, 0)),
|
||||
- base::nullopt /* handles */));
|
||||
+ IPC::MessageView(base::make_span(&data, 0), base::nullopt /* handles */));
|
||||
|
||||
base::RunLoop run_loop;
|
||||
PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure());
|
||||
diff --git a/ipc/message_mojom_traits.cc b/ipc/message_mojom_traits.cc
|
||||
index 4aab9248e9ff6ca8e2d7d085ae3e996ac04666e8..d8ad4a2f919b01362e3e2746bfb7f4fae77b059d 100644
|
||||
--- a/ipc/message_mojom_traits.cc
|
||||
+++ b/ipc/message_mojom_traits.cc
|
||||
@@ -4,15 +4,13 @@
|
||||
|
||||
#include "ipc/message_mojom_traits.h"
|
||||
|
||||
-#include "mojo/public/cpp/base/big_buffer_mojom_traits.h"
|
||||
-
|
||||
namespace mojo {
|
||||
|
||||
// static
|
||||
-mojo_base::BigBufferView
|
||||
-StructTraits<IPC::mojom::MessageDataView, IPC::MessageView>::buffer(
|
||||
+base::span<const uint8_t>
|
||||
+StructTraits<IPC::mojom::MessageDataView, IPC::MessageView>::bytes(
|
||||
IPC::MessageView& view) {
|
||||
- return view.TakeBufferView();
|
||||
+ return view.bytes();
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -26,14 +24,14 @@ StructTraits<IPC::mojom::MessageDataView, IPC::MessageView>::handles(
|
||||
bool StructTraits<IPC::mojom::MessageDataView, IPC::MessageView>::Read(
|
||||
IPC::mojom::MessageDataView data,
|
||||
IPC::MessageView* out) {
|
||||
- mojo_base::BigBufferView buffer_view;
|
||||
- if (!data.ReadBuffer(&buffer_view))
|
||||
- return false;
|
||||
+ mojo::ArrayDataView<uint8_t> bytes;
|
||||
+ data.GetBytesDataView(&bytes);
|
||||
+
|
||||
base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles;
|
||||
if (!data.ReadHandles(&handles))
|
||||
return false;
|
||||
|
||||
- *out = IPC::MessageView(std::move(buffer_view), std::move(handles));
|
||||
+ *out = IPC::MessageView(bytes, std::move(handles));
|
||||
return true;
|
||||
}
|
||||
|
||||
diff --git a/ipc/message_mojom_traits.h b/ipc/message_mojom_traits.h
|
||||
index 617ffbe37309946464e3f180a0ebde97f56dbd75..6b5064a12191e9a663519e7b5cb7c5f907a75054 100644
|
||||
--- a/ipc/message_mojom_traits.h
|
||||
+++ b/ipc/message_mojom_traits.h
|
||||
@@ -7,10 +7,10 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
+#include "base/containers/span.h"
|
||||
#include "base/optional.h"
|
||||
#include "ipc/ipc.mojom-shared.h"
|
||||
#include "ipc/message_view.h"
|
||||
-#include "mojo/public/cpp/base/big_buffer.h"
|
||||
#include "mojo/public/cpp/bindings/struct_traits.h"
|
||||
#include "mojo/public/interfaces/bindings/native_struct.mojom.h"
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace mojo {
|
||||
template <>
|
||||
class StructTraits<IPC::mojom::MessageDataView, IPC::MessageView> {
|
||||
public:
|
||||
- static mojo_base::BigBufferView buffer(IPC::MessageView& view);
|
||||
+ static base::span<const uint8_t> bytes(IPC::MessageView& view);
|
||||
static base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles(
|
||||
IPC::MessageView& view);
|
||||
|
||||
diff --git a/ipc/message_view.cc b/ipc/message_view.cc
|
||||
index 49a80878e7a92cda13105ea0f2fea36ad7ed05e6..39c6608dd507c3ca051b619d966ae521e95fe8e2 100644
|
||||
--- a/ipc/message_view.cc
|
||||
+++ b/ipc/message_view.cc
|
||||
@@ -11,16 +11,9 @@ namespace IPC {
|
||||
MessageView::MessageView() = default;
|
||||
|
||||
MessageView::MessageView(
|
||||
- const Message& message,
|
||||
+ base::span<const uint8_t> bytes,
|
||||
base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles)
|
||||
- : buffer_view_(base::make_span(static_cast<const uint8_t*>(message.data()),
|
||||
- message.size())),
|
||||
- handles_(std::move(handles)) {}
|
||||
-
|
||||
-MessageView::MessageView(
|
||||
- mojo_base::BigBufferView buffer_view,
|
||||
- base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles)
|
||||
- : buffer_view_(std::move(buffer_view)), handles_(std::move(handles)) {}
|
||||
+ : bytes_(bytes), handles_(std::move(handles)) {}
|
||||
|
||||
MessageView::MessageView(MessageView&&) = default;
|
||||
|
||||
diff --git a/ipc/message_view.h b/ipc/message_view.h
|
||||
index 4ec059bf3639b9c75178f2300d0796b433e1d2ed..c7801bb963f06b03c51ba87bffc307792b592dae 100644
|
||||
--- a/ipc/message_view.h
|
||||
+++ b/ipc/message_view.h
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "base/containers/span.h"
|
||||
#include "base/macros.h"
|
||||
#include "ipc/ipc_message.h"
|
||||
-#include "mojo/public/cpp/base/big_buffer.h"
|
||||
#include "mojo/public/interfaces/bindings/native_struct.mojom-forward.h"
|
||||
|
||||
namespace IPC {
|
||||
@@ -20,30 +19,18 @@ class COMPONENT_EXPORT(IPC_MOJOM) MessageView {
|
||||
public:
|
||||
MessageView();
|
||||
MessageView(
|
||||
- const Message& message,
|
||||
- base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles);
|
||||
- MessageView(
|
||||
- mojo_base::BigBufferView buffer_view,
|
||||
+ base::span<const uint8_t> bytes,
|
||||
base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles);
|
||||
MessageView(MessageView&&);
|
||||
~MessageView();
|
||||
|
||||
MessageView& operator=(MessageView&&);
|
||||
|
||||
- const char* data() const {
|
||||
- return reinterpret_cast<const char*>(buffer_view_.data().data());
|
||||
- }
|
||||
-
|
||||
- uint32_t size() const {
|
||||
- return static_cast<uint32_t>(buffer_view_.data().size());
|
||||
- }
|
||||
-
|
||||
- mojo_base::BigBufferView TakeBufferView() { return std::move(buffer_view_); }
|
||||
-
|
||||
+ base::span<const uint8_t> bytes() const { return bytes_; }
|
||||
base::Optional<std::vector<mojo::native::SerializedHandlePtr>> TakeHandles();
|
||||
|
||||
private:
|
||||
- mojo_base::BigBufferView buffer_view_;
|
||||
+ base::span<const uint8_t> bytes_;
|
||||
base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MessageView);
|
||||
@@ -0,0 +1,447 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Van Cleve <davidvc@chromium.org>
|
||||
Date: Thu, 4 Mar 2021 16:50:46 +0000
|
||||
Subject: css: Make fetches from inline CSS use the document's URL as referrer
|
||||
|
||||
Right now, fetches from inline CSS use the inline CSS's base URL
|
||||
instead of the URL from the context that embeds the inline CSS: for
|
||||
instance, loading a source-site.com page with the following code
|
||||
<base href="https://other-site.com">
|
||||
<style type=text/css> @import('best-sheet.com') </style>
|
||||
should lead to the best-sheet.com sheet getting fetched with a
|
||||
source-site.com referrer, but it will currently provide an
|
||||
other-site.com referrer. However, if the imported sheet from
|
||||
best-sheet.com makes more nested fetches, those nested requests should
|
||||
use best-sheet.com as the basis for their referrers (as they do
|
||||
currently).
|
||||
|
||||
This CL updates CSSParserContext's referrer setting logic to roughly do
|
||||
the following:
|
||||
- inline CSS: use the embedding document's URL as the referrer, or, for
|
||||
srcdoc iframes, walk up the frame tree until hitting a non-srcdoc frame
|
||||
- requests from fetched stylesheets: just as currently, use the fetched
|
||||
sheet's URL as the basis for constructing the referrer
|
||||
|
||||
This seemed like it required refactoring CSSParserContext slightly
|
||||
because there are constructors that take both a Document and a base URL,
|
||||
and it's not obvious from the constructor signature whether the
|
||||
Document or the base URL should be the one that provides the referrer.
|
||||
To resolve this ambiguity, the refactor updates these CSSParserContext
|
||||
constructors to take caller-provided Referrer objects.
|
||||
|
||||
(cherry picked from commit 0b1539fcb923056624d4adc84b88140d367d92da)
|
||||
|
||||
Change-Id: If5a99d8057dff5e771e821d0e1f605566e28ff1d
|
||||
Fixed: 1158645, 1158010
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2592447
|
||||
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
|
||||
Reviewed-by: Matt Falkenhagen <falken@chromium.org>
|
||||
Commit-Queue: David Van Cleve <davidvc@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#841509}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2731576
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1558}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.cc b/third_party/blink/renderer/core/css/css_style_sheet.cc
|
||||
index c168b0a244865e3c390989e3e5af275fdef2a4cd..10efc5bd894c16de745b7f4bb07268719f443e73 100644
|
||||
--- a/third_party/blink/renderer/core/css/css_style_sheet.cc
|
||||
+++ b/third_party/blink/renderer/core/css/css_style_sheet.cc
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "third_party/blink/renderer/core/dom/document.h"
|
||||
#include "third_party/blink/renderer/core/dom/node.h"
|
||||
#include "third_party/blink/renderer/core/frame/deprecation.h"
|
||||
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
|
||||
#include "third_party/blink/renderer/core/html/html_link_element.h"
|
||||
#include "third_party/blink/renderer/core/html/html_style_element.h"
|
||||
#include "third_party/blink/renderer/core/html_names.h"
|
||||
@@ -138,9 +139,15 @@ CSSStyleSheet* CSSStyleSheet::CreateInline(Node& owner_node,
|
||||
const KURL& base_url,
|
||||
const TextPosition& start_position,
|
||||
const WTF::TextEncoding& encoding) {
|
||||
+ Document& owner_node_document = owner_node.GetDocument();
|
||||
auto* parser_context = MakeGarbageCollected<CSSParserContext>(
|
||||
- owner_node.GetDocument(), owner_node.GetDocument().BaseURL(),
|
||||
- true /* origin_clean */, owner_node.GetDocument().GetReferrerPolicy(),
|
||||
+ owner_node_document, owner_node_document.BaseURL(),
|
||||
+ true /* origin_clean */,
|
||||
+ Referrer(
|
||||
+ owner_node_document.GetExecutionContext()
|
||||
+ ? owner_node_document.GetExecutionContext()->OutgoingReferrer()
|
||||
+ : String(), // GetExecutionContext() only returns null in tests.
|
||||
+ owner_node.GetDocument().GetReferrerPolicy()),
|
||||
encoding);
|
||||
if (AdTracker::IsAdScriptExecutingInDocument(&owner_node.GetDocument()))
|
||||
parser_context->SetIsAdRelated();
|
||||
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_context.cc b/third_party/blink/renderer/core/css/parser/css_parser_context.cc
|
||||
index 5c1292cf13b4265c3db36fd3c1a71a30b3c81c68..b636bd5388a871fd284a74b7926aeb5922e274e5 100644
|
||||
--- a/third_party/blink/renderer/core/css/parser/css_parser_context.cc
|
||||
+++ b/third_party/blink/renderer/core/css/parser/css_parser_context.cc
|
||||
@@ -53,27 +53,25 @@ CSSParserContext::CSSParserContext(const CSSParserContext* other,
|
||||
is_ad_related_ = other->is_ad_related_;
|
||||
}
|
||||
|
||||
-CSSParserContext::CSSParserContext(
|
||||
- const CSSParserContext* other,
|
||||
- const KURL& base_url,
|
||||
- bool origin_clean,
|
||||
- network::mojom::ReferrerPolicy referrer_policy,
|
||||
- const WTF::TextEncoding& charset,
|
||||
- const Document* use_counter_document)
|
||||
- : CSSParserContext(
|
||||
- base_url,
|
||||
- origin_clean,
|
||||
- charset,
|
||||
- other->mode_,
|
||||
- other->match_mode_,
|
||||
- other->profile_,
|
||||
- Referrer(base_url.StrippedForUseAsReferrer(), referrer_policy),
|
||||
- other->is_html_document_,
|
||||
- other->use_legacy_background_size_shorthand_behavior_,
|
||||
- other->secure_context_mode_,
|
||||
- other->should_check_content_security_policy_,
|
||||
- use_counter_document,
|
||||
- other->resource_fetch_restriction_) {
|
||||
+CSSParserContext::CSSParserContext(const CSSParserContext* other,
|
||||
+ const KURL& base_url,
|
||||
+ bool origin_clean,
|
||||
+ const Referrer& referrer,
|
||||
+ const WTF::TextEncoding& charset,
|
||||
+ const Document* use_counter_document)
|
||||
+ : CSSParserContext(base_url,
|
||||
+ origin_clean,
|
||||
+ charset,
|
||||
+ other->mode_,
|
||||
+ other->match_mode_,
|
||||
+ other->profile_,
|
||||
+ referrer,
|
||||
+ other->is_html_document_,
|
||||
+ other->use_legacy_background_size_shorthand_behavior_,
|
||||
+ other->secure_context_mode_,
|
||||
+ other->should_check_content_security_policy_,
|
||||
+ use_counter_document,
|
||||
+ other->resource_fetch_restriction_) {
|
||||
is_ad_related_ = other->is_ad_related_;
|
||||
}
|
||||
|
||||
@@ -96,18 +94,23 @@ CSSParserContext::CSSParserContext(CSSParserMode mode,
|
||||
ResourceFetchRestriction::kNone) {}
|
||||
|
||||
CSSParserContext::CSSParserContext(const Document& document)
|
||||
- : CSSParserContext(document,
|
||||
- document.BaseURL(),
|
||||
- true /* origin_clean */,
|
||||
- document.GetReferrerPolicy(),
|
||||
- WTF::TextEncoding(),
|
||||
- kLiveProfile) {}
|
||||
+ : CSSParserContext(
|
||||
+ document,
|
||||
+ document.BaseURL(),
|
||||
+ true /* origin_clean */,
|
||||
+ Referrer(document.GetExecutionContext()
|
||||
+ ? document.GetExecutionContext()->OutgoingReferrer()
|
||||
+ : String(), // GetExecutionContext() only returns null
|
||||
+ // in tests.
|
||||
+ document.GetReferrerPolicy()),
|
||||
+ WTF::TextEncoding(),
|
||||
+ kLiveProfile) {}
|
||||
|
||||
CSSParserContext::CSSParserContext(
|
||||
const Document& document,
|
||||
const KURL& base_url_override,
|
||||
bool origin_clean,
|
||||
- network::mojom::ReferrerPolicy referrer_policy_override,
|
||||
+ const Referrer& referrer,
|
||||
const WTF::TextEncoding& charset,
|
||||
SelectorProfile profile,
|
||||
enum ResourceFetchRestriction resource_fetch_restriction)
|
||||
@@ -122,8 +125,7 @@ CSSParserContext::CSSParserContext(
|
||||
: kHTMLStandardMode)
|
||||
: document.InQuirksMode() ? kHTMLQuirksMode : kHTMLStandardMode,
|
||||
profile,
|
||||
- Referrer(base_url_override.StrippedForUseAsReferrer(),
|
||||
- referrer_policy_override),
|
||||
+ referrer,
|
||||
IsA<HTMLDocument>(document),
|
||||
document.GetSettings()
|
||||
? document.GetSettings()
|
||||
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_context.h b/third_party/blink/renderer/core/css/parser/css_parser_context.h
|
||||
index 33b458f21910bcbfdb6956b02cd2ef56bb39778b..8d7ec9e6b7a14fffaaf72dcd0d2c0d0f062dbbfa 100644
|
||||
--- a/third_party/blink/renderer/core/css/parser/css_parser_context.h
|
||||
+++ b/third_party/blink/renderer/core/css/parser/css_parser_context.h
|
||||
@@ -40,10 +40,15 @@ class CORE_EXPORT CSSParserContext final
|
||||
explicit CSSParserContext(const CSSParserContext* other,
|
||||
const Document* use_counter_document = nullptr);
|
||||
|
||||
+ // Creates a context with most of its constructor attributes provided by
|
||||
+ // copying from |other|, except that the remaining constructor arguments take
|
||||
+ // precedence over the corresponding characteristics of |other|. This is
|
||||
+ // useful for initializing @imported sheets' contexts, which inherit most of
|
||||
+ // their characteristics from their parents.
|
||||
CSSParserContext(const CSSParserContext* other,
|
||||
const KURL& base_url_override,
|
||||
bool origin_clean,
|
||||
- network::mojom::ReferrerPolicy referrer_policy_override,
|
||||
+ const Referrer& referrer,
|
||||
const WTF::TextEncoding& charset_override,
|
||||
const Document* use_counter_document);
|
||||
CSSParserContext(CSSParserMode,
|
||||
@@ -54,7 +59,7 @@ class CORE_EXPORT CSSParserContext final
|
||||
CSSParserContext(const Document&,
|
||||
const KURL& base_url_override,
|
||||
bool origin_clean,
|
||||
- network::mojom::ReferrerPolicy referrer_policy_override,
|
||||
+ const Referrer& referrer,
|
||||
const WTF::TextEncoding& charset = WTF::TextEncoding(),
|
||||
SelectorProfile = kLiveProfile,
|
||||
ResourceFetchRestriction resource_fetch_restriction =
|
||||
@@ -69,7 +74,7 @@ class CORE_EXPORT CSSParserContext final
|
||||
CSSParserMode,
|
||||
CSSParserMode match_mode,
|
||||
SelectorProfile,
|
||||
- const Referrer&,
|
||||
+ const Referrer& referrer,
|
||||
bool is_html_document,
|
||||
bool use_legacy_background_size_shorthand_behavior,
|
||||
SecureContextMode,
|
||||
diff --git a/third_party/blink/renderer/core/css/selector_query.cc b/third_party/blink/renderer/core/css/selector_query.cc
|
||||
index 722b751f19207b070664d79c5a9cc758f1c044f4..35d9d926f2e1ac0c2d032817b87c1079af9408ec 100644
|
||||
--- a/third_party/blink/renderer/core/css/selector_query.cc
|
||||
+++ b/third_party/blink/renderer/core/css/selector_query.cc
|
||||
@@ -535,9 +535,8 @@ SelectorQuery* SelectorQueryCache::Add(const AtomicString& selectors,
|
||||
|
||||
CSSSelectorList selector_list = CSSParser::ParseSelector(
|
||||
MakeGarbageCollected<CSSParserContext>(
|
||||
- document, document.BaseURL(), true /* origin_clean */,
|
||||
- document.GetReferrerPolicy(), WTF::TextEncoding(),
|
||||
- CSSParserContext::kSnapshotProfile),
|
||||
+ document, document.BaseURL(), true /* origin_clean */, Referrer(),
|
||||
+ WTF::TextEncoding(), CSSParserContext::kSnapshotProfile),
|
||||
nullptr, selectors);
|
||||
|
||||
if (!selector_list.First()) {
|
||||
diff --git a/third_party/blink/renderer/core/css/selector_query_test.cc b/third_party/blink/renderer/core/css/selector_query_test.cc
|
||||
index 8d701d91372e5c2fb4b1a30f190f629f95e1b0b2..bf14850baf8dd2e92f74b89b78963a367440a704 100644
|
||||
--- a/third_party/blink/renderer/core/css/selector_query_test.cc
|
||||
+++ b/third_party/blink/renderer/core/css/selector_query_test.cc
|
||||
@@ -72,9 +72,8 @@ TEST(SelectorQueryTest, NotMatchingPseudoElement) {
|
||||
|
||||
CSSSelectorList selector_list = CSSParser::ParseSelector(
|
||||
MakeGarbageCollected<CSSParserContext>(
|
||||
- *document, NullURL(), true /* origin_clean */,
|
||||
- network::mojom::ReferrerPolicy::kDefault, WTF::TextEncoding(),
|
||||
- CSSParserContext::kSnapshotProfile),
|
||||
+ *document, NullURL(), true /* origin_clean */, Referrer(),
|
||||
+ WTF::TextEncoding(), CSSParserContext::kSnapshotProfile),
|
||||
nullptr, "span::before");
|
||||
std::unique_ptr<SelectorQuery> query =
|
||||
SelectorQuery::Adopt(std::move(selector_list));
|
||||
@@ -83,9 +82,8 @@ TEST(SelectorQueryTest, NotMatchingPseudoElement) {
|
||||
|
||||
selector_list = CSSParser::ParseSelector(
|
||||
MakeGarbageCollected<CSSParserContext>(
|
||||
- *document, NullURL(), true /* origin_clean */,
|
||||
- network::mojom::ReferrerPolicy::kDefault, WTF::TextEncoding(),
|
||||
- CSSParserContext::kSnapshotProfile),
|
||||
+ *document, NullURL(), true /* origin_clean */, Referrer(),
|
||||
+ WTF::TextEncoding(), CSSParserContext::kSnapshotProfile),
|
||||
nullptr, "span");
|
||||
query = SelectorQuery::Adopt(std::move(selector_list));
|
||||
elm = query->QueryFirst(*document);
|
||||
@@ -103,9 +101,8 @@ TEST(SelectorQueryTest, LastOfTypeNotFinishedParsing) {
|
||||
|
||||
CSSSelectorList selector_list = CSSParser::ParseSelector(
|
||||
MakeGarbageCollected<CSSParserContext>(
|
||||
- *document, NullURL(), true /* origin_clean */,
|
||||
- network::mojom::ReferrerPolicy::kDefault, WTF::TextEncoding(),
|
||||
- CSSParserContext::kSnapshotProfile),
|
||||
+ *document, NullURL(), true /* origin_clean */, Referrer(),
|
||||
+ WTF::TextEncoding(), CSSParserContext::kSnapshotProfile),
|
||||
nullptr, "p:last-of-type");
|
||||
std::unique_ptr<SelectorQuery> query =
|
||||
SelectorQuery::Adopt(std::move(selector_list));
|
||||
diff --git a/third_party/blink/renderer/core/css/style_rule_import.cc b/third_party/blink/renderer/core/css/style_rule_import.cc
|
||||
index 447d130a9c29a698c81c0436b318058172b3a7ef..857fb15c74063613d467c29829eda0a8ea18b9bb 100644
|
||||
--- a/third_party/blink/renderer/core/css/style_rule_import.cc
|
||||
+++ b/third_party/blink/renderer/core/css/style_rule_import.cc
|
||||
@@ -83,8 +83,9 @@ void StyleRuleImport::NotifyFinished(Resource* resource) {
|
||||
CSSParserContext* context = MakeGarbageCollected<CSSParserContext>(
|
||||
parent_context, cached_style_sheet->GetResponse().ResponseUrl(),
|
||||
cached_style_sheet->GetResponse().IsCorsSameOrigin(),
|
||||
- cached_style_sheet->GetReferrerPolicy(), cached_style_sheet->Encoding(),
|
||||
- document);
|
||||
+ Referrer(cached_style_sheet->GetResponse().ResponseUrl(),
|
||||
+ cached_style_sheet->GetReferrerPolicy()),
|
||||
+ cached_style_sheet->Encoding(), document);
|
||||
if (cached_style_sheet->GetResourceRequest().IsAdResource())
|
||||
context->SetIsAdRelated();
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/dom/processing_instruction.cc b/third_party/blink/renderer/core/dom/processing_instruction.cc
|
||||
index 739226d95f964ebf4ae35983c6e1cd5faa01b324..1a1ead65c7642350f7d13364046f665c021bc3b0 100644
|
||||
--- a/third_party/blink/renderer/core/dom/processing_instruction.cc
|
||||
+++ b/third_party/blink/renderer/core/dom/processing_instruction.cc
|
||||
@@ -206,7 +206,9 @@ void ProcessingInstruction::NotifyFinished(Resource* resource) {
|
||||
auto* parser_context = MakeGarbageCollected<CSSParserContext>(
|
||||
GetDocument(), style_resource->GetResponse().ResponseUrl(),
|
||||
style_resource->GetResponse().IsCorsSameOrigin(),
|
||||
- style_resource->GetReferrerPolicy(), style_resource->Encoding());
|
||||
+ Referrer(style_resource->GetResponse().ResponseUrl(),
|
||||
+ style_resource->GetReferrerPolicy()),
|
||||
+ style_resource->Encoding());
|
||||
if (style_resource->GetResourceRequest().IsAdResource())
|
||||
parser_context->SetIsAdRelated();
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/html/link_style.cc b/third_party/blink/renderer/core/html/link_style.cc
|
||||
index 5036ac1f0cb9613772c704a6dc5c5e2496ab5567..5e3b7e361ae1ebe2ff89f10448eac4fe33352031 100644
|
||||
--- a/third_party/blink/renderer/core/html/link_style.cc
|
||||
+++ b/third_party/blink/renderer/core/html/link_style.cc
|
||||
@@ -88,7 +88,9 @@ void LinkStyle::NotifyFinished(Resource* resource) {
|
||||
auto* parser_context = MakeGarbageCollected<CSSParserContext>(
|
||||
GetDocument(), cached_style_sheet->GetResponse().ResponseUrl(),
|
||||
cached_style_sheet->GetResponse().IsCorsSameOrigin(),
|
||||
- cached_style_sheet->GetReferrerPolicy(), cached_style_sheet->Encoding());
|
||||
+ Referrer(cached_style_sheet->GetResponse().ResponseUrl(),
|
||||
+ cached_style_sheet->GetReferrerPolicy()),
|
||||
+ cached_style_sheet->Encoding());
|
||||
if (cached_style_sheet->GetResourceRequest().IsAdResource()) {
|
||||
parser_context->SetIsAdRelated();
|
||||
}
|
||||
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
|
||||
index 0b6e9b6b8b66029f46ca79f24a2519f13e611005..e492003c470af4c7b96551f6dfee79d26f8b7c77 100644
|
||||
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
|
||||
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
|
||||
@@ -244,9 +244,8 @@ VTTParser::ParseState VTTParser::CollectRegionSettings(const String& line) {
|
||||
VTTParser::ParseState VTTParser::CollectStyleSheet(const String& line) {
|
||||
if (line.IsEmpty() || line.Contains("-->")) {
|
||||
auto* parser_context = MakeGarbageCollected<CSSParserContext>(
|
||||
- *document_, NullURL(), true /* origin_clean */,
|
||||
- document_->GetReferrerPolicy(), UTF8Encoding(),
|
||||
- CSSParserContext::kLiveProfile,
|
||||
+ *document_, NullURL(), true /* origin_clean */, Referrer(),
|
||||
+ UTF8Encoding(), CSSParserContext::kLiveProfile,
|
||||
ResourceFetchRestriction::kOnlyDataUrls);
|
||||
auto* style_sheet_contents =
|
||||
MakeGarbageCollected<StyleSheetContents>(parser_context);
|
||||
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
|
||||
index acf5033054cecc1099068e2452cfbef8f1ffbd95..0e9ac683c48befe5f3e740e0632bf93e7569c686 100644
|
||||
--- a/third_party/blink/web_tests/TestExpectations
|
||||
+++ b/third_party/blink/web_tests/TestExpectations
|
||||
@@ -3245,6 +3245,7 @@ virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-restartIce-onneg
|
||||
# See also crbug.com/920100 (sheriff 2019-01-09).
|
||||
crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout Failure ]
|
||||
crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout Failure ]
|
||||
+crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/inline-style-with-differentorigin-base-tag.tentative.html [ Timeout Failure ]
|
||||
crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout Failure ]
|
||||
crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout Failure ]
|
||||
crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/processing-instruction.html [ Timeout Failure ]
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/referrer-policy/css-integration/image/inline-style-with-differentorigin-base-tag.tentative.html b/third_party/blink/web_tests/external/wpt/referrer-policy/css-integration/image/inline-style-with-differentorigin-base-tag.tentative.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..091afd832ab35a76136b4242df1c1ec73aee109d
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/referrer-policy/css-integration/image/inline-style-with-differentorigin-base-tag.tentative.html
|
||||
@@ -0,0 +1,45 @@
|
||||
+<!DOCTYPE html>
|
||||
+<title>CSS integration - image from inline style from document with base tag</title>
|
||||
+<link rel="help" href="https://crbug.com/1158645" />
|
||||
+
|
||||
+<head>
|
||||
+ <meta name="referrer" content="origin">
|
||||
+</head>
|
||||
+
|
||||
+<script src="/resources/testharness.js"></script>
|
||||
+<script src="/resources/testharnessreport.js"></script>
|
||||
+<script src="/common/utils.js"></script>
|
||||
+<!-- Common global functions for referrer-policy tests. -->
|
||||
+<script src="/common/security-features/resources/common.sub.js"></script>
|
||||
+
|
||||
+<!-- This has to follow the <script> tags, or it will make the js files fail to load. -->
|
||||
+<base href="http://other-site.example" />
|
||||
+
|
||||
+<p>Check that resources from inline styles are loaded with
|
||||
+ the referrer and referrer policy from the document and, in
|
||||
+ particular, not with the different base URL set in the base tag.</p>
|
||||
+
|
||||
+<div class="styled"></div>
|
||||
+
|
||||
+<script>
|
||||
+ 'use strict';
|
||||
+ promise_test(function(css_test) {
|
||||
+ var id = token();
|
||||
+ var css_url = location.protocol + "//www1." + location.hostname + ":" + location.port + "/common/security-features/subresource/image.py" + "?id=" + id;
|
||||
+ var img_url = css_url + "&report-headers";
|
||||
+
|
||||
+ var div = document.querySelector("div.styled");
|
||||
+ div.style = "content:url(" + css_url + ")";
|
||||
+ return timeoutPromise(css_test, 1000)
|
||||
+ .then(() => requestViaXhr(img_url))
|
||||
+ .then(function(message) {
|
||||
+ assert_own_property(message, "headers");
|
||||
+ assert_own_property(message, "referrer");
|
||||
+ assert_equals(message.referrer, location.origin + "/");
|
||||
+ });
|
||||
+ }, "Image from inline styles.");
|
||||
+</script>
|
||||
+
|
||||
+<div id="log"></div>
|
||||
+
|
||||
+</html>
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/referrer-policy/css-integration/svg/inline-style-with-differentorigin-base-tag.tentative.html b/third_party/blink/web_tests/external/wpt/referrer-policy/css-integration/svg/inline-style-with-differentorigin-base-tag.tentative.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9a8bc6da418bc7302138daba8cf06cb449bd2dfe
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/referrer-policy/css-integration/svg/inline-style-with-differentorigin-base-tag.tentative.html
|
||||
@@ -0,0 +1,40 @@
|
||||
+<!DOCTYPE html>
|
||||
+<html>
|
||||
+
|
||||
+<head>
|
||||
+ <title>CSS integration - styling SVG from inline style on page with different-origin base tag</title>
|
||||
+ <script src="/resources/testharness.js"></script>
|
||||
+ <script src="/resources/testharnessreport.js"></script>
|
||||
+ <script src="/common/utils.js"></script>
|
||||
+ <!-- Common global functions for referrer-policy tests. -->
|
||||
+ <script src="/common/security-features/resources/common.sub.js"></script>
|
||||
+ <!-- Helper functions for referrer-policy css tests. -->
|
||||
+ <script src="/referrer-policy/css-integration/css-test-helper.js"></script>
|
||||
+ <meta name="referrer" content="origin">
|
||||
+</head>
|
||||
+
|
||||
+<base href="http://other-page.example/" />
|
||||
+
|
||||
+<body>
|
||||
+ <p>Check that resources from inline styles are loaded with
|
||||
+ the referrer and referrer policy from the document and, in
|
||||
+ particular, not from the document's overridden base URL.</p>
|
||||
+ <script>
|
||||
+ function setInlineStyle(test) {
|
||||
+ test.expected = location.origin + "/";
|
||||
+ let svg = createSvg();
|
||||
+ document.body.appendChild(svg);
|
||||
+ let element = svg.getElementsByTagName('path')[0];
|
||||
+ element.style = test.property + ": url(" + url_prefix + "svg.py?id=" +
|
||||
+ test.id + "#invalidFragment);";
|
||||
+ }
|
||||
+
|
||||
+ runSvgTests(svg_test_properties,
|
||||
+ "Styling SVG from inline styles",
|
||||
+ setInlineStyle);
|
||||
+ </script>
|
||||
+
|
||||
+ <div id="log"></div>
|
||||
+</body>
|
||||
+
|
||||
+</html>
|
||||
diff --git a/third_party/blink/web_tests/http/tests/css/resources/referrer-check.php b/third_party/blink/web_tests/http/tests/css/resources/referrer-check.php
|
||||
index 69483e01544c842f56a51d00d1b2ee5dc24b4162..7a517de692f418c3c8b365d0f7aefb9e585c9da0 100644
|
||||
--- a/third_party/blink/web_tests/http/tests/css/resources/referrer-check.php
|
||||
+++ b/third_party/blink/web_tests/http/tests/css/resources/referrer-check.php
|
||||
@@ -31,7 +31,7 @@ $expectedReferrerPaths = array(
|
||||
"document" => "/css/css-resources-referrer.html",
|
||||
"sheet" => "/css/resources/css-resources-referrer.css",
|
||||
"importedSheet" => "/css/resources/css-resources-referrer-import.css",
|
||||
- "iframe" => "/from/iframe.html"
|
||||
+ "iframe" => "/css/css-resources-referrer-srcdoc.html"
|
||||
);
|
||||
|
||||
$from = $_GET["from"];
|
||||
@@ -0,0 +1,73 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kai Ninomiya <kainino@chromium.org>
|
||||
Date: Thu, 11 Feb 2021 02:24:04 +0000
|
||||
Subject: Disable GPU acceleration on all Mesa software rasterizers
|
||||
|
||||
The previous entry only disabled acceleration on swrast, but softpipe
|
||||
and llvmpipe shouldn't be used for "GPU" acceleration either.
|
||||
This should apply to Linux but not ChromeOS, AFAICT.
|
||||
|
||||
This only improves an existing software rendering list entry, but here
|
||||
is the rationale: We prefer to rely on our own (domain specific, so more
|
||||
efficient) software paths, at least for everything other than WebGL. And
|
||||
for WebGL, SwiftShader avoids unknown factors like
|
||||
llvmpipe/softpipe/swrast.
|
||||
|
||||
If you are running a Mesa GL driver (not e.g. NVIDIA) then you can force
|
||||
these configurations with:
|
||||
- LIBGL_ALWAYS_SOFTWARE=1
|
||||
https://docs.mesa3d.org/envvars.html#libgl-environment-variables:~:text=LIBGL_ALWAYS_SOFTWARE
|
||||
- GALLIUM_DRIVER=llvmpipe, softpipe, or swr (though swr didn't work for me)
|
||||
https://docs.mesa3d.org/envvars.html#gallium-environment-variables:~:text=GALLIUM_DRIVER
|
||||
|
||||
The GL_RENDERER strings are:
|
||||
- swrast: "Software Rasterizer" (couldn't test this locally; found this online)
|
||||
- softpipe: "softpipe" (on one machine)
|
||||
- llvmpipe: "llvmpipe (LLVM 10.0.0, 256 bits)" (on one machine)
|
||||
|
||||
Drive-by updates the description of another item to be more accurate
|
||||
(SVGA3D is virtualized over hardware; it's not a software renderer).
|
||||
|
||||
# Unrelated CQ failures on branch
|
||||
(cherry picked from commit 7c7eccfc85e387a0dcd154a2a9c2389177982837)
|
||||
|
||||
No-Try: True
|
||||
Bug: 1155974
|
||||
Change-Id: I0571c1a1bf526260f7ea6cd53f88eec768973b13
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2645491
|
||||
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
|
||||
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
|
||||
Auto-Submit: Kai Ninomiya <kainino@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#846422}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2651183
|
||||
Reviewed-by: Kenneth Russell <kbr@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4324@{#2176}
|
||||
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
|
||||
diff --git a/gpu/config/software_rendering_list.json b/gpu/config/software_rendering_list.json
|
||||
index 5b5c542dbc95e49f9f0e5330f99b94ab4ea72321..dd87f7c0cc928bd330ac156bce9391a36bca2db0 100644
|
||||
--- a/gpu/config/software_rendering_list.json
|
||||
+++ b/gpu/config/software_rendering_list.json
|
||||
@@ -21,11 +21,11 @@
|
||||
{
|
||||
"id": 3,
|
||||
"description": "GL driver is software rendered. GPU acceleration is disabled",
|
||||
- "cr_bugs": [59302, 315217],
|
||||
+ "cr_bugs": [59302, 315217, 1155974],
|
||||
"os": {
|
||||
"type": "linux"
|
||||
},
|
||||
- "gl_renderer": "(?i).*software.*",
|
||||
+ "gl_renderer": "(?i).*(software|llvmpipe|softpipe).*",
|
||||
"features": [
|
||||
"all"
|
||||
]
|
||||
@@ -353,7 +353,7 @@
|
||||
},
|
||||
{
|
||||
"id": 50,
|
||||
- "description": "Disable VMware software renderer on older Mesa",
|
||||
+ "description": "Disable VMware virtualized renderer on older Mesa",
|
||||
"cr_bugs": [145531, 332596, 571899, 629434],
|
||||
"os": {
|
||||
"type": "linux"
|
||||
@@ -0,0 +1,72 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nathan Zabriskie <nazabris@microsoft.com>
|
||||
Date: Fri, 5 Feb 2021 20:44:16 +0000
|
||||
Subject: Fix heap overflow in VideoFrameYUVConverter
|
||||
|
||||
Currently with some texture sizes GLES2Util::ComputeImageDataSizesES3
|
||||
will attempt to add row padding when calculating the size of a
|
||||
VideoFrame plane. This is because it's currently assumed that each row
|
||||
aligns on a 4 byte boundary based on GL_UNPACK_ALIGNMENT but
|
||||
VideoFrames make no such guarantee as they may be densely packed.
|
||||
This CL removes the GL_UNPACK_ALIGNMENT assumption so that we only use
|
||||
the VideoFrame's stride when calculating padding.
|
||||
|
||||
(cherry picked from commit 7de5d0ecb5a4f73aeffe15d825bf694d0d8e2a08)
|
||||
|
||||
Bug: 1166504, 1161131
|
||||
Change-Id: I2484f5dfd2ad85b088fee57758776a5c9bd01d95
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2642765
|
||||
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
|
||||
Commit-Queue: Nathan Zabriskie <nazabris@microsoft.com>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#846298}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2679121
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Auto-Submit: Nathan Zabriskie <nazabris@microsoft.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4324@{#2115}
|
||||
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
|
||||
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
|
||||
index 49d050e7e0d8efabeb7cf1ed46041931394d43b4..4e5f869203d6b99b3368d3264830799d2d62006b 100644
|
||||
--- a/gpu/command_buffer/client/gles2_implementation.cc
|
||||
+++ b/gpu/command_buffer/client/gles2_implementation.cc
|
||||
@@ -840,7 +840,9 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) {
|
||||
case GL_GPU_DISJOINT_EXT:
|
||||
*params = static_cast<GLint>(query_tracker_->CheckAndResetDisjoint());
|
||||
return true;
|
||||
-
|
||||
+ case GL_UNPACK_ALIGNMENT:
|
||||
+ *params = unpack_alignment_;
|
||||
+ return true;
|
||||
case GL_VIEWPORT:
|
||||
if (state_.viewport_width > 0 && state_.viewport_height > 0 &&
|
||||
capabilities_.max_viewport_width > 0 &&
|
||||
@@ -922,7 +924,6 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) {
|
||||
case GL_STENCIL_VALUE_MASK:
|
||||
case GL_STENCIL_WRITEMASK:
|
||||
case GL_SUBPIXEL_BITS:
|
||||
- case GL_UNPACK_ALIGNMENT:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
diff --git a/gpu/command_buffer/client/raster_implementation_gles.cc b/gpu/command_buffer/client/raster_implementation_gles.cc
|
||||
index 299dd4f9874bf7f68563d524167db7180a200e14..f7d794ffbca21b055a9be91fa4b77be79896a730 100644
|
||||
--- a/gpu/command_buffer/client/raster_implementation_gles.cc
|
||||
+++ b/gpu/command_buffer/client/raster_implementation_gles.cc
|
||||
@@ -178,6 +178,9 @@ void RasterImplementationGLES::WritePixels(const gpu::Mailbox& dest_mailbox,
|
||||
BeginSharedImageAccessDirectCHROMIUM(
|
||||
texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
|
||||
|
||||
+ GLint old_align = 0;
|
||||
+ gl_->GetIntegerv(GL_UNPACK_ALIGNMENT, &old_align);
|
||||
+ gl_->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
gl_->PixelStorei(GL_UNPACK_ROW_LENGTH, row_bytes / src_info.bytesPerPixel());
|
||||
gl_->BindTexture(texture_target, texture_id);
|
||||
gl_->TexSubImage2D(texture_target, 0, dst_x_offset, dst_y_offset,
|
||||
@@ -186,6 +189,7 @@ void RasterImplementationGLES::WritePixels(const gpu::Mailbox& dest_mailbox,
|
||||
SkColorTypeToGLDataType(src_info.colorType()), src_pixels);
|
||||
gl_->BindTexture(texture_target, 0);
|
||||
gl_->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
+ gl_->PixelStorei(GL_UNPACK_ALIGNMENT, old_align);
|
||||
|
||||
EndSharedImageAccessDirectCHROMIUM(texture_id);
|
||||
DeleteGpuRasterTexture(texture_id);
|
||||
28
patches/chromium/fix_setparentacessibile_crash_win.patch
Normal file
28
patches/chromium/fix_setparentacessibile_crash_win.patch
Normal file
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Biru Mohanathas <birunthan@mohanathas.com>
|
||||
Date: Thu, 10 Dec 2020 19:02:37 +0200
|
||||
Subject: fix crash in NativeViewHost::SetParentAccessible
|
||||
|
||||
This fixes random crashes on Windows 10. It presumably started happening
|
||||
after the changes in
|
||||
https://chromium.googlesource.com/chromium/src.git/+/5c6c8e994bce2bfb867279ae5068e9f9134e70c3%5E!/#F15
|
||||
|
||||
For context, see: https://github.com/electron/electron/issues/26905
|
||||
|
||||
This patch can likely be upstreamed. The crash cannot be fixed without
|
||||
patching something in Chromium - this is the least invasive change.
|
||||
|
||||
diff --git a/ui/views/controls/native/native_view_host.cc b/ui/views/controls/native/native_view_host.cc
|
||||
index 4779e4f07d923b5af9ba05c2765cf294e75dcc14..6112217d532251f7f6850c23be5c312a908df1e2 100644
|
||||
--- a/ui/views/controls/native/native_view_host.cc
|
||||
+++ b/ui/views/controls/native/native_view_host.cc
|
||||
@@ -54,6 +54,9 @@ void NativeViewHost::Detach() {
|
||||
}
|
||||
|
||||
void NativeViewHost::SetParentAccessible(gfx::NativeViewAccessible accessible) {
|
||||
+ if (!native_wrapper_.get())
|
||||
+ return;
|
||||
+
|
||||
native_wrapper_->SetParentAccessible(accessible);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Tamura <tkent@chromium.org>
|
||||
Date: Mon, 14 Dec 2020 17:37:14 +0000
|
||||
Subject: LayoutNG: Fix an incorrect cache-hit for line boxes
|
||||
|
||||
If an IFC contains an item for an orthogonal writing-mode root,
|
||||
NGFragmentItems::DirtyLinesFromNeedsLayout() failed to mark it as dirty
|
||||
because NeedsLayout flag for the item was already cleared in the
|
||||
ComputeMinMaxSizes() step.
|
||||
|
||||
This CL avoids this issue by assuming orthogonal writing-mode roots
|
||||
dirty regardless of NeedsLayout flag.
|
||||
|
||||
(cherry picked from commit 21976a78429ccd8325acb00b41b4120271580bfb)
|
||||
|
||||
Bug: 1125870, 1147357
|
||||
Change-Id: I603bdd76f9015fbcde46da8e09fb6757b4b0222b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2544326
|
||||
Reviewed-by: Koji Ishii <kojii@chromium.org>
|
||||
Commit-Queue: Kent Tamura <tkent@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#828237}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2584928
|
||||
Reviewed-by: Kent Tamura <tkent@chromium.org>
|
||||
Commit-Queue: Koji Ishii <kojii@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1483}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
|
||||
index cdd49a53f8138572d746d87ba7116880eca850ef..b6915f3501150bc2d4fca79c21fb358d01f9f88e 100644
|
||||
--- a/third_party/blink/renderer/core/BUILD.gn
|
||||
+++ b/third_party/blink/renderer/core/BUILD.gn
|
||||
@@ -1235,6 +1235,7 @@ jumbo_source_set("unit_tests") {
|
||||
"layout/ng/inline/ng_bidi_paragraph_test.cc",
|
||||
"layout/ng/inline/ng_caret_position_test.cc",
|
||||
"layout/ng/inline/ng_fragment_item_test.cc",
|
||||
+ "layout/ng/inline/ng_fragment_items_test.cc",
|
||||
"layout/ng/inline/ng_inline_cursor_test.cc",
|
||||
"layout/ng/inline/ng_inline_fragment_traversal_test.cc",
|
||||
"layout/ng/inline/ng_inline_items_builder_test.cc",
|
||||
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
|
||||
index cfe1900729d4dacc5dad8d94f39b8f80114f6104..de2bc38dc0fe41ef16340642a60208e327173fe2 100644
|
||||
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
|
||||
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
|
||||
@@ -249,9 +249,15 @@ void NGFragmentItems::DirtyLinesFromNeedsLayout(
|
||||
// opportunities. Doing this complicates the logic, especially when culled
|
||||
// inline is involved, and common case is to append to large IFC. Choose
|
||||
// simpler logic and faster to check over more reuse opportunities.
|
||||
+ const auto writing_mode = container->StyleRef().GetWritingMode();
|
||||
for (LayoutObject* child = container->FirstChild(); child;
|
||||
child = child->NextSibling()) {
|
||||
- if (child->NeedsLayout()) {
|
||||
+ // NeedsLayout is not helpful for an orthogonal writing-mode root because
|
||||
+ // its NeedsLayout flag is cleared during the ComputeMinMaxSizes() step of
|
||||
+ // the container.
|
||||
+ if (child->NeedsLayout() ||
|
||||
+ !IsParallelWritingMode(writing_mode,
|
||||
+ child->StyleRef().GetWritingMode())) {
|
||||
DirtyLinesFromChangedChild(child);
|
||||
return;
|
||||
}
|
||||
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_test.cc
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0a36ada712c0bbc9afe0edad70dfb68c5028d84e
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_test.cc
|
||||
@@ -0,0 +1,43 @@
|
||||
+// Copyright 2020 The Chromium Authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+#include "testing/gtest/include/gtest/gtest.h"
|
||||
+#include "third_party/blink/renderer/core/layout/ng/ng_layout_test.h"
|
||||
+
|
||||
+namespace blink {
|
||||
+
|
||||
+class NGFragmentItemsTest : public NGLayoutTest {};
|
||||
+
|
||||
+// crbug.com/1147357
|
||||
+// DirtyLinesFromNeedsLayout() didn't work well with an orthogonal writing-mode
|
||||
+// root as a child, and it caused a failure of OOF descendants propagation.
|
||||
+TEST_F(NGFragmentItemsTest,
|
||||
+ DirtyLinesFromNeedsLayoutWithOrthogonalWritingMode) {
|
||||
+ SetBodyInnerHTML(R"HTML(
|
||||
+<style>
|
||||
+button {
|
||||
+ font-size: 100px;
|
||||
+}
|
||||
+#span1 {
|
||||
+ position: absolute;
|
||||
+}
|
||||
+code {
|
||||
+ writing-mode: vertical-rl;
|
||||
+}
|
||||
+</style>
|
||||
+<rt id="rt1"><span id="span1"></span></rt>
|
||||
+<button>
|
||||
+<code><ruby id="ruby1"></ruby></code>
|
||||
+b AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
+</button>)HTML");
|
||||
+ RunDocumentLifecycle();
|
||||
+
|
||||
+ GetDocument().getElementById("ruby1")->appendChild(
|
||||
+ GetDocument().getElementById("rt1"));
|
||||
+ RunDocumentLifecycle();
|
||||
+
|
||||
+ EXPECT_TRUE(GetLayoutObjectByElementId("span1")->EverHadLayout());
|
||||
+}
|
||||
+
|
||||
+} // namespace blink
|
||||
@@ -0,0 +1,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lan Wei <lanwei@chromium.org>
|
||||
Date: Tue, 20 Apr 2021 17:08:53 +0000
|
||||
Subject: M86-LTS: Add null pointer check in RenderWidgetHostInputEventRouter
|
||||
|
||||
We have some crashes in RenderWidgetHostInputEventRouter class, we are
|
||||
adding some null pointer check in this class to avoid the crash.
|
||||
|
||||
(cherry picked from commit 5f47666b79ac7ded20e1c7657037498561bd3352)
|
||||
|
||||
Bug: 1155297
|
||||
Change-Id: I3b63d5748523ae2ce8ab469832adfc75d586e411
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2818680
|
||||
Reviewed-by: Charlie Reis <creis@chromium.org>
|
||||
Commit-Queue: Lan Wei <lanwei@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#871108}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2838329
|
||||
Reviewed-by: Lan Wei <lanwei@chromium.org>
|
||||
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1617}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
|
||||
index f45da60a8f8cdeb6406e123554c05c4f399b0433..d88d28c2d4b09a00a9a42b59acad898d6516c158 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
|
||||
@@ -1949,7 +1949,7 @@ void RenderWidgetHostInputEventRouter::OnAggregatedHitTestRegionListUpdated(
|
||||
const std::vector<viz::AggregatedHitTestRegion>& hit_test_data) {
|
||||
for (auto& region : hit_test_data) {
|
||||
auto iter = owner_map_.find(region.frame_sink_id);
|
||||
- if (iter != owner_map_.end())
|
||||
+ if (iter != owner_map_.end() && iter->second)
|
||||
iter->second->NotifyHitTestRegionUpdated(region);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lan Wei <lanwei@chromium.org>
|
||||
Date: Tue, 20 Apr 2021 16:32:33 +0000
|
||||
Subject: M86-LTS: Add weak pointer to RWHIER::FrameSinkIdOwnerMap and
|
||||
RWHIER::TargetMap
|
||||
|
||||
In RWHIER::FrameSinkIdOwnerMap and RWHIER::TargetMap, we change raw
|
||||
pointer of RenderWidgetHostViewBase to weak pointer, such as
|
||||
using FrameSinkIdOwnerMap = std::unordered_map<viz::FrameSinkId,
|
||||
base::WeakPtr<RenderWidgetHostViewBase>,
|
||||
viz::FrameSinkIdHash>;
|
||||
using TargetMap = std::map<uint32_t,
|
||||
base::WeakPtr<RenderWidgetHostViewBase>>;
|
||||
|
||||
This CL should fix the crash of stale pointer.
|
||||
|
||||
(cherry picked from commit 3e3e3cf7036d7e33a4d68b8416ae25730f9eee1d)
|
||||
|
||||
Bug: 1155297
|
||||
Change-Id: I5b3270882ef06ae48c86bd460261723c7113953d
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2792344
|
||||
Reviewed-by: James MacLean <wjmaclean@chromium.org>
|
||||
Reviewed-by: Aaron Colwell <acolwell@chromium.org>
|
||||
Commit-Queue: Lan Wei <lanwei@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#870013}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2838587
|
||||
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Auto-Submit: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Reviewed-by: Lan Wei <lanwei@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1616}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
|
||||
index d88d28c2d4b09a00a9a42b59acad898d6516c158..0a19dfd63474bcc7da579bee850f92f642d525c7 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
|
||||
@@ -345,7 +345,7 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
|
||||
|
||||
// Remove this view from the owner_map.
|
||||
for (auto entry : owner_map_) {
|
||||
- if (entry.second == view) {
|
||||
+ if (entry.second.get() == view) {
|
||||
owner_map_.erase(entry.first);
|
||||
// There will only be one instance of a particular view in the map.
|
||||
break;
|
||||
@@ -368,7 +368,7 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
|
||||
// replace it with nullptr so that we maintain the 1:1 correspondence between
|
||||
// map entries and the touch sequences that underly them.
|
||||
for (auto it : touchscreen_gesture_target_map_) {
|
||||
- if (it.second == view)
|
||||
+ if (it.second.get() == view)
|
||||
it.second = nullptr;
|
||||
}
|
||||
|
||||
@@ -417,8 +417,10 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
|
||||
void RenderWidgetHostInputEventRouter::ClearAllObserverRegistrations() {
|
||||
// Since we're shutting down, it's safe to call RenderWidgetHostViewBase::
|
||||
// RemoveObserver() directly here.
|
||||
- for (auto entry : owner_map_)
|
||||
- entry.second->RemoveObserver(this);
|
||||
+ for (auto entry : owner_map_) {
|
||||
+ if (entry.second)
|
||||
+ entry.second->RemoveObserver(this);
|
||||
+ }
|
||||
owner_map_.clear();
|
||||
viz::HostFrameSinkManager* manager = GetHostFrameSinkManager();
|
||||
if (manager)
|
||||
@@ -840,7 +842,7 @@ void RenderWidgetHostInputEventRouter::DispatchTouchEvent(
|
||||
touch_event.unique_touch_event_id) ==
|
||||
touchscreen_gesture_target_map_.end());
|
||||
touchscreen_gesture_target_map_[touch_event.unique_touch_event_id] =
|
||||
- touch_target_;
|
||||
+ touch_target_->GetWeakPtr();
|
||||
} else if (touch_event.GetType() == blink::WebInputEvent::Type::kTouchStart) {
|
||||
active_touches_ += CountChangedTouchPoints(touch_event);
|
||||
}
|
||||
@@ -1352,7 +1354,7 @@ void RenderWidgetHostInputEventRouter::AddFrameSinkIdOwner(
|
||||
// We want to be notified if the owner is destroyed so we can remove it from
|
||||
// our map.
|
||||
owner->AddObserver(this);
|
||||
- owner_map_.insert(std::make_pair(id, owner));
|
||||
+ owner_map_.insert(std::make_pair(id, owner->GetWeakPtr()));
|
||||
}
|
||||
|
||||
void RenderWidgetHostInputEventRouter::RemoveFrameSinkIdOwner(
|
||||
@@ -1364,7 +1366,8 @@ void RenderWidgetHostInputEventRouter::RemoveFrameSinkIdOwner(
|
||||
// stale values if the view destructs and isn't an observer anymore.
|
||||
// Note: the view the iterator points at will be deleted in the following
|
||||
// call, and shouldn't be used after this point.
|
||||
- OnRenderWidgetHostViewBaseDestroyed(it_to_remove->second);
|
||||
+ if (it_to_remove->second)
|
||||
+ OnRenderWidgetHostViewBaseDestroyed(it_to_remove->second.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1415,7 +1418,7 @@ RenderWidgetHostInputEventRouter::FindTouchscreenGestureEventTarget(
|
||||
bool RenderWidgetHostInputEventRouter::IsViewInMap(
|
||||
const RenderWidgetHostViewBase* view) const {
|
||||
DCHECK(!is_registered(view->GetFrameSinkId()) ||
|
||||
- owner_map_.find(view->GetFrameSinkId())->second == view);
|
||||
+ owner_map_.find(view->GetFrameSinkId())->second.get() == view);
|
||||
return is_registered(view->GetFrameSinkId());
|
||||
}
|
||||
|
||||
@@ -1552,7 +1555,7 @@ void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent(
|
||||
target = result.view;
|
||||
fallback_target_location = transformed_point;
|
||||
} else if (is_gesture_start) {
|
||||
- target = gesture_target_it->second;
|
||||
+ target = gesture_target_it->second.get();
|
||||
touchscreen_gesture_target_map_.erase(gesture_target_it);
|
||||
|
||||
// Abort any scroll bubbling in progress to avoid double entry.
|
||||
@@ -1738,7 +1741,7 @@ RenderWidgetHostInputEventRouter::FindViewFromFrameSinkId(
|
||||
// If the point hit a Surface whose namspace is no longer in the map, then
|
||||
// it likely means the RenderWidgetHostView has been destroyed but its
|
||||
// parent frame has not sent a new compositor frame since that happened.
|
||||
- return iter == owner_map_.end() ? nullptr : iter->second;
|
||||
+ return iter == owner_map_.end() ? nullptr : iter->second.get();
|
||||
}
|
||||
|
||||
bool RenderWidgetHostInputEventRouter::ShouldContinueHitTesting(
|
||||
@@ -1758,8 +1761,10 @@ bool RenderWidgetHostInputEventRouter::ShouldContinueHitTesting(
|
||||
std::vector<RenderWidgetHostView*>
|
||||
RenderWidgetHostInputEventRouter::GetRenderWidgetHostViewsForTests() const {
|
||||
std::vector<RenderWidgetHostView*> hosts;
|
||||
- for (auto entry : owner_map_)
|
||||
- hosts.push_back(entry.second);
|
||||
+ for (auto entry : owner_map_) {
|
||||
+ DCHECK(entry.second);
|
||||
+ hosts.push_back(entry.second.get());
|
||||
+ }
|
||||
|
||||
return hosts;
|
||||
}
|
||||
@@ -1928,8 +1933,10 @@ void RenderWidgetHostInputEventRouter::SetCursor(const WebCursor& cursor) {
|
||||
last_device_scale_factor_ =
|
||||
last_mouse_move_root_view_->current_device_scale_factor();
|
||||
if (auto* cursor_manager = last_mouse_move_root_view_->GetCursorManager()) {
|
||||
- for (auto it : owner_map_)
|
||||
- cursor_manager->UpdateCursor(it.second, cursor);
|
||||
+ for (auto it : owner_map_) {
|
||||
+ if (it.second)
|
||||
+ cursor_manager->UpdateCursor(it.second.get(), cursor);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.h b/content/browser/renderer_host/render_widget_host_input_event_router.h
|
||||
index 42629b133b883865bebfa27f5d29eb5e2d153d0b..c4ce54a5a6beb509d6242ee0e5ebdf4c88f01251 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_input_event_router.h
|
||||
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.h
|
||||
@@ -195,10 +195,11 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
|
||||
FRIEND_TEST_ALL_PREFIXES(BrowserSideFlingBrowserTest,
|
||||
InertialGSUBubblingStopsWhenParentCannotScroll);
|
||||
|
||||
- using FrameSinkIdOwnerMap = std::unordered_map<viz::FrameSinkId,
|
||||
- RenderWidgetHostViewBase*,
|
||||
- viz::FrameSinkIdHash>;
|
||||
- using TargetMap = std::map<uint32_t, RenderWidgetHostViewBase*>;
|
||||
+ using FrameSinkIdOwnerMap =
|
||||
+ std::unordered_map<viz::FrameSinkId,
|
||||
+ base::WeakPtr<RenderWidgetHostViewBase>,
|
||||
+ viz::FrameSinkIdHash>;
|
||||
+ using TargetMap = std::map<uint32_t, base::WeakPtr<RenderWidgetHostViewBase>>;
|
||||
|
||||
void ClearAllObserverRegistrations();
|
||||
RenderWidgetTargetResult FindViewAtLocation(
|
||||
@@ -0,0 +1,174 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Cunningham <chcunningham@chromium.org>
|
||||
Date: Tue, 5 Jan 2021 21:23:21 +0000
|
||||
Subject: MediaCapabilities: Use threadsafe static wtf::String
|
||||
|
||||
This replaces DEFINE_THREAD_SAFE_STATIC_LOCAL(const String, ...).
|
||||
StringImpl ref counting (behind that macro) is not currently threadsafe.
|
||||
|
||||
(cherry picked from commit f9add3b8e53c440129f7be4a181a22c440e856bc)
|
||||
|
||||
Bug: 1160534
|
||||
Change-Id: I70f4aa796aaefabbee36db4fcdf0fbf0defe4959
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2606399
|
||||
Commit-Queue: Chrome Cunningham <chcunningham@chromium.org>
|
||||
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
|
||||
Auto-Submit: Chrome Cunningham <chcunningham@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#839863}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2611646
|
||||
Reviewed-by: Chrome Cunningham <chcunningham@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4324@{#1460}
|
||||
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn
|
||||
index 0f08d60394f526b883a91c3994bea5dbe6a7d3e8..d38dc0f47cc186cc5bf45704a668438450797a8c 100644
|
||||
--- a/third_party/blink/renderer/modules/BUILD.gn
|
||||
+++ b/third_party/blink/renderer/modules/BUILD.gn
|
||||
@@ -21,12 +21,18 @@ config("modules_implementation") {
|
||||
defines = [ "BLINK_MODULES_IMPLEMENTATION=1" ]
|
||||
}
|
||||
|
||||
-make_names("module_names") {
|
||||
+make_names("indexed_db_names") {
|
||||
in_files = [ "indexeddb/indexed_db_names.json5" ]
|
||||
output_dir = blink_modules_output_dir
|
||||
deps = [] # Don't use default deps (otherwise it will be circular).
|
||||
}
|
||||
|
||||
+make_names("media_capabilities_names") {
|
||||
+ in_files = [ "media_capabilities/media_capabilities_names.json5" ]
|
||||
+ output_dir = blink_modules_output_dir
|
||||
+ deps = [] # Don't use default deps (otherwise it will be circular).
|
||||
+}
|
||||
+
|
||||
jumbo_component("modules") {
|
||||
output_name = "blink_modules"
|
||||
|
||||
@@ -42,8 +48,9 @@ jumbo_component("modules") {
|
||||
"modules_initializer.h",
|
||||
]
|
||||
|
||||
- # Compile sources generated by module_names script.
|
||||
- sources += get_target_outputs(":module_names")
|
||||
+ # Compile sources generated by make_names script.
|
||||
+ sources += get_target_outputs(":indexed_db_names")
|
||||
+ sources += get_target_outputs(":media_capabilities_names")
|
||||
|
||||
sources += bindings_modules_v8_files
|
||||
sources += rebase_path(
|
||||
@@ -165,8 +172,9 @@ jumbo_component("modules") {
|
||||
}
|
||||
|
||||
deps = [
|
||||
+ ":indexed_db_names",
|
||||
":make_modules_generated",
|
||||
- ":module_names",
|
||||
+ ":media_capabilities_names",
|
||||
"//jingle:webrtc_glue",
|
||||
"//net:net",
|
||||
"//third_party/blink/renderer/bindings/modules:generated",
|
||||
@@ -249,7 +257,8 @@ jumbo_source_set("modules_testing") {
|
||||
|
||||
group("make_modules_generated") {
|
||||
public_deps = [
|
||||
- ":module_names",
|
||||
+ ":indexed_db_names",
|
||||
+ ":media_capabilities_names",
|
||||
"//third_party/blink/renderer/bindings/modules:bindings_modules_generated",
|
||||
"//third_party/blink/renderer/core:core_event_interfaces",
|
||||
]
|
||||
diff --git a/third_party/blink/renderer/modules/media_capabilities/DEPS b/third_party/blink/renderer/modules/media_capabilities/DEPS
|
||||
index 3b8d2749b4f486c4b0b207d4e20f966b5e573e07..1a5a3e9e3b6a031c4752cd92cf87426cae72f1d2 100644
|
||||
--- a/third_party/blink/renderer/modules/media_capabilities/DEPS
|
||||
+++ b/third_party/blink/renderer/modules/media_capabilities/DEPS
|
||||
@@ -12,6 +12,7 @@ include_rules = [
|
||||
"-third_party/blink/renderer/modules",
|
||||
"+third_party/blink/renderer/modules/encryptedmedia",
|
||||
"+third_party/blink/renderer/modules/media_capabilities",
|
||||
+ "+third_party/blink/renderer/modules/media_capabilities_names.h",
|
||||
"+third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h",
|
||||
"+third_party/blink/renderer/modules/modules_export.h",
|
||||
]
|
||||
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
|
||||
index d571e60943092c746a7f4136b9e626128839abfc..9515ae2f71a415bb81a7e786c9d7fb2b623bd852 100644
|
||||
--- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
|
||||
+++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h"
|
||||
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h"
|
||||
#include "third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h"
|
||||
+#include "third_party/blink/renderer/modules/media_capabilities_names.h"
|
||||
#include "third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h"
|
||||
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
|
||||
#include "third_party/blink/renderer/platform/bindings/script_state.h"
|
||||
@@ -296,9 +297,9 @@ WebAudioConfiguration ToWebAudioConfiguration(
|
||||
DCHECK(parsed_content_type.IsValid());
|
||||
DCHECK(!parsed_content_type.GetParameters().HasDuplicatedNames());
|
||||
|
||||
- DEFINE_THREAD_SAFE_STATIC_LOCAL(const String, codecs, ("codecs"));
|
||||
web_configuration.mime_type = parsed_content_type.MimeType().LowerASCII();
|
||||
- web_configuration.codec = parsed_content_type.ParameterValueForName(codecs);
|
||||
+ web_configuration.codec = parsed_content_type.ParameterValueForName(
|
||||
+ media_capabilities_names::kCodecs);
|
||||
|
||||
// |channels| is optional and will be set to a null WebString if not present.
|
||||
web_configuration.channels = configuration->hasChannels()
|
||||
@@ -324,9 +325,9 @@ WebVideoConfiguration ToWebVideoConfiguration(
|
||||
DCHECK(parsed_content_type.IsValid());
|
||||
DCHECK(!parsed_content_type.GetParameters().HasDuplicatedNames());
|
||||
|
||||
- DEFINE_THREAD_SAFE_STATIC_LOCAL(const String, codecs, ("codecs"));
|
||||
web_configuration.mime_type = parsed_content_type.MimeType().LowerASCII();
|
||||
- web_configuration.codec = parsed_content_type.ParameterValueForName(codecs);
|
||||
+ web_configuration.codec = parsed_content_type.ParameterValueForName(
|
||||
+ media_capabilities_names::kCodecs);
|
||||
|
||||
DCHECK(configuration->hasWidth());
|
||||
web_configuration.width = configuration->width();
|
||||
@@ -586,9 +587,9 @@ bool ParseContentType(const String& content_type,
|
||||
return false;
|
||||
}
|
||||
|
||||
- DEFINE_THREAD_SAFE_STATIC_LOCAL(const String, codecs, ("codecs"));
|
||||
*mime_type = parsed_content_type.MimeType().LowerASCII();
|
||||
- *codec = parsed_content_type.ParameterValueForName(codecs);
|
||||
+ *codec = parsed_content_type.ParameterValueForName(
|
||||
+ media_capabilities_names::kCodecs);
|
||||
return true;
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities_names.json5 b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_names.json5
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..01f9a0f705da3fad7708cccbd22c9a8c1789ff0c
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_names.json5
|
||||
@@ -0,0 +1,9 @@
|
||||
+{
|
||||
+ metadata: {
|
||||
+ namespace: "media_capabilities_names",
|
||||
+ },
|
||||
+
|
||||
+ data: [
|
||||
+ "codecs",
|
||||
+ ],
|
||||
+}
|
||||
diff --git a/third_party/blink/renderer/modules/modules_initializer.cc b/third_party/blink/renderer/modules/modules_initializer.cc
|
||||
index df76ac04d4c64697cf5979609a55372b025adadb..5b830fd8c312bdbefe8a52b2e896b194aedb63c6 100644
|
||||
--- a/third_party/blink/renderer/modules/modules_initializer.cc
|
||||
+++ b/third_party/blink/renderer/modules/modules_initializer.cc
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "third_party/blink/renderer/modules/launch/file_handling_expiry_impl.h"
|
||||
#include "third_party/blink/renderer/modules/launch/web_launch_service_impl.h"
|
||||
#include "third_party/blink/renderer/modules/manifest/manifest_manager.h"
|
||||
+#include "third_party/blink/renderer/modules/media_capabilities_names.h"
|
||||
#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
|
||||
#include "third_party/blink/renderer/modules/mediastream/user_media_client.h"
|
||||
#include "third_party/blink/renderer/modules/mediastream/user_media_controller.h"
|
||||
@@ -117,6 +118,7 @@ void ModulesInitializer::Initialize() {
|
||||
Document::RegisterEventFactory(EventModulesFactory::Create());
|
||||
ModuleBindingsInitializer::Init();
|
||||
indexed_db_names::Init();
|
||||
+ media_capabilities_names::Init();
|
||||
AXObjectCache::Init(AXObjectCacheImpl::Create);
|
||||
DraggedIsolatedFileSystem::Init(
|
||||
DraggedIsolatedFileSystemImpl::PrepareForDataObject);
|
||||
@@ -0,0 +1,152 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Markus Handell <handellm@google.com>
|
||||
Date: Tue, 23 Feb 2021 18:45:55 +0000
|
||||
Subject: MediaRecorder: tolerate non-GMB NV12 frames for H264.
|
||||
|
||||
The VPX video track recorders were updated to tolerate non-GMB NV12
|
||||
input in crrev/c/2425748, but the H264 encoder was left neglected,
|
||||
which hurts Mac users that have disabled hardware acceleration. This
|
||||
change adds that support to it.
|
||||
|
||||
[TBR landing because mcasas@chromium.org is OOO]
|
||||
|
||||
TBR=mcasas@chromium.org
|
||||
(cherry picked from commit de865890bf6a12c74ae9943ede6132d25c7a33dd)
|
||||
|
||||
Bug: 1177593
|
||||
Change-Id: I608c76b1de8261dcc44463fe896e3b63d5fd329e
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2694407
|
||||
Reviewed-by: ccameron <ccameron@chromium.org>
|
||||
Reviewed-by: Evan Shrubsole <eshr@google.com>
|
||||
Reviewed-by: Miguel Casas <mcasas@chromium.org>
|
||||
Commit-Queue: Markus Handell <handellm@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#854709}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2715222
|
||||
Cr-Commit-Position: refs/branch-heads/4389@{#1320}
|
||||
Cr-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
|
||||
diff --git a/media/base/video_util.cc b/media/base/video_util.cc
|
||||
index 3daa1cb27d5705d56d0075e82a9ecd0bfb86c366..d5a0f1b578e22822089d704fcd7b98cbb26bb405 100644
|
||||
--- a/media/base/video_util.cc
|
||||
+++ b/media/base/video_util.cc
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "base/numerics/safe_math.h"
|
||||
#include "media/base/video_frame.h"
|
||||
#include "third_party/libyuv/include/libyuv.h"
|
||||
+#include "ui/gfx/gpu_memory_buffer.h"
|
||||
|
||||
namespace media {
|
||||
|
||||
@@ -424,6 +425,38 @@ void CopyRGBToVideoFrame(const uint8_t* source,
|
||||
region_in_frame.width(), region_in_frame.height());
|
||||
}
|
||||
|
||||
+scoped_refptr<VideoFrame> ConvertToMemoryMappedFrame(
|
||||
+ scoped_refptr<VideoFrame> video_frame) {
|
||||
+ DCHECK(video_frame);
|
||||
+ DCHECK(video_frame->HasGpuMemoryBuffer());
|
||||
+ auto* gmb = video_frame->GetGpuMemoryBuffer();
|
||||
+ if (!gmb->Map())
|
||||
+ return nullptr;
|
||||
+ const size_t num_planes = VideoFrame::NumPlanes(video_frame->format());
|
||||
+ uint8_t* plane_addrs[VideoFrame::kMaxPlanes] = {};
|
||||
+ for (size_t i = 0; i < num_planes; i++)
|
||||
+ plane_addrs[i] = static_cast<uint8_t*>(gmb->memory(i));
|
||||
+ auto mapped_frame = VideoFrame::WrapExternalYuvDataWithLayout(
|
||||
+ video_frame->layout(), video_frame->visible_rect(),
|
||||
+ video_frame->natural_size(), plane_addrs[0], plane_addrs[1],
|
||||
+ plane_addrs[2], video_frame->timestamp());
|
||||
+ if (!mapped_frame) {
|
||||
+ gmb->Unmap();
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ mapped_frame->set_color_space(video_frame->ColorSpace());
|
||||
+ mapped_frame->metadata()->MergeMetadataFrom(video_frame->metadata());
|
||||
+ // Pass |video_frame| so that it outlives |mapped_frame| and the mapped buffer
|
||||
+ // is unmapped on destruction.
|
||||
+ mapped_frame->AddDestructionObserver(base::BindOnce(
|
||||
+ [](scoped_refptr<VideoFrame> frame) {
|
||||
+ DCHECK(frame->HasGpuMemoryBuffer());
|
||||
+ frame->GetGpuMemoryBuffer()->Unmap();
|
||||
+ },
|
||||
+ std::move(video_frame)));
|
||||
+ return mapped_frame;
|
||||
+}
|
||||
+
|
||||
scoped_refptr<VideoFrame> WrapAsI420VideoFrame(
|
||||
scoped_refptr<VideoFrame> frame) {
|
||||
DCHECK_EQ(VideoFrame::STORAGE_OWNED_MEMORY, frame->storage_type());
|
||||
diff --git a/media/base/video_util.h b/media/base/video_util.h
|
||||
index 42e060a25b711fca8bba3cef8ade9bbaa2092c55..2681163c55618ae8738d91987bb46a4e8bcc541b 100644
|
||||
--- a/media/base/video_util.h
|
||||
+++ b/media/base/video_util.h
|
||||
@@ -134,6 +134,12 @@ MEDIA_EXPORT gfx::Size GetRectSizeFromOrigin(const gfx::Rect& rect);
|
||||
MEDIA_EXPORT gfx::Size PadToMatchAspectRatio(const gfx::Size& size,
|
||||
const gfx::Size& target);
|
||||
|
||||
+// A helper function to map GpuMemoryBuffer-based VideoFrame. This function
|
||||
+// maps the given GpuMemoryBuffer of |frame| as-is without converting pixel
|
||||
+// format. The returned VideoFrame owns the |frame|.
|
||||
+MEDIA_EXPORT scoped_refptr<VideoFrame> ConvertToMemoryMappedFrame(
|
||||
+ scoped_refptr<VideoFrame> frame);
|
||||
+
|
||||
// Copy an RGB bitmap into the specified |region_in_frame| of a YUV video frame.
|
||||
// Fills the regions outside |region_in_frame| with black.
|
||||
MEDIA_EXPORT void CopyRGBToVideoFrame(const uint8_t* source,
|
||||
diff --git a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
|
||||
index 401e696e886f68fc4a9bb9ac0614959f0a8673a8..c323faab804ad421b1c8f8d7789222304c4d44e6 100644
|
||||
--- a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
|
||||
+++ b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
|
||||
@@ -54,9 +54,13 @@ void H264Encoder::EncodeOnEncodingTaskRunner(
|
||||
base::TimeTicks capture_timestamp) {
|
||||
TRACE_EVENT0("media", "H264Encoder::EncodeOnEncodingTaskRunner");
|
||||
DCHECK(encoding_task_runner_->BelongsToCurrentThread());
|
||||
+ DCHECK(frame->format() == media::VideoPixelFormat::PIXEL_FORMAT_NV12 ||
|
||||
+ frame->format() == media::VideoPixelFormat::PIXEL_FORMAT_I420 ||
|
||||
+ frame->format() == media::VideoPixelFormat::PIXEL_FORMAT_I420A);
|
||||
|
||||
- if (frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER)
|
||||
+ if (frame->format() == media::PIXEL_FORMAT_NV12)
|
||||
frame = ConvertToI420ForSoftwareEncoder(frame);
|
||||
+ DCHECK(frame->IsMappable());
|
||||
|
||||
const gfx::Size frame_size = frame->visible_rect().size();
|
||||
if (!openh264_encoder_ || configured_size_ != frame_size) {
|
||||
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
|
||||
index 0397c605efbb2a669e0235898e1b3029e3b4f0e8..7a7683092919b3712b2c09a86b06fd9c724f8aac 100644
|
||||
--- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
|
||||
+++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
|
||||
@@ -415,20 +415,17 @@ bool VideoTrackRecorderImpl::Encoder::CanEncodeAlphaChannel() {
|
||||
scoped_refptr<media::VideoFrame>
|
||||
VideoTrackRecorderImpl::Encoder::ConvertToI420ForSoftwareEncoder(
|
||||
scoped_refptr<media::VideoFrame> frame) {
|
||||
- DCHECK_EQ(frame->storage_type(),
|
||||
- media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER);
|
||||
- // NV12 is currently the only supported pixel format for GpuMemoryBuffer.
|
||||
DCHECK_EQ(frame->format(), media::VideoPixelFormat::PIXEL_FORMAT_NV12);
|
||||
|
||||
- auto* gmb = frame->GetGpuMemoryBuffer();
|
||||
- if (!gmb->Map())
|
||||
- return frame;
|
||||
+ if (frame->GetGpuMemoryBuffer())
|
||||
+ frame = media::ConvertToMemoryMappedFrame(frame);
|
||||
+
|
||||
scoped_refptr<media::VideoFrame> i420_frame = media::VideoFrame::CreateFrame(
|
||||
media::VideoPixelFormat::PIXEL_FORMAT_I420, frame->coded_size(),
|
||||
frame->visible_rect(), frame->natural_size(), frame->timestamp());
|
||||
auto ret = libyuv::NV12ToI420(
|
||||
- static_cast<const uint8_t*>(gmb->memory(0)), gmb->stride(0),
|
||||
- static_cast<const uint8_t*>(gmb->memory(1)), gmb->stride(1),
|
||||
+ static_cast<const uint8_t*>(frame->data(0)), frame->stride(0),
|
||||
+ static_cast<const uint8_t*>(frame->data(1)), frame->stride(1),
|
||||
i420_frame->data(media::VideoFrame::kYPlane),
|
||||
i420_frame->stride(media::VideoFrame::kYPlane),
|
||||
i420_frame->data(media::VideoFrame::kUPlane),
|
||||
@@ -436,7 +433,6 @@ VideoTrackRecorderImpl::Encoder::ConvertToI420ForSoftwareEncoder(
|
||||
i420_frame->data(media::VideoFrame::kVPlane),
|
||||
i420_frame->stride(media::VideoFrame::kVPlane),
|
||||
frame->coded_size().width(), frame->coded_size().height());
|
||||
- gmb->Unmap();
|
||||
if (ret)
|
||||
return frame;
|
||||
return i420_frame;
|
||||
@@ -0,0 +1,179 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dale Curtis <dalecurtis@chromium.org>
|
||||
Date: Fri, 13 Nov 2020 21:06:58 +0000
|
||||
Subject: Merge M86: "Ensure that buffers used by ImageDecoder haven't been
|
||||
neutered."
|
||||
|
||||
Since JavaScript may detach the underlying buffers, we need to check
|
||||
to ensure they're still valid before using them for decoding.
|
||||
|
||||
TBR=sandersd
|
||||
|
||||
(cherry picked from commit fa93fba6a28d384b0a0cddd63e85eb10cb97bb53)
|
||||
|
||||
Test: Updated unittests. Manual test case breaks.
|
||||
Change-Id: Iefe5f8adf619cd6afdfedcb08a13c2996bfe0d32
|
||||
Fixed: 1146761
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2527542
|
||||
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
|
||||
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
|
||||
Reviewed-by: Dan Sanders <sandersd@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#825615}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2537781
|
||||
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1453}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc
|
||||
index e42ceaf37038b58e53d11bfb63b7a27aa414a87b..780fdbef3afb9cca322002f736fc3d9b87f834b3 100644
|
||||
--- a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc
|
||||
+++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc
|
||||
@@ -99,9 +99,8 @@ ImageDecoderExternal::ImageDecoderExternal(ScriptState* script_state,
|
||||
return;
|
||||
}
|
||||
|
||||
- // TODO: Data is owned by the caller who may be free to manipulate it. We will
|
||||
- // probably need to make a copy to our own internal data or neuter the buffers
|
||||
- // as seen by JS.
|
||||
+ // Since data is owned by the caller who may be free to manipulate it, we must
|
||||
+ // check HasValidEncodedData() before attempting to access |decoder_|.
|
||||
segment_reader_ = SegmentReader::CreateFromSkData(
|
||||
SkData::MakeWithoutCopy(buffer.Data(), buffer.ByteLengthAsSizeT()));
|
||||
if (!segment_reader_) {
|
||||
@@ -206,6 +205,7 @@ void ImageDecoderExternal::Trace(Visitor* visitor) const {
|
||||
|
||||
void ImageDecoderExternal::CreateImageDecoder() {
|
||||
DCHECK(!decoder_);
|
||||
+ DCHECK(HasValidEncodedData());
|
||||
|
||||
// TODO: We should probably call ImageDecoder::SetMemoryAllocator() so that
|
||||
// we can recycle frame buffers for decoded images.
|
||||
@@ -260,6 +260,13 @@ void ImageDecoderExternal::MaybeSatisfyPendingDecodes() {
|
||||
continue;
|
||||
}
|
||||
|
||||
+ if (!HasValidEncodedData()) {
|
||||
+ request->resolver->Reject(MakeGarbageCollected<DOMException>(
|
||||
+ DOMExceptionCode::kInvalidStateError,
|
||||
+ "Source data has been neutered"));
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
auto* image = decoder_->DecodeFrameBufferAtIndex(request->frame_index);
|
||||
if (decoder_->Failed() || !image) {
|
||||
request->complete = true;
|
||||
@@ -326,6 +333,7 @@ void ImageDecoderExternal::MaybeSatisfyPendingDecodes() {
|
||||
}
|
||||
|
||||
void ImageDecoderExternal::MaybeSatisfyPendingMetadataDecodes() {
|
||||
+ DCHECK(HasValidEncodedData());
|
||||
DCHECK(decoder_);
|
||||
DCHECK(decoder_->Failed() || decoder_->IsDecodedSizeAvailable());
|
||||
for (auto& resolver : pending_metadata_decodes_)
|
||||
@@ -334,6 +342,9 @@ void ImageDecoderExternal::MaybeSatisfyPendingMetadataDecodes() {
|
||||
}
|
||||
|
||||
void ImageDecoderExternal::MaybeUpdateMetadata() {
|
||||
+ if (!HasValidEncodedData())
|
||||
+ return;
|
||||
+
|
||||
const size_t decoded_frame_count = decoder_->FrameCount();
|
||||
if (decoder_->Failed()) {
|
||||
MaybeSatisfyPendingMetadataDecodes();
|
||||
@@ -358,4 +369,22 @@ void ImageDecoderExternal::MaybeUpdateMetadata() {
|
||||
MaybeSatisfyPendingMetadataDecodes();
|
||||
}
|
||||
|
||||
+bool ImageDecoderExternal::HasValidEncodedData() const {
|
||||
+ // If we keep an internal copy of the data, it's always valid.
|
||||
+ if (stream_buffer_)
|
||||
+ return true;
|
||||
+
|
||||
+ if (init_data_->data().IsArrayBuffer() &&
|
||||
+ init_data_->data().GetAsArrayBuffer()->IsDetached()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (init_data_->data().IsArrayBufferView() &&
|
||||
+ !init_data_->data().GetAsArrayBufferView()->BaseAddress()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc.rej b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc.rej
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..68d0eae0c7cd414f8cbe90aee79417d2a4ffe98b
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc.rej
|
||||
@@ -0,0 +1,53 @@
|
||||
+diff a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc (rejected hunks)
|
||||
+@@ -120,9 +120,8 @@
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+- // TODO(crbug.com/1073995): Data is owned by the caller who may be free to
|
||||
+- // manipulate it. We will probably need to make a copy to our own internal
|
||||
+- // data or neuter the buffers as seen by JS.
|
||||
++ // Since data is owned by the caller who may be free to manipulate it, we must
|
||||
++ // check HasValidEncodedData() before attempting to access |decoder_|.
|
||||
+ segment_reader_ = SegmentReader::CreateFromSkData(
|
||||
+ SkData::MakeWithoutCopy(buffer.Data(), buffer.ByteLengthAsSizeT()));
|
||||
+ if (!segment_reader_) {
|
||||
+@@ -266,6 +265,7 @@
|
||||
+
|
||||
+ void ImageDecoderExternal::CreateImageDecoder() {
|
||||
+ DCHECK(!decoder_);
|
||||
++ DCHECK(HasValidEncodedData());
|
||||
+
|
||||
+ // TODO(crbug.com/1073995): We should probably call
|
||||
+ // ImageDecoder::SetMemoryAllocator() so that we can recycle frame buffers for
|
||||
+@@ -320,6 +320,13 @@
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
++ if (!HasValidEncodedData()) {
|
||||
++ request->exception = MakeGarbageCollected<DOMException>(
|
||||
++ DOMExceptionCode::kInvalidStateError,
|
||||
++ "Source data has been neutered");
|
||||
++ continue;
|
||||
++ }
|
||||
++
|
||||
+ auto* image = decoder_->DecodeFrameBufferAtIndex(request->frame_index);
|
||||
+ if (decoder_->Failed() || !image) {
|
||||
+ // TODO(crbug.com/1073995): Include frameIndex in rejection?
|
||||
+@@ -398,6 +405,7 @@
|
||||
+ }
|
||||
+
|
||||
+ void ImageDecoderExternal::MaybeSatisfyPendingMetadataDecodes() {
|
||||
++ DCHECK(HasValidEncodedData());
|
||||
+ DCHECK(decoder_);
|
||||
+ if (!decoder_->IsSizeAvailable() && !decoder_->Failed())
|
||||
+ return;
|
||||
+@@ -409,6 +417,9 @@
|
||||
+ }
|
||||
+
|
||||
+ void ImageDecoderExternal::MaybeUpdateMetadata() {
|
||||
++ if (!HasValidEncodedData())
|
||||
++ return;
|
||||
++
|
||||
+ // Since we always create the decoder at construction, we need to wait until
|
||||
+ // at least the size is available before signaling that metadata has been
|
||||
+ // retrieved.
|
||||
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h
|
||||
index 1b4ac0ce7eade63c06c1030c29fc90a8551aa7c2..7d9d534ce14d07e49fca99f11297e74b1311363e 100644
|
||||
--- a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h
|
||||
+++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h
|
||||
@@ -61,6 +61,10 @@ class MODULES_EXPORT ImageDecoderExternal final : public ScriptWrappable,
|
||||
void MaybeSatisfyPendingMetadataDecodes();
|
||||
void MaybeUpdateMetadata();
|
||||
|
||||
+ // Returns false if the decoder was constructed with an ArrayBuffer or
|
||||
+ // ArrayBufferView that has since been neutered.
|
||||
+ bool HasValidEncodedData() const;
|
||||
+
|
||||
Member<ScriptState> script_state_;
|
||||
|
||||
// Used when a ReadableStream is provided.
|
||||
@@ -0,0 +1,206 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dale Curtis <dalecurtis@chromium.org>
|
||||
Date: Mon, 5 Oct 2020 22:14:12 +0000
|
||||
Subject: Only zero out cross-origin audio that doesn't get played out.
|
||||
|
||||
Cross-origin audio is still allowed to play out, it just can't be
|
||||
captured by the containing page.
|
||||
|
||||
Bug: 1128657, 1134679
|
||||
Test: Unit tests added.
|
||||
|
||||
Change-Id: Id4c73e315072b8683e45a2ddf929d534f1da9928
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2450390
|
||||
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
|
||||
Reviewed-by: Will Cassella <cassew@google.com>
|
||||
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#813956}
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
|
||||
index c54e1768886a7d2d922f13596a9fb3b456ba6611..5cc64a4ae790f8b0b72520f1b8d2b89617bd22e2 100644
|
||||
--- a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
|
||||
+++ b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
|
||||
@@ -81,10 +81,6 @@ class WebAudioSourceProviderImpl::TeeFilter
|
||||
const int num_rendered_frames = renderer_->Render(
|
||||
delay, delay_timestamp, prior_frames_skipped, audio_bus);
|
||||
|
||||
- // Zero out frames after rendering
|
||||
- if (origin_tainted_.IsSet())
|
||||
- audio_bus->Zero();
|
||||
-
|
||||
// Avoid taking the copy lock for the vast majority of cases.
|
||||
if (copy_required_) {
|
||||
base::AutoLock auto_lock(copy_lock_);
|
||||
@@ -93,7 +89,11 @@ class WebAudioSourceProviderImpl::TeeFilter
|
||||
media::AudioTimestampHelper::TimeToFrames(delay, sample_rate_);
|
||||
std::unique_ptr<media::AudioBus> bus_copy =
|
||||
media::AudioBus::Create(audio_bus->channels(), audio_bus->frames());
|
||||
- audio_bus->CopyTo(bus_copy.get());
|
||||
+ // Disable copying when origin is tainted.
|
||||
+ if (origin_tainted_.IsSet())
|
||||
+ bus_copy->Zero();
|
||||
+ else
|
||||
+ audio_bus->CopyTo(bus_copy.get());
|
||||
copy_audio_bus_callback_.Run(std::move(bus_copy),
|
||||
static_cast<uint32_t>(frames_delayed),
|
||||
sample_rate_);
|
||||
@@ -119,6 +119,7 @@ class WebAudioSourceProviderImpl::TeeFilter
|
||||
}
|
||||
|
||||
void TaintOrigin() { origin_tainted_.Set(); }
|
||||
+ bool is_tainted() const { return origin_tainted_.IsSet(); }
|
||||
|
||||
private:
|
||||
AudioRendererSink::RenderCallback* renderer_ = nullptr;
|
||||
@@ -220,6 +221,13 @@ void WebAudioSourceProviderImpl::ProvideInput(
|
||||
DCHECK_EQ(tee_filter_->channels(), bus_wrapper_->channels());
|
||||
const int frames = tee_filter_->Render(
|
||||
base::TimeDelta(), base::TimeTicks::Now(), 0, bus_wrapper_.get());
|
||||
+
|
||||
+ // Zero out frames after rendering for tainted origins.
|
||||
+ if (tee_filter_->is_tainted()) {
|
||||
+ bus_wrapper_->Zero();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (frames < incoming_number_of_frames)
|
||||
bus_wrapper_->ZeroFramesPartial(frames, incoming_number_of_frames - frames);
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
|
||||
index 1f0c69d7143c06af3127a3f4b8dea6bd416d949f..db319bcc4f2fce940b5269da994e61a9978772f0 100644
|
||||
--- a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
|
||||
+++ b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
|
||||
@@ -22,6 +22,11 @@ using ::testing::_;
|
||||
namespace blink {
|
||||
|
||||
namespace {
|
||||
+
|
||||
+MATCHER(IsMuted, std::string(negation ? "isn't" : "is") + " muted") {
|
||||
+ return arg->AreFramesZero();
|
||||
+}
|
||||
+
|
||||
const float kTestVolume = 0.25;
|
||||
const int kTestSampleRate = 48000;
|
||||
} // namespace
|
||||
@@ -89,17 +94,10 @@ class WebAudioSourceProviderImplTest : public testing::Test,
|
||||
|
||||
// WebAudioSourceProviderClient implementation.
|
||||
MOCK_METHOD2(SetFormat, void(uint32_t numberOfChannels, float sampleRate));
|
||||
-
|
||||
- // CopyAudioCB. Added forwarder method due to GMock troubles with scoped_ptr.
|
||||
MOCK_METHOD3(DoCopyAudioCB,
|
||||
- void(media::AudioBus*,
|
||||
+ void(std::unique_ptr<media::AudioBus> bus,
|
||||
uint32_t frames_delayed,
|
||||
int sample_rate));
|
||||
- void OnAudioBus(std::unique_ptr<media::AudioBus> bus,
|
||||
- uint32_t frames_delayed,
|
||||
- int sample_rate) {
|
||||
- DoCopyAudioCB(bus.get(), frames_delayed, sample_rate);
|
||||
- }
|
||||
|
||||
int Render(media::AudioBus* audio_bus) {
|
||||
return wasp_impl_->RenderForTesting(audio_bus);
|
||||
@@ -163,6 +161,35 @@ TEST_F(WebAudioSourceProviderImplTest, SinkMethods) {
|
||||
CallAllSinkMethodsAndVerify(false);
|
||||
}
|
||||
|
||||
+// Test tainting effects on Render().
|
||||
+TEST_F(WebAudioSourceProviderImplTest, RenderTainted) {
|
||||
+ auto bus = media::AudioBus::Create(params_);
|
||||
+ bus->Zero();
|
||||
+
|
||||
+ // Point the WebVector into memory owned by |bus|.
|
||||
+ WebVector<float*> audio_data(static_cast<size_t>(bus->channels()));
|
||||
+ for (size_t i = 0; i < audio_data.size(); ++i)
|
||||
+ audio_data[i] = bus->channel(static_cast<int>(i));
|
||||
+
|
||||
+ wasp_impl_->Initialize(params_, &fake_callback_);
|
||||
+
|
||||
+ EXPECT_CALL(*mock_sink_, Start());
|
||||
+ wasp_impl_->Start();
|
||||
+ EXPECT_CALL(*mock_sink_, Play());
|
||||
+ wasp_impl_->Play();
|
||||
+
|
||||
+ Render(bus.get());
|
||||
+ ASSERT_FALSE(bus->AreFramesZero());
|
||||
+
|
||||
+ // Normal audio output should be unaffected by tainting.
|
||||
+ wasp_impl_->TaintOrigin();
|
||||
+ Render(bus.get());
|
||||
+ ASSERT_FALSE(bus->AreFramesZero());
|
||||
+
|
||||
+ EXPECT_CALL(*mock_sink_, Stop());
|
||||
+ wasp_impl_->Stop();
|
||||
+}
|
||||
+
|
||||
// Test the AudioRendererSink state machine and its effects on provideInput().
|
||||
TEST_F(WebAudioSourceProviderImplTest, ProvideInput) {
|
||||
auto bus1 = media::AudioBus::Create(params_);
|
||||
@@ -249,12 +276,37 @@ TEST_F(WebAudioSourceProviderImplTest, ProvideInput) {
|
||||
ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get()));
|
||||
}
|
||||
|
||||
+// Test tainting effects on ProvideInput().
|
||||
+TEST_F(WebAudioSourceProviderImplTest, ProvideInputTainted) {
|
||||
+ auto bus = media::AudioBus::Create(params_);
|
||||
+ bus->Zero();
|
||||
+
|
||||
+ // Point the WebVector into memory owned by |bus|.
|
||||
+ WebVector<float*> audio_data(static_cast<size_t>(bus->channels()));
|
||||
+ for (size_t i = 0; i < audio_data.size(); ++i)
|
||||
+ audio_data[i] = bus->channel(static_cast<int>(i));
|
||||
+
|
||||
+ wasp_impl_->Initialize(params_, &fake_callback_);
|
||||
+ SetClient(this);
|
||||
+
|
||||
+ wasp_impl_->Start();
|
||||
+ wasp_impl_->Play();
|
||||
+ wasp_impl_->ProvideInput(audio_data, params_.frames_per_buffer());
|
||||
+ ASSERT_FALSE(bus->AreFramesZero());
|
||||
+
|
||||
+ wasp_impl_->TaintOrigin();
|
||||
+ wasp_impl_->ProvideInput(audio_data, params_.frames_per_buffer());
|
||||
+ ASSERT_TRUE(bus->AreFramesZero());
|
||||
+
|
||||
+ wasp_impl_->Stop();
|
||||
+}
|
||||
+
|
||||
// Verify CopyAudioCB is called if registered.
|
||||
TEST_F(WebAudioSourceProviderImplTest, CopyAudioCB) {
|
||||
testing::InSequence s;
|
||||
wasp_impl_->Initialize(params_, &fake_callback_);
|
||||
wasp_impl_->SetCopyAudioCallback(WTF::BindRepeating(
|
||||
- &WebAudioSourceProviderImplTest::OnAudioBus, base::Unretained(this)));
|
||||
+ &WebAudioSourceProviderImplTest::DoCopyAudioCB, base::Unretained(this)));
|
||||
|
||||
const auto bus1 = media::AudioBus::Create(params_);
|
||||
EXPECT_CALL(*this, DoCopyAudioCB(_, 0, params_.sample_rate())).Times(1);
|
||||
@@ -267,6 +319,27 @@ TEST_F(WebAudioSourceProviderImplTest, CopyAudioCB) {
|
||||
testing::Mock::VerifyAndClear(mock_sink_.get());
|
||||
}
|
||||
|
||||
+// Verify CopyAudioCB is zero when tainted.
|
||||
+TEST_F(WebAudioSourceProviderImplTest, CopyAudioCBTainted) {
|
||||
+ testing::InSequence s;
|
||||
+ wasp_impl_->Initialize(params_, &fake_callback_);
|
||||
+ wasp_impl_->SetCopyAudioCallback(WTF::BindRepeating(
|
||||
+ &WebAudioSourceProviderImplTest::DoCopyAudioCB, base::Unretained(this)));
|
||||
+
|
||||
+ const auto bus1 = media::AudioBus::Create(params_);
|
||||
+ EXPECT_CALL(*this,
|
||||
+ DoCopyAudioCB(testing::Not(IsMuted()), 0, params_.sample_rate()))
|
||||
+ .Times(1);
|
||||
+ Render(bus1.get());
|
||||
+
|
||||
+ wasp_impl_->TaintOrigin();
|
||||
+ EXPECT_CALL(*this, DoCopyAudioCB(IsMuted(), 0, params_.sample_rate()))
|
||||
+ .Times(1);
|
||||
+ Render(bus1.get());
|
||||
+
|
||||
+ testing::Mock::VerifyAndClear(mock_sink_.get());
|
||||
+}
|
||||
+
|
||||
TEST_F(WebAudioSourceProviderImplTest, MultipleInitializeWithSetClient) {
|
||||
// setClient() with a nullptr client should do nothing if no client is set.
|
||||
wasp_impl_->SetClient(nullptr);
|
||||
342
patches/chromium/ots_backport_maxp_sanitization.patch
Normal file
342
patches/chromium/ots_backport_maxp_sanitization.patch
Normal file
@@ -0,0 +1,342 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Dominik=20R=C3=B6ttsches?= <drott@chromium.org>
|
||||
Date: Mon, 11 Jan 2021 12:27:12 +0000
|
||||
Subject: Backport maxp sanitization
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Backport [1] to perform additional sanitization on maxp values.
|
||||
|
||||
[1] https://github.com/khaledhosny/ots/pull/227
|
||||
|
||||
(cherry picked from commit 6d0e7d799a46336c6bc297d4075a27dd0e7c235d)
|
||||
|
||||
Bug: 1153329
|
||||
Change-Id: I4bc2288574802559f6c9c67a52b6dfcd8cc7467a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2588339
|
||||
Auto-Submit: Dominik Röttsches <drott@chromium.org>
|
||||
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Reviewed-by: Koji Ishii <kojii@chromium.org>
|
||||
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#836679}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2620800
|
||||
Commit-Queue: Dominik Röttsches <drott@chromium.org>
|
||||
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4324@{#1620}
|
||||
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
|
||||
diff --git a/third_party/ots/README.chromium b/third_party/ots/README.chromium
|
||||
index 8e8aaba85b508110eb9662d5714712dd481e037c..c35d4f71f5af26c19675a3a5d8ef8ee3730c94da 100644
|
||||
--- a/third_party/ots/README.chromium
|
||||
+++ b/third_party/ots/README.chromium
|
||||
@@ -11,4 +11,7 @@ Local Modifications:
|
||||
- BUILD.gn: Added.
|
||||
- fuzz/: Added.
|
||||
- ots.cc: Allow CFF2 outlines, upstreamed in
|
||||
- https://github.com/khaledhosny/ots/pull/161
|
||||
\ No newline at end of file
|
||||
+ https://github.com/khaledhosny/ots/pull/161
|
||||
+- glyf.h, glyf.cc - Backport of "Sanitise values for fonts with invalid
|
||||
+ maxPoints and maxComponentPoints"
|
||||
+ https://github.com/khaledhosny/ots/pull/227
|
||||
diff --git a/third_party/ots/src/glyf.cc b/third_party/ots/src/glyf.cc
|
||||
index b8fb2866da7d16c2cafc470dcc10277a19bd325a..8d2e498ea8f48160e06de8200f2afc6e598252df 100644
|
||||
--- a/third_party/ots/src/glyf.cc
|
||||
+++ b/third_party/ots/src/glyf.cc
|
||||
@@ -99,6 +99,11 @@ bool OpenTypeGLYF::ParseSimpleGlyph(Buffer &glyph,
|
||||
num_flags = tmp_index + 1;
|
||||
}
|
||||
|
||||
+ if (num_flags > this->maxp->max_points) {
|
||||
+ Warning("Number of contour points exceeds maxp maxPoints, adjusting limit.");
|
||||
+ this->maxp->max_points = num_flags;
|
||||
+ }
|
||||
+
|
||||
uint16_t bytecode_length = 0;
|
||||
if (!glyph.ReadU16(&bytecode_length)) {
|
||||
return Error("Can't read bytecode length");
|
||||
@@ -143,7 +148,9 @@ bool OpenTypeGLYF::ParseSimpleGlyph(Buffer &glyph,
|
||||
#define WE_HAVE_A_TWO_BY_TWO (1u << 7)
|
||||
#define WE_HAVE_INSTRUCTIONS (1u << 8)
|
||||
|
||||
-bool OpenTypeGLYF::ParseCompositeGlyph(Buffer &glyph) {
|
||||
+bool OpenTypeGLYF::ParseCompositeGlyph(
|
||||
+ Buffer &glyph,
|
||||
+ ComponentPointCount* component_point_count) {
|
||||
uint16_t flags = 0;
|
||||
uint16_t gid = 0;
|
||||
do {
|
||||
@@ -192,6 +199,10 @@ bool OpenTypeGLYF::ParseCompositeGlyph(Buffer &glyph) {
|
||||
return Error("Can't read transform");
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Push inital components on stack at level 1
|
||||
+ // to traverse them in parent function.
|
||||
+ component_point_count->gid_stack.push_back({gid, 1});
|
||||
} while (flags & MORE_COMPONENTS);
|
||||
|
||||
if (flags & WE_HAVE_INSTRUCTIONS) {
|
||||
@@ -241,29 +252,16 @@ bool OpenTypeGLYF::Parse(const uint8_t *data, size_t length) {
|
||||
uint32_t current_offset = 0;
|
||||
|
||||
for (unsigned i = 0; i < num_glyphs; ++i) {
|
||||
- const unsigned gly_offset = offsets[i];
|
||||
- // The LOCA parser checks that these values are monotonic
|
||||
- const unsigned gly_length = offsets[i + 1] - offsets[i];
|
||||
- if (!gly_length) {
|
||||
- // this glyph has no outline (e.g. the space charactor)
|
||||
+
|
||||
+ Buffer glyph(GetGlyphBufferSection(data, length, offsets, i));
|
||||
+ if (!glyph.buffer())
|
||||
+ return false;
|
||||
+
|
||||
+ if (!glyph.length()) {
|
||||
resulting_offsets[i] = current_offset;
|
||||
continue;
|
||||
}
|
||||
|
||||
- if (gly_offset >= length) {
|
||||
- return Error("Glyph %d offset %d too high %ld", i, gly_offset, length);
|
||||
- }
|
||||
- // Since these are unsigned types, the compiler is not allowed to assume
|
||||
- // that they never overflow.
|
||||
- if (gly_offset + gly_length < gly_offset) {
|
||||
- return Error("Glyph %d length (%d < 0)!", i, gly_length);
|
||||
- }
|
||||
- if (gly_offset + gly_length > length) {
|
||||
- return Error("Glyph %d length %d too high", i, gly_length);
|
||||
- }
|
||||
-
|
||||
- Buffer glyph(data + gly_offset, gly_length);
|
||||
-
|
||||
int16_t num_contours, xmin, ymin, xmax, ymax;
|
||||
if (!glyph.ReadS16(&num_contours) ||
|
||||
!glyph.ReadS16(&xmin) ||
|
||||
@@ -300,9 +298,56 @@ bool OpenTypeGLYF::Parse(const uint8_t *data, size_t length) {
|
||||
return Error("Failed to parse glyph %d", i);
|
||||
}
|
||||
} else {
|
||||
- if (!ParseCompositeGlyph(glyph)) {
|
||||
+
|
||||
+ ComponentPointCount component_point_count;
|
||||
+ if (!ParseCompositeGlyph(glyph, &component_point_count)) {
|
||||
return Error("Failed to parse glyph %d", i);
|
||||
}
|
||||
+
|
||||
+ // Check maxComponentDepth and validate maxComponentPoints.
|
||||
+ // ParseCompositeGlyph placed the first set of component glyphs on the
|
||||
+ // component_point_count.gid_stack, which we start to process below. If a
|
||||
+ // nested glyph is in turn a component glyph, additional glyphs are placed
|
||||
+ // on the stack.
|
||||
+ while (component_point_count.gid_stack.size()) {
|
||||
+ GidAtLevel stack_top_gid = component_point_count.gid_stack.back();
|
||||
+ component_point_count.gid_stack.pop_back();
|
||||
+
|
||||
+ Buffer points_count_glyph(GetGlyphBufferSection(
|
||||
+ data,
|
||||
+ length,
|
||||
+ offsets,
|
||||
+ stack_top_gid.gid));
|
||||
+
|
||||
+ if (!points_count_glyph.buffer())
|
||||
+ return false;
|
||||
+
|
||||
+ if (!points_count_glyph.length())
|
||||
+ continue;
|
||||
+
|
||||
+ if (!TraverseComponentsCountingPoints(points_count_glyph,
|
||||
+ i,
|
||||
+ stack_top_gid.level,
|
||||
+ &component_point_count)) {
|
||||
+ return Error("Error validating component points and depth.");
|
||||
+ }
|
||||
+
|
||||
+ if (component_point_count.accumulated_component_points >
|
||||
+ std::numeric_limits<uint16_t>::max()) {
|
||||
+ return Error("Illegal composite points value "
|
||||
+ "exceeding 0xFFFF for base glyph %d.", i);
|
||||
+ } else if (component_point_count.accumulated_component_points >
|
||||
+ this->maxp->max_c_points) {
|
||||
+ Warning("Number of composite points in glyph %d exceeds "
|
||||
+ "maxp maxCompositePoints: %d vs %d, adjusting limit.",
|
||||
+ i,
|
||||
+ component_point_count.accumulated_component_points,
|
||||
+ this->maxp->max_c_points
|
||||
+ );
|
||||
+ this->maxp->max_c_points =
|
||||
+ component_point_count.accumulated_component_points;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
size_t new_size = glyph.offset();
|
||||
@@ -342,6 +387,122 @@ bool OpenTypeGLYF::Parse(const uint8_t *data, size_t length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+bool OpenTypeGLYF::TraverseComponentsCountingPoints(
|
||||
+ Buffer &glyph,
|
||||
+ uint16_t base_glyph_id,
|
||||
+ uint32_t level,
|
||||
+ ComponentPointCount* component_point_count) {
|
||||
+
|
||||
+ int16_t num_contours;
|
||||
+ if (!glyph.ReadS16(&num_contours) ||
|
||||
+ !glyph.Skip(8)) {
|
||||
+ return Error("Can't read glyph header.");
|
||||
+ }
|
||||
+
|
||||
+ if (num_contours <= -2) {
|
||||
+ return Error("Bad number of contours %d in glyph.", num_contours);
|
||||
+ }
|
||||
+
|
||||
+ if (num_contours == 0)
|
||||
+ return true;
|
||||
+
|
||||
+ // FontTools counts a component level for each traversed recursion. We start
|
||||
+ // counting at level 0. If we reach a level that's deeper than
|
||||
+ // maxComponentDepth, we expand maxComponentDepth unless it's larger than
|
||||
+ // the maximum possible depth.
|
||||
+ if (level > std::numeric_limits<uint16_t>::max()) {
|
||||
+ return Error("Illegal component depth exceeding 0xFFFF in base glyph id %d.",
|
||||
+ base_glyph_id);
|
||||
+ } else if (level > this->maxp->max_c_depth) {
|
||||
+ this->maxp->max_c_depth = level;
|
||||
+ Warning("Component depth exceeds maxp maxComponentDepth "
|
||||
+ "in glyph %d, adjust limit to %d.",
|
||||
+ base_glyph_id, level);
|
||||
+ }
|
||||
+
|
||||
+ if (num_contours > 0) {
|
||||
+ uint16_t num_points = 0;
|
||||
+ for (int i = 0; i < num_contours; ++i) {
|
||||
+ // Simple glyph, add contour points.
|
||||
+ uint16_t tmp_index = 0;
|
||||
+ if (!glyph.ReadU16(&tmp_index)) {
|
||||
+ return Error("Can't read contour index %d", i);
|
||||
+ }
|
||||
+ num_points = tmp_index + 1;
|
||||
+ }
|
||||
+
|
||||
+ component_point_count->accumulated_component_points += num_points;
|
||||
+ return true;
|
||||
+ } else {
|
||||
+ assert(num_contours == -1);
|
||||
+
|
||||
+ // Composite glyph, add gid's to stack.
|
||||
+ uint16_t flags = 0;
|
||||
+ uint16_t gid = 0;
|
||||
+ do {
|
||||
+ if (!glyph.ReadU16(&flags) || !glyph.ReadU16(&gid)) {
|
||||
+ return Error("Can't read composite glyph flags or glyphIndex");
|
||||
+ }
|
||||
+
|
||||
+ size_t skip_bytes = 0;
|
||||
+ skip_bytes += flags & ARG_1_AND_2_ARE_WORDS ? 4 : 2;
|
||||
+
|
||||
+ if (flags & WE_HAVE_A_SCALE) {
|
||||
+ skip_bytes += 2;
|
||||
+ } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
|
||||
+ skip_bytes += 4;
|
||||
+ } else if (flags & WE_HAVE_A_TWO_BY_TWO) {
|
||||
+ skip_bytes += 8;
|
||||
+ }
|
||||
+
|
||||
+ if (!glyph.Skip(skip_bytes)) {
|
||||
+ return Error("Failed to parse component glyph.");
|
||||
+ }
|
||||
+
|
||||
+ if (gid >= this->maxp->num_glyphs) {
|
||||
+ return Error("Invalid glyph id used in composite glyph: %d", gid);
|
||||
+ }
|
||||
+
|
||||
+ component_point_count->gid_stack.push_back({gid, level + 1u});
|
||||
+ } while (flags & MORE_COMPONENTS);
|
||||
+ return true;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+Buffer OpenTypeGLYF::GetGlyphBufferSection(
|
||||
+ const uint8_t *data,
|
||||
+ size_t length,
|
||||
+ const std::vector<uint32_t>& loca_offsets,
|
||||
+ unsigned glyph_id) {
|
||||
+
|
||||
+ Buffer null_buffer(nullptr, 0);
|
||||
+
|
||||
+ const unsigned gly_offset = loca_offsets[glyph_id];
|
||||
+ // The LOCA parser checks that these values are monotonic
|
||||
+ const unsigned gly_length = loca_offsets[glyph_id + 1] - loca_offsets[glyph_id];
|
||||
+ if (!gly_length) {
|
||||
+ // this glyph has no outline (e.g. the space character)
|
||||
+ return Buffer(data + gly_offset, 0);
|
||||
+ }
|
||||
+
|
||||
+ if (gly_offset >= length) {
|
||||
+ Error("Glyph %d offset %d too high %ld", glyph_id, gly_offset, length);
|
||||
+ return null_buffer;
|
||||
+ }
|
||||
+ // Since these are unsigned types, the compiler is not allowed to assume
|
||||
+ // that they never overflow.
|
||||
+ if (gly_offset + gly_length < gly_offset) {
|
||||
+ Error("Glyph %d length (%d < 0)!", glyph_id, gly_length);
|
||||
+ return null_buffer;
|
||||
+ }
|
||||
+ if (gly_offset + gly_length > length) {
|
||||
+ Error("Glyph %d length %d too high", glyph_id, gly_length);
|
||||
+ return null_buffer;
|
||||
+ }
|
||||
+
|
||||
+ return Buffer(data + gly_offset, gly_length);
|
||||
+}
|
||||
+
|
||||
bool OpenTypeGLYF::Serialize(OTSStream *out) {
|
||||
for (unsigned i = 0; i < this->iov.size(); ++i) {
|
||||
if (!out->Write(this->iov[i].first, this->iov[i].second)) {
|
||||
diff --git a/third_party/ots/src/glyf.h b/third_party/ots/src/glyf.h
|
||||
index 1da94e4b9455c47371ffb07a39921be1aaca61e8..08c585df349db447a7b9bfa0fd2e8dde31728e5d 100644
|
||||
--- a/third_party/ots/src/glyf.h
|
||||
+++ b/third_party/ots/src/glyf.h
|
||||
@@ -23,12 +23,38 @@ class OpenTypeGLYF : public Table {
|
||||
bool Serialize(OTSStream *out);
|
||||
|
||||
private:
|
||||
+ struct GidAtLevel {
|
||||
+ uint16_t gid;
|
||||
+ uint32_t level;
|
||||
+ };
|
||||
+
|
||||
+ struct ComponentPointCount {
|
||||
+ ComponentPointCount() : accumulated_component_points(0) {};
|
||||
+ uint32_t accumulated_component_points;
|
||||
+ std::vector<GidAtLevel> gid_stack;
|
||||
+ };
|
||||
+
|
||||
bool ParseFlagsForSimpleGlyph(Buffer &glyph,
|
||||
uint32_t num_flags,
|
||||
uint32_t *flag_index,
|
||||
uint32_t *coordinates_length);
|
||||
bool ParseSimpleGlyph(Buffer &glyph, int16_t num_contours);
|
||||
- bool ParseCompositeGlyph(Buffer &glyph);
|
||||
+ bool ParseCompositeGlyph(
|
||||
+ Buffer &glyph,
|
||||
+ ComponentPointCount* component_point_count);
|
||||
+
|
||||
+
|
||||
+ bool TraverseComponentsCountingPoints(
|
||||
+ Buffer& glyph,
|
||||
+ uint16_t base_glyph_id,
|
||||
+ uint32_t level,
|
||||
+ ComponentPointCount* component_point_count);
|
||||
+
|
||||
+ Buffer GetGlyphBufferSection(
|
||||
+ const uint8_t *data,
|
||||
+ size_t length,
|
||||
+ const std::vector<uint32_t>& loca_offsets,
|
||||
+ unsigned glyph_id);
|
||||
|
||||
OpenTypeMAXP* maxp;
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Dominik=20R=C3=B6ttsches?= <drott@chromium.org>
|
||||
Date: Mon, 11 Jan 2021 14:33:32 +0000
|
||||
Subject: Backport of "[glyf] Guard access to maxp version 1 field"
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
(cherry picked from commit fac68744a85e8c601f60f1ef73a6e9ddf150855e)
|
||||
|
||||
Bug: 1153329, 1158774
|
||||
Change-Id: I6acd298f841f92a751f606d710415fe32343825f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2593261
|
||||
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
|
||||
Auto-Submit: Dominik Röttsches <drott@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#837353}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2621064
|
||||
Commit-Queue: Dominik Röttsches <drott@chromium.org>
|
||||
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4324@{#1625}
|
||||
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
|
||||
diff --git a/third_party/ots/README.chromium b/third_party/ots/README.chromium
|
||||
index c35d4f71f5af26c19675a3a5d8ef8ee3730c94da..43ddc08a0e1a65bb084b60d66c641c911cfba279 100644
|
||||
--- a/third_party/ots/README.chromium
|
||||
+++ b/third_party/ots/README.chromium
|
||||
@@ -15,3 +15,5 @@ Local Modifications:
|
||||
- glyf.h, glyf.cc - Backport of "Sanitise values for fonts with invalid
|
||||
maxPoints and maxComponentPoints"
|
||||
https://github.com/khaledhosny/ots/pull/227
|
||||
+- glyf.cc - Backport of "[glyf] Guard access to maxp version 1 field"
|
||||
+ Upstream commit 1141c81c411b599e40496679129d0884715e8650
|
||||
diff --git a/third_party/ots/src/glyf.cc b/third_party/ots/src/glyf.cc
|
||||
index 8d2e498ea8f48160e06de8200f2afc6e598252df..ab9232ea2dcb5fe0ea2b4d3274b11103c85e51fa 100644
|
||||
--- a/third_party/ots/src/glyf.cc
|
||||
+++ b/third_party/ots/src/glyf.cc
|
||||
@@ -99,7 +99,8 @@ bool OpenTypeGLYF::ParseSimpleGlyph(Buffer &glyph,
|
||||
num_flags = tmp_index + 1;
|
||||
}
|
||||
|
||||
- if (num_flags > this->maxp->max_points) {
|
||||
+ if (this->maxp->version_1 &&
|
||||
+ num_flags > this->maxp->max_points) {
|
||||
Warning("Number of contour points exceeds maxp maxPoints, adjusting limit.");
|
||||
this->maxp->max_points = num_flags;
|
||||
}
|
||||
@@ -336,7 +337,8 @@ bool OpenTypeGLYF::Parse(const uint8_t *data, size_t length) {
|
||||
std::numeric_limits<uint16_t>::max()) {
|
||||
return Error("Illegal composite points value "
|
||||
"exceeding 0xFFFF for base glyph %d.", i);
|
||||
- } else if (component_point_count.accumulated_component_points >
|
||||
+ } else if (this->maxp->version_1 &&
|
||||
+ component_point_count.accumulated_component_points >
|
||||
this->maxp->max_c_points) {
|
||||
Warning("Number of composite points in glyph %d exceeds "
|
||||
"maxp maxCompositePoints: %d vs %d, adjusting limit.",
|
||||
@@ -413,7 +415,8 @@ bool OpenTypeGLYF::TraverseComponentsCountingPoints(
|
||||
if (level > std::numeric_limits<uint16_t>::max()) {
|
||||
return Error("Illegal component depth exceeding 0xFFFF in base glyph id %d.",
|
||||
base_glyph_id);
|
||||
- } else if (level > this->maxp->max_c_depth) {
|
||||
+ } else if (this->maxp->version_1 &&
|
||||
+ level > this->maxp->max_c_depth) {
|
||||
this->maxp->max_c_depth = level;
|
||||
Warning("Component depth exceeds maxp maxComponentDepth "
|
||||
"in glyph %d, adjust limit to %d.",
|
||||
@@ -0,0 +1,476 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Date: Tue, 8 Dec 2020 07:20:47 +0000
|
||||
Subject: Reland "Reland "[FSA] Add IsSafePathComponent checks to
|
||||
GetFile/GetDirectoryHandle.""
|
||||
|
||||
This is a reland of 2d41c3952d2851948a09ddcf3e97bae6c419b024
|
||||
|
||||
The added test was modified to no longer assert that all unsafe files
|
||||
were written to disk successfully. This should make the test pass (albeit
|
||||
with less stringent checks) on file systems/platforms that don't allow
|
||||
all unsafe file names.
|
||||
|
||||
Original change's description:
|
||||
> Reland "[FSA] Add IsSafePathComponent checks to GetFile/GetDirectoryHandle."
|
||||
>
|
||||
> This is a reland of 004377929febd7cf7392932b01df7f4a0a362679
|
||||
>
|
||||
> The main difference is to make sure iterating over a directory doesn't
|
||||
> return files we don't want to expose either (and not CHECK failing if
|
||||
> such files are found when iterating).
|
||||
>
|
||||
> Original change's description:
|
||||
> > [FSA] Add IsSafePathComponent checks to GetFile/GetDirectoryHandle.
|
||||
> >
|
||||
> > This isn't directly using net::IsSafePortablePathComponent since what
|
||||
> > is safe for the File System Access API is not the same as what is safe
|
||||
> > for Downloads. As such currently this duplicates a lot of the
|
||||
> > implementation of this method, but in a followup we should attempt to
|
||||
> > unify these two implementations as much as possible.
|
||||
> >
|
||||
> > Bug: 1150810, 1154757
|
||||
> > Change-Id: Iba4c92ef5f1cd924aa22b9dd201762d48b4bbc3b
|
||||
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2568383
|
||||
> > Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
|
||||
> > Reviewed-by: Victor Costan <pwnall@chromium.org>
|
||||
> > Cr-Commit-Position: refs/heads/master@{#833042}
|
||||
>
|
||||
> Bug: 1150810
|
||||
> Bug: 1154757
|
||||
> Change-Id: I3341b9824a1ac4cbd6f100355960ad55b01f0753
|
||||
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2575370
|
||||
> Commit-Queue: Victor Costan <pwnall@chromium.org>
|
||||
> Reviewed-by: Victor Costan <pwnall@chromium.org>
|
||||
> Cr-Commit-Position: refs/heads/master@{#834118}
|
||||
|
||||
Bug: 1150810
|
||||
Bug: 1154757
|
||||
Change-Id: Ie5cad9a7b2383c89b96e8a7be6cfe75ad2555fa6
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2577614
|
||||
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Auto-Submit: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Reviewed-by: Victor Costan <pwnall@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#834598}
|
||||
|
||||
diff --git a/content/browser/native_file_system/native_file_system_directory_handle_impl.cc b/content/browser/native_file_system/native_file_system_directory_handle_impl.cc
|
||||
index 89ea8eaf06595607b7c54f96318ad0f984690b99..fff61f2a648d9be70c50115a446bea5b14c3b3ce 100644
|
||||
--- a/content/browser/native_file_system/native_file_system_directory_handle_impl.cc
|
||||
+++ b/content/browser/native_file_system/native_file_system_directory_handle_impl.cc
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "content/browser/native_file_system/native_file_system_directory_handle_impl.h"
|
||||
|
||||
+#include "base/i18n/file_util_icu.h"
|
||||
#include "base/strings/strcat.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
@@ -12,6 +13,7 @@
|
||||
#include "content/browser/native_file_system/native_file_system_transfer_token_impl.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "net/base/escape.h"
|
||||
+#include "net/base/filename_util.h"
|
||||
#include "storage/browser/file_system/file_system_context.h"
|
||||
#include "storage/browser/file_system/file_system_operation_runner.h"
|
||||
#include "storage/common/file_system/file_system_util.h"
|
||||
@@ -28,27 +30,6 @@ using storage::FileSystemOperationRunner;
|
||||
|
||||
namespace content {
|
||||
|
||||
-namespace {
|
||||
-
|
||||
-// Returns true when |name| contains a path separator like "/".
|
||||
-bool ContainsPathSeparator(const std::string& name) {
|
||||
- const base::FilePath filepath_name = storage::StringToFilePath(name);
|
||||
-
|
||||
- const size_t separator_position =
|
||||
- filepath_name.value().find_first_of(base::FilePath::kSeparators);
|
||||
-
|
||||
- return separator_position != base::FilePath::StringType::npos;
|
||||
-}
|
||||
-
|
||||
-// Returns true when |name| is "." or "..".
|
||||
-bool IsCurrentOrParentDirectory(const std::string& name) {
|
||||
- const base::FilePath filepath_name = storage::StringToFilePath(name);
|
||||
- return filepath_name.value() == base::FilePath::kCurrentDirectory ||
|
||||
- filepath_name.value() == base::FilePath::kParentDirectory;
|
||||
-}
|
||||
-
|
||||
-} // namespace
|
||||
-
|
||||
NativeFileSystemDirectoryHandleImpl::NativeFileSystemDirectoryHandleImpl(
|
||||
NativeFileSystemManagerImpl* manager,
|
||||
const BindingContext& context,
|
||||
@@ -387,9 +368,10 @@ void NativeFileSystemDirectoryHandleImpl::DidReadDirectory(
|
||||
blink::mojom::NativeFileSystemErrorPtr get_child_url_result =
|
||||
GetChildURL(basename, &child_url);
|
||||
|
||||
- // All entries must exist in this directory as a direct child with a valid
|
||||
- // |basename|.
|
||||
- CHECK_EQ(get_child_url_result->status, NativeFileSystemStatus::kOk);
|
||||
+ // Skip any entries with names that aren't allowed to be accessed by
|
||||
+ // this API, such as files with disallowed characters in their names.
|
||||
+ if (get_child_url_result->status != NativeFileSystemStatus::kOk)
|
||||
+ continue;
|
||||
|
||||
entries.push_back(
|
||||
CreateEntry(basename, child_url,
|
||||
@@ -418,25 +400,99 @@ void NativeFileSystemDirectoryHandleImpl::RemoveEntryImpl(
|
||||
url, recurse);
|
||||
}
|
||||
|
||||
+namespace {
|
||||
+
|
||||
+// Returns whether the specified extension receives special handling by the
|
||||
+// Windows shell.
|
||||
+bool IsShellIntegratedExtension(const base::FilePath::StringType& extension) {
|
||||
+ base::FilePath::StringType extension_lower = base::ToLowerASCII(extension);
|
||||
+
|
||||
+ // .lnk files may be used to execute arbitrary code (see
|
||||
+ // https://nvd.nist.gov/vuln/detail/CVE-2010-2568).
|
||||
+ if (extension_lower == FILE_PATH_LITERAL("lnk"))
|
||||
+ return true;
|
||||
+
|
||||
+ // Setting a file's extension to a CLSID may conceal its actual file type on
|
||||
+ // some Windows versions (see https://nvd.nist.gov/vuln/detail/CVE-2004-0420).
|
||||
+ if (!extension_lower.empty() &&
|
||||
+ (extension_lower.front() == FILE_PATH_LITERAL('{')) &&
|
||||
+ (extension_lower.back() == FILE_PATH_LITERAL('}')))
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+// static
|
||||
+bool NativeFileSystemDirectoryHandleImpl::IsSafePathComponent(
|
||||
+ const std::string& name) {
|
||||
+ // This method is similar to net::IsSafePortablePathComponent, with a few
|
||||
+ // notable differences where the net version does not consider names safe
|
||||
+ // while here we do want to allow them. These cases are:
|
||||
+ // - Names starting with a '.'. These would be hidden files in most file
|
||||
+ // managers, but are something we explicitly want to support for the
|
||||
+ // File System Access API, for names like .git.
|
||||
+ // - Names that end in '.local'. For downloads writing to such files is
|
||||
+ // dangerous since it might modify what code is executed when an executable
|
||||
+ // is ran from the same directory. For the File System Access API this
|
||||
+ // isn't really a problem though, since if a website can write to a .local
|
||||
+ // file via a FileSystemDirectoryHandle they can also just modify the
|
||||
+ // executables in the directory directly.
|
||||
+ //
|
||||
+ // TODO(https://crbug.com/1154757): Unify this with
|
||||
+ // net::IsSafePortablePathComponent, with the result probably ending up in
|
||||
+ // base/i18n/file_util_icu.h.
|
||||
+
|
||||
+ const base::FilePath component = storage::StringToFilePath(name);
|
||||
+ // Empty names, or names that contain path separators are invalid.
|
||||
+ if (component.empty() || component != component.BaseName() ||
|
||||
+ component != component.StripTrailingSeparators()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ base::string16 component16;
|
||||
+#if defined(OS_WIN)
|
||||
+ component16.assign(component.value().begin(), component.value().end());
|
||||
+#else
|
||||
+ std::string component8 = component.AsUTF8Unsafe();
|
||||
+ if (!base::UTF8ToUTF16(component8.c_str(), component8.size(), &component16))
|
||||
+ return false;
|
||||
+#endif
|
||||
+ // base::i18n::IsFilenameLegal blocks names that start with '.', so strip out
|
||||
+ // a leading '.' before passing it to that method.
|
||||
+ // TODO(mek): Consider making IsFilenameLegal more flexible to support this
|
||||
+ // use case.
|
||||
+ if (component16[0] == '.')
|
||||
+ component16 = component16.substr(1);
|
||||
+ if (!base::i18n::IsFilenameLegal(component16))
|
||||
+ return false;
|
||||
+
|
||||
+ base::FilePath::StringType extension = component.Extension();
|
||||
+ if (!extension.empty())
|
||||
+ extension.erase(extension.begin()); // Erase preceding '.'.
|
||||
+ if (IsShellIntegratedExtension(extension))
|
||||
+ return false;
|
||||
+
|
||||
+ if (base::TrimString(component.value(), FILE_PATH_LITERAL("."),
|
||||
+ base::TRIM_TRAILING) != component.value()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (net::IsReservedNameOnWindows(component.value()))
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+
|
||||
blink::mojom::NativeFileSystemErrorPtr
|
||||
NativeFileSystemDirectoryHandleImpl::GetChildURL(
|
||||
const std::string& basename,
|
||||
storage::FileSystemURL* result) {
|
||||
- // TODO(mek): Rather than doing URL serialization and parsing we should just
|
||||
- // have a way to get a child FileSystemURL directly from its parent.
|
||||
-
|
||||
- if (basename.empty()) {
|
||||
- return native_file_system_error::FromStatus(
|
||||
- NativeFileSystemStatus::kInvalidArgument,
|
||||
- "Name can't be an empty string.");
|
||||
- }
|
||||
|
||||
- if (ContainsPathSeparator(basename) || IsCurrentOrParentDirectory(basename)) {
|
||||
- // |basename| must refer to a entry that exists in this directory as a
|
||||
- // direct child.
|
||||
+ if (!IsSafePathComponent(basename)) {
|
||||
return native_file_system_error::FromStatus(
|
||||
- NativeFileSystemStatus::kInvalidArgument,
|
||||
- "Name contains invalid characters.");
|
||||
+ NativeFileSystemStatus::kInvalidArgument, "Name is not allowed.");
|
||||
}
|
||||
|
||||
std::string escaped_name =
|
||||
diff --git a/content/browser/native_file_system/native_file_system_directory_handle_impl.h b/content/browser/native_file_system/native_file_system_directory_handle_impl.h
|
||||
index 061ffbb26d13966bc1d4da6c31fd17687d31422a..7ff29b706da905dbb30328bfe854cd052f2b84bb 100644
|
||||
--- a/content/browser/native_file_system/native_file_system_directory_handle_impl.h
|
||||
+++ b/content/browser/native_file_system/native_file_system_directory_handle_impl.h
|
||||
@@ -57,6 +57,14 @@ class CONTENT_EXPORT NativeFileSystemDirectoryHandleImpl
|
||||
mojo::PendingReceiver<blink::mojom::NativeFileSystemTransferToken> token)
|
||||
override;
|
||||
|
||||
+ // The File System Access API should not give access to files that might
|
||||
+ // trigger special handling from the operating system. This method is used to
|
||||
+ // validate that all paths passed to GetFileHandle/GetDirectoryHandle are safe
|
||||
+ // to be exposed to the web.
|
||||
+ // TODO(https://crbug.com/1154757): Merge this with
|
||||
+ // net::IsSafePortablePathComponent.
|
||||
+ static bool IsSafePathComponent(const std::string& name);
|
||||
+
|
||||
private:
|
||||
// This method creates the file if it does not currently exists. I.e. it is
|
||||
// the implementation for passing create=true to GetFile.
|
||||
diff --git a/content/browser/native_file_system/native_file_system_directory_handle_impl_unittest.cc b/content/browser/native_file_system/native_file_system_directory_handle_impl_unittest.cc
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..8f5e109c78cebecca1a9724327ceb1fefa01e6db
|
||||
--- /dev/null
|
||||
+++ b/content/browser/native_file_system/native_file_system_directory_handle_impl_unittest.cc
|
||||
@@ -0,0 +1,196 @@
|
||||
+// Copyright 2020 The Chromium Authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+#include "content/browser/native_file_system/native_file_system_directory_handle_impl.h"
|
||||
+
|
||||
+#include <iterator>
|
||||
+#include <string>
|
||||
+
|
||||
+#include "base/bind.h"
|
||||
+#include "base/files/file_util.h"
|
||||
+#include "base/files/scoped_temp_dir.h"
|
||||
+#include "base/macros.h"
|
||||
+#include "base/run_loop.h"
|
||||
+#include "base/test/bind.h"
|
||||
+#include "base/test/task_environment.h"
|
||||
+#include "build/build_config.h"
|
||||
+#include "content/browser/native_file_system/fixed_native_file_system_permission_grant.h"
|
||||
+#include "content/public/test/browser_task_environment.h"
|
||||
+#include "storage/browser/test/test_file_system_context.h"
|
||||
+#include "testing/gmock/include/gmock/gmock.h"
|
||||
+#include "testing/gtest/include/gtest/gtest.h"
|
||||
+
|
||||
+namespace content {
|
||||
+
|
||||
+using storage::FileSystemURL;
|
||||
+
|
||||
+class NativeFileSystemDirectoryHandleImplTest : public testing::Test {
|
||||
+ public:
|
||||
+ NativeFileSystemDirectoryHandleImplTest()
|
||||
+ : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}
|
||||
+
|
||||
+ void SetUp() override {
|
||||
+ ASSERT_TRUE(dir_.CreateUniqueTempDir());
|
||||
+
|
||||
+ file_system_context_ = storage::CreateFileSystemContextForTesting(
|
||||
+ /*quota_manager_proxy=*/nullptr, dir_.GetPath());
|
||||
+
|
||||
+ chrome_blob_context_ = base::MakeRefCounted<ChromeBlobStorageContext>();
|
||||
+ chrome_blob_context_->InitializeOnIOThread(base::FilePath(),
|
||||
+ base::FilePath(), nullptr);
|
||||
+
|
||||
+ manager_ = base::MakeRefCounted<NativeFileSystemManagerImpl>(
|
||||
+ file_system_context_, chrome_blob_context_,
|
||||
+ /*permission_context=*/nullptr,
|
||||
+ /*off_the_record=*/false);
|
||||
+
|
||||
+ auto url_and_fs = manager_->CreateFileSystemURLFromPath(
|
||||
+ test_src_origin_, NativeFileSystemEntryFactory::PathType::kLocal,
|
||||
+ dir_.GetPath());
|
||||
+
|
||||
+ handle_ = std::make_unique<NativeFileSystemDirectoryHandleImpl>(
|
||||
+ manager_.get(),
|
||||
+ NativeFileSystemManagerImpl::BindingContext(
|
||||
+ test_src_origin_, test_src_url_, /*worker_process_id=*/1),
|
||||
+ url_and_fs.url,
|
||||
+ NativeFileSystemManagerImpl::SharedHandleState(
|
||||
+ allow_grant_, allow_grant_, std::move(url_and_fs.file_system)));
|
||||
+ }
|
||||
+
|
||||
+ void TearDown() override { task_environment_.RunUntilIdle(); }
|
||||
+
|
||||
+ protected:
|
||||
+ const GURL test_src_url_ = GURL("http://example.com/foo");
|
||||
+ const url::Origin test_src_origin_ = url::Origin::Create(test_src_url_);
|
||||
+
|
||||
+ BrowserTaskEnvironment task_environment_;
|
||||
+
|
||||
+ base::ScopedTempDir dir_;
|
||||
+ scoped_refptr<storage::FileSystemContext> file_system_context_;
|
||||
+ scoped_refptr<ChromeBlobStorageContext> chrome_blob_context_;
|
||||
+ scoped_refptr<NativeFileSystemManagerImpl> manager_;
|
||||
+
|
||||
+ scoped_refptr<FixedNativeFileSystemPermissionGrant> allow_grant_ =
|
||||
+ base::MakeRefCounted<FixedNativeFileSystemPermissionGrant>(
|
||||
+ FixedNativeFileSystemPermissionGrant::PermissionStatus::GRANTED,
|
||||
+ base::FilePath());
|
||||
+ std::unique_ptr<NativeFileSystemDirectoryHandleImpl> handle_;
|
||||
+};
|
||||
+
|
||||
+TEST_F(NativeFileSystemDirectoryHandleImplTest, IsSafePathComponent) {
|
||||
+ constexpr const char* kSafePathComponents[] = {
|
||||
+ "a", "a.txt", "a b.txt", "My Computer", ".a", "lnk.zip", "lnk", "a.local",
|
||||
+ };
|
||||
+
|
||||
+ constexpr const char* kUnsafePathComponents[] = {
|
||||
+ "",
|
||||
+ ".",
|
||||
+ "..",
|
||||
+ "...",
|
||||
+ "con",
|
||||
+ "con.zip",
|
||||
+ "NUL",
|
||||
+ "NUL.zip",
|
||||
+ "a.",
|
||||
+ "a\"a",
|
||||
+ "a<a",
|
||||
+ "a>a",
|
||||
+ "a?a",
|
||||
+ "a/",
|
||||
+ "a\\",
|
||||
+ "a ",
|
||||
+ "a . .",
|
||||
+ " Computer",
|
||||
+ "My Computer.{a}",
|
||||
+ "My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
|
||||
+ "a\\a",
|
||||
+ "a.lnk",
|
||||
+ "a/a",
|
||||
+ "C:\\",
|
||||
+ "C:/",
|
||||
+ "C:",
|
||||
+ };
|
||||
+
|
||||
+ for (const char* component : kSafePathComponents) {
|
||||
+ EXPECT_TRUE(
|
||||
+ NativeFileSystemDirectoryHandleImpl::IsSafePathComponent(component))
|
||||
+ << component;
|
||||
+ }
|
||||
+ for (const char* component : kUnsafePathComponents) {
|
||||
+ EXPECT_FALSE(
|
||||
+ NativeFileSystemDirectoryHandleImpl::IsSafePathComponent(component))
|
||||
+ << component;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+namespace {
|
||||
+class TestNativeFileSystemDirectoryEntriesListener
|
||||
+ : public blink::mojom::NativeFileSystemDirectoryEntriesListener {
|
||||
+ public:
|
||||
+ TestNativeFileSystemDirectoryEntriesListener(
|
||||
+ std::vector<blink::mojom::NativeFileSystemEntryPtr>* entries,
|
||||
+ base::OnceClosure done)
|
||||
+ : entries_(entries), done_(std::move(done)) {}
|
||||
+
|
||||
+ void DidReadDirectory(
|
||||
+ blink::mojom::NativeFileSystemErrorPtr result,
|
||||
+ std::vector<blink::mojom::NativeFileSystemEntryPtr> entries,
|
||||
+ bool has_more_entries) override {
|
||||
+ EXPECT_EQ(result->status, blink::mojom::NativeFileSystemStatus::kOk);
|
||||
+ entries_->insert(entries_->end(), std::make_move_iterator(entries.begin()),
|
||||
+ std::make_move_iterator(entries.end()));
|
||||
+ if (!has_more_entries) {
|
||||
+ std::move(done_).Run();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ std::vector<blink::mojom::NativeFileSystemEntryPtr>* entries_;
|
||||
+ base::OnceClosure done_;
|
||||
+};
|
||||
+} // namespace
|
||||
+
|
||||
+TEST_F(NativeFileSystemDirectoryHandleImplTest, GetEntries) {
|
||||
+ constexpr const char* kSafeNames[] = {"a", "a.txt", "My Computer", "lnk.txt",
|
||||
+ "a.local"};
|
||||
+ constexpr const char* kUnsafeNames[] = {
|
||||
+ "con", "con.zip", "NUL", "a.",
|
||||
+ "a\"a", "a . .", "a.lnk", "My Computer.{a}",
|
||||
+ };
|
||||
+ for (const char* name : kSafeNames) {
|
||||
+ ASSERT_TRUE(base::WriteFile(dir_.GetPath().AppendASCII(name), "data"))
|
||||
+ << name;
|
||||
+ }
|
||||
+ for (const char* name : kUnsafeNames) {
|
||||
+ base::FilePath file_path = dir_.GetPath().AppendASCII(name);
|
||||
+ bool success = base::WriteFile(file_path, "data");
|
||||
+#if !defined(OS_WIN)
|
||||
+ // Some of the unsafe names are not legal file names on Windows. This is
|
||||
+ // okay, and doesn't materially effect the outcome of the test, so just
|
||||
+ // ignore any failures writing these files to disk.
|
||||
+ EXPECT_TRUE(success) << "Failed to create file " << file_path;
|
||||
+#else
|
||||
+ ignore_result(success);
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ std::vector<blink::mojom::NativeFileSystemEntryPtr> entries;
|
||||
+ base::RunLoop loop;
|
||||
+ mojo::PendingRemote<blink::mojom::NativeFileSystemDirectoryEntriesListener>
|
||||
+ listener;
|
||||
+ mojo::MakeSelfOwnedReceiver(
|
||||
+ std::make_unique<TestNativeFileSystemDirectoryEntriesListener>(
|
||||
+ &entries, loop.QuitClosure()),
|
||||
+ listener.InitWithNewPipeAndPassReceiver());
|
||||
+ handle_->GetEntries(std::move(listener));
|
||||
+ loop.Run();
|
||||
+
|
||||
+ std::vector<std::string> names;
|
||||
+ for (const auto& entry : entries) {
|
||||
+ names.push_back(entry->name);
|
||||
+ }
|
||||
+ EXPECT_THAT(names, testing::UnorderedElementsAreArray(kSafeNames));
|
||||
+}
|
||||
+
|
||||
+} // namespace content
|
||||
diff --git a/content/browser/native_file_system/native_file_system_file_handle_impl_unittest.cc b/content/browser/native_file_system/native_file_system_file_handle_impl_unittest.cc
|
||||
index 2cb03f2ad023f90a5f494492becb615fa7c6ddcf..98a794e3426c0c6df1ea1513fb1dff31f47e4227 100644
|
||||
--- a/content/browser/native_file_system/native_file_system_file_handle_impl_unittest.cc
|
||||
+++ b/content/browser/native_file_system/native_file_system_file_handle_impl_unittest.cc
|
||||
@@ -30,8 +30,6 @@
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "third_party/blink/public/common/features.h"
|
||||
|
||||
-using storage::FileSystemURL;
|
||||
-
|
||||
namespace content {
|
||||
|
||||
using blink::mojom::PermissionStatus;
|
||||
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
|
||||
index 6ac9a2997b4071333fbb056a4b0f1d680578bf61..ff01656c305107fba856b39b7f0f955a24dc43a1 100644
|
||||
--- a/content/test/BUILD.gn
|
||||
+++ b/content/test/BUILD.gn
|
||||
@@ -1796,6 +1796,7 @@ test("content_unittests") {
|
||||
"../browser/media/webaudio/audio_context_manager_impl_unittest.cc",
|
||||
"../browser/memory/swap_metrics_driver_impl_unittest.cc",
|
||||
"../browser/native_file_system/file_system_chooser_unittest.cc",
|
||||
+ "../browser/native_file_system/native_file_system_directory_handle_impl_unittest.cc",
|
||||
"../browser/native_file_system/native_file_system_file_handle_impl_unittest.cc",
|
||||
"../browser/native_file_system/native_file_system_file_writer_impl_unittest.cc",
|
||||
"../browser/native_file_system/native_file_system_handle_base_unittest.cc",
|
||||
@@ -0,0 +1,140 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Min Qin <qinmin@chromium.org>
|
||||
Date: Fri, 12 Feb 2021 22:45:08 +0000
|
||||
Subject: Stop using raw WebContents ptr in DragDownloadFile
|
||||
|
||||
BUG=1172192
|
||||
|
||||
(cherry picked from commit 99dc876a13df19f3512bcfb97e794ab5d1b28905)
|
||||
|
||||
Change-Id: Ie029713553ff88c1e271db1c84396e1ddda19286
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2666189
|
||||
Reviewed-by: Xing Liu <xingliu@chromium.org>
|
||||
Commit-Queue: Min Qin <qinmin@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#849692}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2692927
|
||||
Reviewed-by: Shakti Sahu <shaktisahu@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4324@{#2200}
|
||||
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
|
||||
diff --git a/content/browser/download/drag_download_file.cc b/content/browser/download/drag_download_file.cc
|
||||
index 05c110adcbdebd67adc58a5e17b46dbd50ccc220..5dc8fe2214f6b5ef16445196e54ccb668c9fb5ef 100644
|
||||
--- a/content/browser/download/drag_download_file.cc
|
||||
+++ b/content/browser/download/drag_download_file.cc
|
||||
@@ -37,15 +37,17 @@ class DragDownloadFile::DragDownloadFileUI
|
||||
DragDownloadFileUI(const GURL& url,
|
||||
const Referrer& referrer,
|
||||
const std::string& referrer_encoding,
|
||||
- WebContents* web_contents,
|
||||
+ int render_process_id,
|
||||
+ int render_frame_id,
|
||||
OnCompleted on_completed)
|
||||
: on_completed_(std::move(on_completed)),
|
||||
url_(url),
|
||||
referrer_(referrer),
|
||||
referrer_encoding_(referrer_encoding),
|
||||
- web_contents_(web_contents) {
|
||||
+ render_process_id_(render_process_id),
|
||||
+ render_frame_id_(render_frame_id) {
|
||||
DCHECK(on_completed_);
|
||||
- DCHECK(web_contents_);
|
||||
+ DCHECK_GE(render_frame_id_, 0);
|
||||
// May be called on any thread.
|
||||
// Do not call weak_ptr_factory_.GetWeakPtr() outside the UI thread.
|
||||
}
|
||||
@@ -54,6 +56,10 @@ class DragDownloadFile::DragDownloadFileUI
|
||||
const base::FilePath& file_path) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
+ RenderFrameHost* host =
|
||||
+ RenderFrameHost::FromID(render_process_id_, render_frame_id_);
|
||||
+ if (!host)
|
||||
+ return;
|
||||
// TODO(https://crbug.com/614134) This should use the frame actually
|
||||
// containing the link being dragged rather than the main frame of the tab.
|
||||
net::NetworkTrafficAnnotationTag traffic_annotation =
|
||||
@@ -79,9 +85,9 @@ class DragDownloadFile::DragDownloadFileUI
|
||||
}
|
||||
}
|
||||
})");
|
||||
- std::unique_ptr<download::DownloadUrlParameters> params(
|
||||
- DownloadRequestUtils::CreateDownloadForWebContentsMainFrame(
|
||||
- web_contents_, url_, traffic_annotation));
|
||||
+ auto params = std::make_unique<download::DownloadUrlParameters>(
|
||||
+ url_, render_process_id_, host->GetRenderViewHost()->GetRoutingID(),
|
||||
+ render_frame_id_, traffic_annotation);
|
||||
params->set_referrer(referrer_.url);
|
||||
params->set_referrer_policy(
|
||||
Referrer::ReferrerPolicyForUrlRequest(referrer_.policy));
|
||||
@@ -91,7 +97,7 @@ class DragDownloadFile::DragDownloadFileUI
|
||||
params->set_file_path(file_path);
|
||||
params->set_file(std::move(file)); // Nulls file.
|
||||
params->set_download_source(download::DownloadSource::DRAG_AND_DROP);
|
||||
- BrowserContext::GetDownloadManager(web_contents_->GetBrowserContext())
|
||||
+ BrowserContext::GetDownloadManager(host->GetBrowserContext())
|
||||
->DownloadUrl(std::move(params));
|
||||
}
|
||||
|
||||
@@ -165,7 +171,8 @@ class DragDownloadFile::DragDownloadFileUI
|
||||
GURL url_;
|
||||
Referrer referrer_;
|
||||
std::string referrer_encoding_;
|
||||
- WebContents* web_contents_;
|
||||
+ int render_process_id_;
|
||||
+ int render_frame_id_;
|
||||
download::DownloadItem* download_item_ = nullptr;
|
||||
|
||||
// Only used in the callback from DownloadManager::DownloadUrl().
|
||||
@@ -182,8 +189,10 @@ DragDownloadFile::DragDownloadFile(const base::FilePath& file_path,
|
||||
WebContents* web_contents)
|
||||
: file_path_(file_path), file_(std::move(file)) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
+ RenderFrameHost* host = web_contents->GetMainFrame();
|
||||
drag_ui_ = new DragDownloadFileUI(
|
||||
- url, referrer, referrer_encoding, web_contents,
|
||||
+ url, referrer, referrer_encoding, host->GetProcess()->GetID(),
|
||||
+ host->GetRoutingID(),
|
||||
base::BindOnce(&DragDownloadFile::DownloadCompleted,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
DCHECK(!file_path_.empty());
|
||||
diff --git a/content/browser/download/drag_download_file_browsertest.cc b/content/browser/download/drag_download_file_browsertest.cc
|
||||
index 800891a6df4f0d79f1dd0a9cf89b47b882d0f3de..88e248e49898ef55eff694d0979e01bbe69aa2f6 100644
|
||||
--- a/content/browser/download/drag_download_file_browsertest.cc
|
||||
+++ b/content/browser/download/drag_download_file_browsertest.cc
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "content/public/test/content_browser_test.h"
|
||||
#include "content/public/test/content_browser_test_utils.h"
|
||||
#include "content/public/test/download_test_observer.h"
|
||||
+#include "content/public/test/test_utils.h"
|
||||
#include "content/shell/browser/shell.h"
|
||||
#include "content/shell/browser/shell_browser_context.h"
|
||||
#include "content/shell/browser/shell_download_manager_delegate.h"
|
||||
@@ -129,6 +130,28 @@ IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_Complete) {
|
||||
RunUntilSucceed();
|
||||
}
|
||||
|
||||
+IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_ClosePage) {
|
||||
+ base::FilePath name(
|
||||
+ downloads_directory().AppendASCII("DragDownloadFileTest_Complete.txt"));
|
||||
+ GURL url = embedded_test_server()->GetURL("/download/download-test.lib");
|
||||
+ Referrer referrer;
|
||||
+ std::string referrer_encoding;
|
||||
+ auto file = std::make_unique<DragDownloadFile>(name, base::File(), url,
|
||||
+ referrer, referrer_encoding,
|
||||
+ shell()->web_contents());
|
||||
+ scoped_refptr<MockDownloadFileObserver> observer(
|
||||
+ new MockDownloadFileObserver());
|
||||
+ ON_CALL(*observer.get(), OnDownloadAborted())
|
||||
+ .WillByDefault(InvokeWithoutArgs(this, &DragDownloadFileTest::FailFast));
|
||||
+ DownloadManager* manager = BrowserContext::GetDownloadManager(
|
||||
+ shell()->web_contents()->GetBrowserContext());
|
||||
+ file->Start(observer.get());
|
||||
+ shell()->web_contents()->Close();
|
||||
+ RunAllTasksUntilIdle();
|
||||
+ std::vector<download::DownloadItem*> downloads;
|
||||
+ manager->GetAllDownloads(&downloads);
|
||||
+ ASSERT_EQ(0u, downloads.size());
|
||||
+}
|
||||
// TODO(benjhayden): Test Stop().
|
||||
|
||||
} // namespace content
|
||||
@@ -0,0 +1,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Scott Violet <sky@chromium.org>
|
||||
Date: Fri, 13 Nov 2020 20:47:38 +0000
|
||||
Subject: ui: CHECK that UnPremultiply is passed a 32bpp image
|
||||
|
||||
To do otherwise results in accessing random data.
|
||||
|
||||
BUG=1147430
|
||||
TEST=none
|
||||
|
||||
(cherry picked from commit 1f673896837ab8c687d93fec604c96c78c7f679b)
|
||||
|
||||
Change-Id: Icedacbaac64cad3fc903e6423c6f9aad8c1e8cb5
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2531118
|
||||
Commit-Queue: danakj <danakj@chromium.org>
|
||||
Reviewed-by: danakj <danakj@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#826300}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2538047
|
||||
Reviewed-by: Scott Violet <sky@chromium.org>
|
||||
Commit-Queue: Scott Violet <sky@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1452}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/ui/gfx/skbitmap_operations.cc b/ui/gfx/skbitmap_operations.cc
|
||||
index c08079f585b033849c744838c1db7a05ef729450..30372e849213d0446ac7edd72452782606bf938f 100644
|
||||
--- a/ui/gfx/skbitmap_operations.cc
|
||||
+++ b/ui/gfx/skbitmap_operations.cc
|
||||
@@ -630,6 +630,8 @@ SkBitmap SkBitmapOperations::UnPreMultiply(const SkBitmap& bitmap) {
|
||||
return bitmap;
|
||||
if (bitmap.isOpaque())
|
||||
return bitmap;
|
||||
+ // It's expected this code is called with a 32bpp image.
|
||||
+ CHECK_EQ(kN32_SkColorType, bitmap.colorType());
|
||||
|
||||
const SkImageInfo& opaque_info =
|
||||
bitmap.info().makeAlphaType(kOpaque_SkAlphaType);
|
||||
@@ -0,0 +1,951 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jana Grill <janagrill@google.com>
|
||||
Date: Thu, 15 Apr 2021 19:35:42 +0000
|
||||
Subject: Use IDType for permission change subscriptions.
|
||||
|
||||
(cherry picked from commit ad1489b7c3ed705fc623cdffdc292324be9fcbfa)
|
||||
|
||||
Bug: 1025683
|
||||
Change-Id: I3b44ba7833138e8a657a4192e1a36c978695db32
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2791431
|
||||
Reviewed-by: Richard Coles <torne@chromium.org>
|
||||
Reviewed-by: Yuchen Liu <yucliu@chromium.org>
|
||||
Reviewed-by: Nasko Oskov <nasko@chromium.org>
|
||||
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
|
||||
Reviewed-by: Fabrice de Gans-Riberi <fdegans@chromium.org>
|
||||
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
|
||||
Reviewed-by: Illia Klimov <elklm@google.com>
|
||||
Auto-Submit: Balazs Engedy <engedy@chromium.org>
|
||||
Commit-Queue: Balazs Engedy <engedy@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#867999}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2817980
|
||||
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
|
||||
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4240@{#1607}
|
||||
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
|
||||
|
||||
diff --git a/android_webview/browser/aw_permission_manager.cc b/android_webview/browser/aw_permission_manager.cc
|
||||
index bedb16b046d45b257e28e29e410afe43f5c8817c..c020e9668cbd2de9d36d2e160a07e324a2510d6b 100644
|
||||
--- a/android_webview/browser/aw_permission_manager.cc
|
||||
+++ b/android_webview/browser/aw_permission_manager.cc
|
||||
@@ -469,16 +469,17 @@ PermissionStatus AwPermissionManager::GetPermissionStatusForFrame(
|
||||
.GetOrigin());
|
||||
}
|
||||
|
||||
-int AwPermissionManager::SubscribePermissionStatusChange(
|
||||
+AwPermissionManager::SubscriptionId
|
||||
+AwPermissionManager::SubscribePermissionStatusChange(
|
||||
PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(PermissionStatus)> callback) {
|
||||
- return content::PermissionController::kNoPendingOperation;
|
||||
+ return SubscriptionId();
|
||||
}
|
||||
|
||||
void AwPermissionManager::UnsubscribePermissionStatusChange(
|
||||
- int subscription_id) {}
|
||||
+ SubscriptionId subscription_id) {}
|
||||
|
||||
void AwPermissionManager::CancelPermissionRequest(int request_id) {
|
||||
PendingRequest* pending_request = pending_requests_.Lookup(request_id);
|
||||
diff --git a/android_webview/browser/aw_permission_manager.h b/android_webview/browser/aw_permission_manager.h
|
||||
index d9670cac33b84016568e9693b62e83c5e7ee0969..7439e78199783b8ebe2c303ebebf0e1cf62dc718 100644
|
||||
--- a/android_webview/browser/aw_permission_manager.h
|
||||
+++ b/android_webview/browser/aw_permission_manager.h
|
||||
@@ -49,13 +49,14 @@ class AwPermissionManager : public content::PermissionControllerDelegate {
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin) override;
|
||||
- int SubscribePermissionStatusChange(
|
||||
+ SubscriptionId SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
|
||||
override;
|
||||
- void UnsubscribePermissionStatusChange(int subscription_id) override;
|
||||
+ void UnsubscribePermissionStatusChange(
|
||||
+ SubscriptionId subscription_id) override;
|
||||
|
||||
protected:
|
||||
void CancelPermissionRequest(int request_id);
|
||||
diff --git a/chrome/browser/permissions/permission_manager_browsertest.cc b/chrome/browser/permissions/permission_manager_browsertest.cc
|
||||
index 440203ce6eca40070e09eae8bafe2a50bea75060..d48e6d85611b2ea4560f56d5e09fafa3a3453e7a 100644
|
||||
--- a/chrome/browser/permissions/permission_manager_browsertest.cc
|
||||
+++ b/chrome/browser/permissions/permission_manager_browsertest.cc
|
||||
@@ -49,13 +49,13 @@ class SubscriptionInterceptingPermissionManager
|
||||
callback_ = std::move(callback);
|
||||
}
|
||||
|
||||
- int SubscribePermissionStatusChange(
|
||||
+ SubscriptionId SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
|
||||
override {
|
||||
- int result =
|
||||
+ SubscriptionId result =
|
||||
permissions::PermissionManager::SubscribePermissionStatusChange(
|
||||
permission, render_frame_host, requesting_origin, callback);
|
||||
std::move(callback_).Run();
|
||||
diff --git a/chromecast/browser/cast_permission_manager.cc b/chromecast/browser/cast_permission_manager.cc
|
||||
index b358fc3bdb5c6af93a1e6568a667049574367741..b3a226dabff062e591fee38682409dec5e38a213 100644
|
||||
--- a/chromecast/browser/cast_permission_manager.cc
|
||||
+++ b/chromecast/browser/cast_permission_manager.cc
|
||||
@@ -63,17 +63,17 @@ CastPermissionManager::GetPermissionStatusForFrame(
|
||||
return blink::mojom::PermissionStatus::GRANTED;
|
||||
}
|
||||
|
||||
-int CastPermissionManager::SubscribePermissionStatusChange(
|
||||
+CastPermissionManager::SubscriptionId
|
||||
+CastPermissionManager::SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
|
||||
- return content::PermissionController::kNoPendingOperation;
|
||||
+ return SubscriptionId();
|
||||
}
|
||||
|
||||
void CastPermissionManager::UnsubscribePermissionStatusChange(
|
||||
- int subscription_id) {
|
||||
-}
|
||||
+ SubscriptionId subscription_id) {}
|
||||
|
||||
} // namespace shell
|
||||
} // namespace chromecast
|
||||
diff --git a/chromecast/browser/cast_permission_manager.h b/chromecast/browser/cast_permission_manager.h
|
||||
index 564ac2b304596027cf7096892dfaf9796500419c..f9da64c6110307cf9912e897f87fcbb2ca123d75 100644
|
||||
--- a/chromecast/browser/cast_permission_manager.h
|
||||
+++ b/chromecast/browser/cast_permission_manager.h
|
||||
@@ -43,13 +43,14 @@ class CastPermissionManager : public content::PermissionControllerDelegate {
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin) override;
|
||||
- int SubscribePermissionStatusChange(
|
||||
+ SubscriptionId SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
|
||||
override;
|
||||
- void UnsubscribePermissionStatusChange(int subscription_id) override;
|
||||
+ void UnsubscribePermissionStatusChange(
|
||||
+ SubscriptionId subscription_id) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CastPermissionManager);
|
||||
diff --git a/components/permissions/permission_manager.cc b/components/permissions/permission_manager.cc
|
||||
index a9566441647f0e8527a6b9603f663f66e49b2abb..bdf639f49a987eb2d7ae31346dc01b85dac57eaa 100644
|
||||
--- a/components/permissions/permission_manager.cc
|
||||
+++ b/components/permissions/permission_manager.cc
|
||||
@@ -542,14 +542,15 @@ bool PermissionManager::IsPermissionOverridableByDevTools(
|
||||
origin->GetURL());
|
||||
}
|
||||
|
||||
-int PermissionManager::SubscribePermissionStatusChange(
|
||||
+PermissionManager::SubscriptionId
|
||||
+PermissionManager::SubscribePermissionStatusChange(
|
||||
PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(PermissionStatus)> callback) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
if (is_shutting_down_)
|
||||
- return 0;
|
||||
+ return SubscriptionId();
|
||||
|
||||
if (subscriptions_.IsEmpty())
|
||||
PermissionsClient::Get()
|
||||
@@ -586,16 +587,20 @@ int PermissionManager::SubscribePermissionStatusChange(
|
||||
subscription->callback =
|
||||
base::BindRepeating(&SubscriptionCallbackWrapper, std::move(callback));
|
||||
|
||||
- return subscriptions_.Add(std::move(subscription));
|
||||
+ auto id = subscription_id_generator_.GenerateNextId();
|
||||
+ subscriptions_.AddWithID(std::move(subscription), id);
|
||||
+ return id;
|
||||
}
|
||||
|
||||
-void PermissionManager::UnsubscribePermissionStatusChange(int subscription_id) {
|
||||
+void PermissionManager::UnsubscribePermissionStatusChange(
|
||||
+ SubscriptionId subscription_id) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
if (is_shutting_down_)
|
||||
return;
|
||||
|
||||
- // Whether |subscription_id| is known will be checked by the Remove() call.
|
||||
- subscriptions_.Remove(subscription_id);
|
||||
+ if (subscriptions_.Lookup(subscription_id)) {
|
||||
+ subscriptions_.Remove(subscription_id);
|
||||
+ }
|
||||
|
||||
if (subscriptions_.IsEmpty()) {
|
||||
PermissionsClient::Get()
|
||||
diff --git a/components/permissions/permission_manager.h b/components/permissions/permission_manager.h
|
||||
index d11fb4b2c4a1a360ae01154995091439e13bd9a0..19d29dde0392adff318e82bd1c3091c4e1dcd926 100644
|
||||
--- a/components/permissions/permission_manager.h
|
||||
+++ b/components/permissions/permission_manager.h
|
||||
@@ -114,13 +114,14 @@ class PermissionManager : public KeyedService,
|
||||
bool IsPermissionOverridableByDevTools(
|
||||
content::PermissionType permission,
|
||||
const base::Optional<url::Origin>& origin) override;
|
||||
- int SubscribePermissionStatusChange(
|
||||
+ SubscriptionId SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
|
||||
override;
|
||||
- void UnsubscribePermissionStatusChange(int subscription_id) override;
|
||||
+ void UnsubscribePermissionStatusChange(
|
||||
+ SubscriptionId subscription_id) override;
|
||||
|
||||
// TODO(raymes): Rather than exposing this, use the denial reason from
|
||||
// GetPermissionStatus in callers to determine whether a permission is
|
||||
@@ -153,7 +154,8 @@ class PermissionManager : public KeyedService,
|
||||
class PermissionResponseCallback;
|
||||
|
||||
struct Subscription;
|
||||
- using SubscriptionsMap = base::IDMap<std::unique_ptr<Subscription>>;
|
||||
+ using SubscriptionsMap =
|
||||
+ base::IDMap<std::unique_ptr<Subscription>, SubscriptionId>;
|
||||
|
||||
PermissionContextBase* GetPermissionContext(ContentSettingsType type);
|
||||
|
||||
@@ -186,6 +188,7 @@ class PermissionManager : public KeyedService,
|
||||
content::BrowserContext* browser_context_;
|
||||
PendingRequestsMap pending_requests_;
|
||||
SubscriptionsMap subscriptions_;
|
||||
+ SubscriptionId::Generator subscription_id_generator_;
|
||||
|
||||
PermissionContextMap permission_contexts_;
|
||||
using ContentSettingsTypeOverrides =
|
||||
diff --git a/components/permissions/permission_manager_unittest.cc b/components/permissions/permission_manager_unittest.cc
|
||||
index ff5793acc907134fc486fcd5b9c20bf0cf2d960c..0070768b4a41e2890b89aba817fe24f6268272c1 100644
|
||||
--- a/components/permissions/permission_manager_unittest.cc
|
||||
+++ b/components/permissions/permission_manager_unittest.cc
|
||||
@@ -325,7 +325,7 @@ TEST_F(PermissionManagerTest, SubscriptionDestroyedCleanlyWithoutUnsubscribe) {
|
||||
}
|
||||
|
||||
TEST_F(PermissionManagerTest, SubscribeUnsubscribeAfterShutdown) {
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -340,7 +340,7 @@ TEST_F(PermissionManagerTest, SubscribeUnsubscribeAfterShutdown) {
|
||||
subscription_id);
|
||||
|
||||
// Check that subscribe/unsubscribe after shutdown don't crash.
|
||||
- int subscription2_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription2_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -351,7 +351,7 @@ TEST_F(PermissionManagerTest, SubscribeUnsubscribeAfterShutdown) {
|
||||
}
|
||||
|
||||
TEST_F(PermissionManagerTest, SameTypeChangeNotifies) {
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -369,7 +369,7 @@ TEST_F(PermissionManagerTest, SameTypeChangeNotifies) {
|
||||
}
|
||||
|
||||
TEST_F(PermissionManagerTest, DifferentTypeChangeDoesNotNotify) {
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -386,7 +386,7 @@ TEST_F(PermissionManagerTest, DifferentTypeChangeDoesNotNotify) {
|
||||
}
|
||||
|
||||
TEST_F(PermissionManagerTest, ChangeAfterUnsubscribeDoesNotNotify) {
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -403,7 +403,7 @@ TEST_F(PermissionManagerTest, ChangeAfterUnsubscribeDoesNotNotify) {
|
||||
}
|
||||
|
||||
TEST_F(PermissionManagerTest, DifferentPrimaryUrlDoesNotNotify) {
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -420,7 +420,7 @@ TEST_F(PermissionManagerTest, DifferentPrimaryUrlDoesNotNotify) {
|
||||
}
|
||||
|
||||
TEST_F(PermissionManagerTest, DifferentSecondaryUrlDoesNotNotify) {
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -437,7 +437,7 @@ TEST_F(PermissionManagerTest, DifferentSecondaryUrlDoesNotNotify) {
|
||||
}
|
||||
|
||||
TEST_F(PermissionManagerTest, WildCardPatternNotifies) {
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -458,7 +458,7 @@ TEST_F(PermissionManagerTest, ClearSettingsNotifies) {
|
||||
url(), url(), ContentSettingsType::GEOLOCATION, std::string(),
|
||||
CONTENT_SETTING_ALLOW);
|
||||
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -475,7 +475,7 @@ TEST_F(PermissionManagerTest, ClearSettingsNotifies) {
|
||||
}
|
||||
|
||||
TEST_F(PermissionManagerTest, NewValueCorrectlyPassed) {
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -497,7 +497,7 @@ TEST_F(PermissionManagerTest, ChangeWithoutPermissionChangeDoesNotNotify) {
|
||||
url(), url(), ContentSettingsType::GEOLOCATION, std::string(),
|
||||
CONTENT_SETTING_ALLOW);
|
||||
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -518,7 +518,7 @@ TEST_F(PermissionManagerTest, ChangesBackAndForth) {
|
||||
url(), url(), ContentSettingsType::GEOLOCATION, std::string(),
|
||||
CONTENT_SETTING_ASK);
|
||||
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -549,7 +549,7 @@ TEST_F(PermissionManagerTest, ChangesBackAndForthWorker) {
|
||||
url(), url(), ContentSettingsType::GEOLOCATION, std::string(),
|
||||
CONTENT_SETTING_ASK);
|
||||
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, nullptr, url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -576,7 +576,7 @@ TEST_F(PermissionManagerTest, ChangesBackAndForthWorker) {
|
||||
}
|
||||
|
||||
TEST_F(PermissionManagerTest, SubscribeMIDIPermission) {
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::MIDI, main_rfh(), url(),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
@@ -796,7 +796,7 @@ TEST_F(PermissionManagerTest, SubscribeWithPermissionDelegation) {
|
||||
content::RenderFrameHost* parent = main_rfh();
|
||||
content::RenderFrameHost* child = AddChildRFH(parent, kOrigin2);
|
||||
|
||||
- int subscription_id =
|
||||
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
|
||||
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
|
||||
PermissionType::GEOLOCATION, child, GURL(kOrigin2),
|
||||
base::Bind(&PermissionManagerTest::OnPermissionChange,
|
||||
diff --git a/content/browser/android/nfc_host.cc b/content/browser/android/nfc_host.cc
|
||||
index 30517f69b3d790690121bda2f3de50c0e31fadd1..0f077d211a23d05813dafd7dc621915c1fb79ba5 100644
|
||||
--- a/content/browser/android/nfc_host.cc
|
||||
+++ b/content/browser/android/nfc_host.cc
|
||||
@@ -99,8 +99,8 @@ void NFCHost::OnPermissionStatusChange(blink::mojom::PermissionStatus status) {
|
||||
|
||||
void NFCHost::Close() {
|
||||
nfc_provider_.reset();
|
||||
- if (subscription_id_ != 0)
|
||||
- permission_controller_->UnsubscribePermissionStatusChange(subscription_id_);
|
||||
+ permission_controller_->UnsubscribePermissionStatusChange(subscription_id_);
|
||||
+ subscription_id_ = PermissionController::SubscriptionId();
|
||||
}
|
||||
|
||||
} // namespace content
|
||||
diff --git a/content/browser/android/nfc_host.h b/content/browser/android/nfc_host.h
|
||||
index 8df7cbec810ecb535f4ce4b54266c34243341571..6b5f8dde17d0abda6132845018b4a8f81859cd0d 100644
|
||||
--- a/content/browser/android/nfc_host.h
|
||||
+++ b/content/browser/android/nfc_host.h
|
||||
@@ -44,7 +44,7 @@ class NFCHost : public WebContentsObserver {
|
||||
mojo::Remote<device::mojom::NFCProvider> nfc_provider_;
|
||||
|
||||
// Permission change subscription ID provided by |permission_controller_|.
|
||||
- int subscription_id_ = 0;
|
||||
+ PermissionController::SubscriptionId subscription_id_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NFCHost);
|
||||
};
|
||||
diff --git a/content/browser/permissions/permission_controller_impl.cc b/content/browser/permissions/permission_controller_impl.cc
|
||||
index c6edd2ebec0b57808512c3b6c574548431efac7e..4722e9d7b3ed77489fa28f97afa55726f7f727e4 100644
|
||||
--- a/content/browser/permissions/permission_controller_impl.cc
|
||||
+++ b/content/browser/permissions/permission_controller_impl.cc
|
||||
@@ -132,7 +132,8 @@ struct PermissionControllerImpl::Subscription {
|
||||
int render_frame_id = -1;
|
||||
int render_process_id = -1;
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback;
|
||||
- int delegate_subscription_id;
|
||||
+ // This is default-initialized to an invalid ID.
|
||||
+ PermissionControllerDelegate::SubscriptionId delegate_subscription_id;
|
||||
};
|
||||
|
||||
PermissionControllerImpl::~PermissionControllerImpl() {
|
||||
@@ -388,7 +389,8 @@ void PermissionControllerImpl::OnDelegatePermissionStatusChange(
|
||||
subscription->callback.Run(status);
|
||||
}
|
||||
|
||||
-int PermissionControllerImpl::SubscribePermissionStatusChange(
|
||||
+PermissionControllerImpl::SubscriptionId
|
||||
+PermissionControllerImpl::SubscribePermissionStatusChange(
|
||||
PermissionType permission,
|
||||
RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
@@ -422,21 +424,21 @@ int PermissionControllerImpl::SubscribePermissionStatusChange(
|
||||
base::BindRepeating(
|
||||
&PermissionControllerImpl::OnDelegatePermissionStatusChange,
|
||||
base::Unretained(this), subscription.get()));
|
||||
- } else {
|
||||
- subscription->delegate_subscription_id = kNoPendingOperation;
|
||||
}
|
||||
- return subscriptions_.Add(std::move(subscription));
|
||||
+
|
||||
+ auto id = subscription_id_generator_.GenerateNextId();
|
||||
+ subscriptions_.AddWithID(std::move(subscription), id);
|
||||
+ return id;
|
||||
}
|
||||
|
||||
void PermissionControllerImpl::UnsubscribePermissionStatusChange(
|
||||
- int subscription_id) {
|
||||
+ SubscriptionId subscription_id) {
|
||||
Subscription* subscription = subscriptions_.Lookup(subscription_id);
|
||||
if (!subscription)
|
||||
return;
|
||||
PermissionControllerDelegate* delegate =
|
||||
browser_context_->GetPermissionControllerDelegate();
|
||||
- if (delegate &&
|
||||
- subscription->delegate_subscription_id != kNoPendingOperation) {
|
||||
+ if (delegate) {
|
||||
delegate->UnsubscribePermissionStatusChange(
|
||||
subscription->delegate_subscription_id);
|
||||
}
|
||||
diff --git a/content/browser/permissions/permission_controller_impl.h b/content/browser/permissions/permission_controller_impl.h
|
||||
index 7ebf3c48a0e863d9f4312b37e014ce0f89e5c3c7..d85788867f746547f80405c46660e055631d9208 100644
|
||||
--- a/content/browser/permissions/permission_controller_impl.h
|
||||
+++ b/content/browser/permissions/permission_controller_impl.h
|
||||
@@ -72,18 +72,19 @@ class CONTENT_EXPORT PermissionControllerImpl : public PermissionController {
|
||||
const GURL& requesting_origin,
|
||||
const GURL& embedding_origin);
|
||||
|
||||
- int SubscribePermissionStatusChange(
|
||||
+ SubscriptionId SubscribePermissionStatusChange(
|
||||
PermissionType permission,
|
||||
RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
const base::RepeatingCallback<void(blink::mojom::PermissionStatus)>&
|
||||
callback);
|
||||
|
||||
- void UnsubscribePermissionStatusChange(int subscription_id);
|
||||
+ void UnsubscribePermissionStatusChange(SubscriptionId subscription_id);
|
||||
|
||||
private:
|
||||
struct Subscription;
|
||||
- using SubscriptionsMap = base::IDMap<std::unique_ptr<Subscription>>;
|
||||
+ using SubscriptionsMap =
|
||||
+ base::IDMap<std::unique_ptr<Subscription>, SubscriptionId>;
|
||||
using SubscriptionsStatusMap =
|
||||
base::flat_map<SubscriptionsMap::KeyType, blink::mojom::PermissionStatus>;
|
||||
|
||||
@@ -98,7 +99,13 @@ class CONTENT_EXPORT PermissionControllerImpl : public PermissionController {
|
||||
const base::Optional<url::Origin>& origin);
|
||||
|
||||
DevToolsPermissionOverrides devtools_permission_overrides_;
|
||||
+
|
||||
+ // Note that SubscriptionId is distinct from
|
||||
+ // PermissionControllerDelegate::SubscriptionId, and the concrete ID values
|
||||
+ // may be different as well.
|
||||
SubscriptionsMap subscriptions_;
|
||||
+ SubscriptionId::Generator subscription_id_generator_;
|
||||
+
|
||||
BrowserContext* browser_context_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PermissionControllerImpl);
|
||||
diff --git a/content/browser/permissions/permission_service_context.cc b/content/browser/permissions/permission_service_context.cc
|
||||
index c3ab81294edbb297108c3b8f59a35f1cfb8131f9..f15abf265eb690b5dfd66bb1c2d5e13b005ddbd0 100644
|
||||
--- a/content/browser/permissions/permission_service_context.cc
|
||||
+++ b/content/browser/permissions/permission_service_context.cc
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "content/browser/permissions/permission_service_impl.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/navigation_handle.h"
|
||||
-#include "content/public/browser/permission_controller.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
@@ -32,7 +31,7 @@ class PermissionServiceContext::PermissionSubscription {
|
||||
PermissionSubscription& operator=(const PermissionSubscription&) = delete;
|
||||
|
||||
~PermissionSubscription() {
|
||||
- DCHECK_NE(id_, 0);
|
||||
+ DCHECK(id_);
|
||||
BrowserContext* browser_context = context_->GetBrowserContext();
|
||||
if (browser_context) {
|
||||
PermissionControllerImpl::FromBrowserContext(browser_context)
|
||||
@@ -41,7 +40,7 @@ class PermissionServiceContext::PermissionSubscription {
|
||||
}
|
||||
|
||||
void OnConnectionError() {
|
||||
- DCHECK_NE(id_, 0);
|
||||
+ DCHECK(id_);
|
||||
context_->ObserverHadConnectionError(id_);
|
||||
}
|
||||
|
||||
@@ -49,12 +48,12 @@ class PermissionServiceContext::PermissionSubscription {
|
||||
observer_->OnPermissionStatusChange(status);
|
||||
}
|
||||
|
||||
- void set_id(int id) { id_ = id; }
|
||||
+ void set_id(PermissionController::SubscriptionId id) { id_ = id; }
|
||||
|
||||
private:
|
||||
PermissionServiceContext* const context_;
|
||||
mojo::Remote<blink::mojom::PermissionObserver> observer_;
|
||||
- int id_ = 0;
|
||||
+ PermissionController::SubscriptionId id_;
|
||||
};
|
||||
|
||||
PermissionServiceContext::PermissionServiceContext(
|
||||
@@ -108,7 +107,7 @@ void PermissionServiceContext::CreateSubscription(
|
||||
}
|
||||
|
||||
GURL requesting_origin(origin.Serialize());
|
||||
- int subscription_id =
|
||||
+ auto subscription_id =
|
||||
PermissionControllerImpl::FromBrowserContext(browser_context)
|
||||
->SubscribePermissionStatusChange(
|
||||
permission_type, render_frame_host_, requesting_origin,
|
||||
@@ -119,7 +118,8 @@ void PermissionServiceContext::CreateSubscription(
|
||||
subscriptions_[subscription_id] = std::move(subscription);
|
||||
}
|
||||
|
||||
-void PermissionServiceContext::ObserverHadConnectionError(int subscription_id) {
|
||||
+void PermissionServiceContext::ObserverHadConnectionError(
|
||||
+ PermissionController::SubscriptionId subscription_id) {
|
||||
size_t erased = subscriptions_.erase(subscription_id);
|
||||
DCHECK_EQ(1u, erased);
|
||||
}
|
||||
diff --git a/content/browser/permissions/permission_service_context.h b/content/browser/permissions/permission_service_context.h
|
||||
index 4f93be504fd854b50bea96dedbc5d324d25ea6f1..0680c70c8ee4a79bb85c2fd1e3769a29f339816e 100644
|
||||
--- a/content/browser/permissions/permission_service_context.h
|
||||
+++ b/content/browser/permissions/permission_service_context.h
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "content/common/content_export.h"
|
||||
+#include "content/public/browser/permission_controller.h"
|
||||
#include "content/public/browser/permission_type.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
@@ -52,7 +53,8 @@ class CONTENT_EXPORT PermissionServiceContext : public WebContentsObserver {
|
||||
mojo::PendingRemote<blink::mojom::PermissionObserver> observer);
|
||||
|
||||
// Called when the connection to a PermissionObserver has an error.
|
||||
- void ObserverHadConnectionError(int subscription_id);
|
||||
+ void ObserverHadConnectionError(
|
||||
+ PermissionController::SubscriptionId subscription_id);
|
||||
|
||||
// May return nullptr during teardown, or when showing an interstitial.
|
||||
BrowserContext* GetBrowserContext() const;
|
||||
@@ -78,7 +80,8 @@ class CONTENT_EXPORT PermissionServiceContext : public WebContentsObserver {
|
||||
RenderFrameHost* const render_frame_host_;
|
||||
RenderProcessHost* const render_process_host_;
|
||||
mojo::UniqueReceiverSet<blink::mojom::PermissionService> services_;
|
||||
- std::unordered_map<int, std::unique_ptr<PermissionSubscription>>
|
||||
+ std::unordered_map<PermissionController::SubscriptionId,
|
||||
+ std::unique_ptr<PermissionSubscription>>
|
||||
subscriptions_;
|
||||
};
|
||||
|
||||
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h
|
||||
index 4468b5c906454a8cf4484c8f3f81841c9130721b..677f7a5fe22b55f12c324048972a7200ac8c873b 100644
|
||||
--- a/content/browser/renderer_host/media/media_stream_manager.h
|
||||
+++ b/content/browser/renderer_host/media/media_stream_manager.h
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "content/public/browser/desktop_media_id.h"
|
||||
#include "content/public/browser/media_request_state.h"
|
||||
#include "content/public/browser/media_stream_request.h"
|
||||
+#include "content/public/browser/permission_controller.h"
|
||||
#include "media/base/video_facing.h"
|
||||
#include "third_party/blink/public/common/mediastream/media_devices.h"
|
||||
#include "third_party/blink/public/common/mediastream/media_stream_controls.h"
|
||||
diff --git a/content/public/browser/permission_controller.h b/content/public/browser/permission_controller.h
|
||||
index b9b42def49b35d31c22ee0d6c158737bdc0824b6..77fe96a1c33aea5e887e171b92f199acdf7dd6df 100644
|
||||
--- a/content/public/browser/permission_controller.h
|
||||
+++ b/content/public/browser/permission_controller.h
|
||||
@@ -6,6 +6,7 @@
|
||||
#define CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_H_
|
||||
|
||||
#include "base/supports_user_data.h"
|
||||
+#include "base/util/type_safety/id_type.h"
|
||||
#include "content/common/content_export.h"
|
||||
#include "content/public/browser/permission_type.h"
|
||||
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
|
||||
@@ -20,8 +21,13 @@ class RenderFrameHost;
|
||||
class CONTENT_EXPORT PermissionController
|
||||
: public base::SupportsUserData::Data {
|
||||
public:
|
||||
- // Constant retured when registering and subscribing if
|
||||
- // cancelling/unsubscribing at a later stage would have no effect.
|
||||
+ // Identifier for an active subscription. This is intentionally a distinct
|
||||
+ // type from PermissionControllerDelegate::SubscriptionId as the concrete
|
||||
+ // identifier values may be different.
|
||||
+ using SubscriptionId = util::IdType64<PermissionController>;
|
||||
+
|
||||
+ // Constant returned when requesting a permission if cancelling at a later
|
||||
+ // stage would have no effect.
|
||||
static const int kNoPendingOperation = -1;
|
||||
|
||||
~PermissionController() override {}
|
||||
@@ -48,4 +54,17 @@ class CONTENT_EXPORT PermissionController
|
||||
|
||||
} // namespace content
|
||||
|
||||
+namespace std {
|
||||
+
|
||||
+template <>
|
||||
+struct hash<content::PermissionController::SubscriptionId> {
|
||||
+ std::size_t operator()(
|
||||
+ const content::PermissionController::SubscriptionId& v) const {
|
||||
+ content::PermissionController::SubscriptionId::Hasher hasher;
|
||||
+ return hasher(v);
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+} // namespace std
|
||||
+
|
||||
#endif // CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_H_
|
||||
diff --git a/content/public/browser/permission_controller_delegate.h b/content/public/browser/permission_controller_delegate.h
|
||||
index e47de2a278e67091442c63bb7130022eae587041..82a1d4f0efd384386d8215f39d735ba488e4bc61 100644
|
||||
--- a/content/public/browser/permission_controller_delegate.h
|
||||
+++ b/content/public/browser/permission_controller_delegate.h
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_DELEGATE_H_
|
||||
#define CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_DELEGATE_H_
|
||||
|
||||
+#include "base/util/type_safety/id_type.h"
|
||||
#include "content/common/content_export.h"
|
||||
#include "content/public/browser/devtools_permission_overrides.h"
|
||||
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
|
||||
@@ -18,6 +19,10 @@ class RenderFrameHost;
|
||||
class CONTENT_EXPORT PermissionControllerDelegate {
|
||||
public:
|
||||
using PermissionOverrides = DevToolsPermissionOverrides::PermissionOverrides;
|
||||
+
|
||||
+ // Identifier for an active subscription.
|
||||
+ using SubscriptionId = util::IdType64<PermissionControllerDelegate>;
|
||||
+
|
||||
virtual ~PermissionControllerDelegate() = default;
|
||||
|
||||
// Requests a permission on behalf of a frame identified by
|
||||
@@ -80,21 +85,21 @@ class CONTENT_EXPORT PermissionControllerDelegate {
|
||||
|
||||
// Runs the given |callback| whenever the |permission| associated with the
|
||||
// given RenderFrameHost changes. A nullptr should be passed if the request
|
||||
- // is from a worker. Returns the subscription_id to be used to unsubscribe.
|
||||
- // Can be kNoPendingOperation if the subscribe was not successful.
|
||||
- virtual int SubscribePermissionStatusChange(
|
||||
+ // is from a worker. Returns the ID to be used to unsubscribe, which can be
|
||||
+ // `is_null()` if the subscribe was not successful.
|
||||
+ virtual SubscriptionId SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)>
|
||||
callback) = 0;
|
||||
|
||||
- // Unregisters from permission status change notifications.
|
||||
- // The |subscription_id| must match the value returned by the
|
||||
- // SubscribePermissionStatusChange call. Unsubscribing
|
||||
- // an already unsubscribed |subscription_id| or providing the
|
||||
- // |subscription_id| kNoPendingOperation is a no-op.
|
||||
- virtual void UnsubscribePermissionStatusChange(int subscription_id) = 0;
|
||||
+ // Unregisters from permission status change notifications. The
|
||||
+ // |subscription_id| must match the value returned by the
|
||||
+ // SubscribePermissionStatusChange call. Unsubscribing an already
|
||||
+ // unsubscribed |subscription_id| or an `is_null()` ID is a no-op.
|
||||
+ virtual void UnsubscribePermissionStatusChange(
|
||||
+ SubscriptionId subscription_id) = 0;
|
||||
|
||||
// Manually overrides default permission settings of delegate, if overrides
|
||||
// are tracked by the delegate. This method should only be called by the
|
||||
@@ -116,4 +121,17 @@ class CONTENT_EXPORT PermissionControllerDelegate {
|
||||
|
||||
} // namespace content
|
||||
|
||||
+namespace std {
|
||||
+
|
||||
+template <>
|
||||
+struct hash<content::PermissionControllerDelegate::SubscriptionId> {
|
||||
+ std::size_t operator()(
|
||||
+ const content::PermissionControllerDelegate::SubscriptionId& v) const {
|
||||
+ content::PermissionControllerDelegate::SubscriptionId::Hasher hasher;
|
||||
+ return hasher(v);
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+} // namespace std
|
||||
+
|
||||
#endif // CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_DELEGATE_H_
|
||||
diff --git a/content/public/test/mock_permission_manager.h b/content/public/test/mock_permission_manager.h
|
||||
index a193bd00e23abf2295c8bcf2ed5fb3acae68440f..34e71e23a2dae6d55348d8139480459b36377c0c 100644
|
||||
--- a/content/public/test/mock_permission_manager.h
|
||||
+++ b/content/public/test/mock_permission_manager.h
|
||||
@@ -49,13 +49,13 @@ class MockPermissionManager : public PermissionControllerDelegate {
|
||||
void ResetPermission(PermissionType permission,
|
||||
const GURL& requesting_origin,
|
||||
const GURL& embedding_origin) override {}
|
||||
- int SubscribePermissionStatusChange(
|
||||
+ SubscriptionId SubscribePermissionStatusChange(
|
||||
PermissionType permission,
|
||||
RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
|
||||
override;
|
||||
- void UnsubscribePermissionStatusChange(int subscription_id) override {}
|
||||
+ void UnsubscribePermissionStatusChange(SubscriptionId subscription_id) override {}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(MockPermissionManager);
|
||||
diff --git a/content/shell/browser/shell_permission_manager.cc b/content/shell/browser/shell_permission_manager.cc
|
||||
index d0396ea346f267a26a8d318d518be59a55b9311a..b302b378960e9cf2445e1e8983d05f6fc2c668b6 100644
|
||||
--- a/content/shell/browser/shell_permission_manager.cc
|
||||
+++ b/content/shell/browser/shell_permission_manager.cc
|
||||
@@ -133,16 +133,16 @@ ShellPermissionManager::GetPermissionStatusForFrame(
|
||||
.GetOrigin());
|
||||
}
|
||||
|
||||
-int ShellPermissionManager::SubscribePermissionStatusChange(
|
||||
+ShellPermissionManager::SubscriptionId
|
||||
+ShellPermissionManager::SubscribePermissionStatusChange(
|
||||
PermissionType permission,
|
||||
RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
|
||||
- return PermissionController::kNoPendingOperation;
|
||||
+ return SubscriptionId();
|
||||
}
|
||||
|
||||
void ShellPermissionManager::UnsubscribePermissionStatusChange(
|
||||
- int subscription_id) {
|
||||
-}
|
||||
+ SubscriptionId subscription_id) {}
|
||||
|
||||
} // namespace content
|
||||
diff --git a/content/shell/browser/shell_permission_manager.h b/content/shell/browser/shell_permission_manager.h
|
||||
index 85477665a9dd643f50c4567c1133973bc258a94f..ecda464779c39df4a8b4b1726414cf2763033f53 100644
|
||||
--- a/content/shell/browser/shell_permission_manager.h
|
||||
+++ b/content/shell/browser/shell_permission_manager.h
|
||||
@@ -42,13 +42,14 @@ class ShellPermissionManager : public PermissionControllerDelegate {
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin) override;
|
||||
- int SubscribePermissionStatusChange(
|
||||
+ SubscriptionId SubscribePermissionStatusChange(
|
||||
PermissionType permission,
|
||||
RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
|
||||
override;
|
||||
- void UnsubscribePermissionStatusChange(int subscription_id) override;
|
||||
+ void UnsubscribePermissionStatusChange(
|
||||
+ SubscriptionId subscription_id) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ShellPermissionManager);
|
||||
diff --git a/content/shell/browser/web_test/web_test_permission_manager.cc b/content/shell/browser/web_test/web_test_permission_manager.cc
|
||||
index 67f34deebcbf854692be497b1c31d8da72a5b03d..9c876335c3a2feee4f73d9f6f8e14d67f3988291 100644
|
||||
--- a/content/shell/browser/web_test/web_test_permission_manager.cc
|
||||
+++ b/content/shell/browser/web_test/web_test_permission_manager.cc
|
||||
@@ -147,7 +147,8 @@ WebTestPermissionManager::GetPermissionStatusForFrame(
|
||||
.GetOrigin());
|
||||
}
|
||||
|
||||
-int WebTestPermissionManager::SubscribePermissionStatusChange(
|
||||
+WebTestPermissionManager::SubscriptionId
|
||||
+WebTestPermissionManager::SubscribePermissionStatusChange(
|
||||
PermissionType permission,
|
||||
RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
@@ -170,14 +171,18 @@ int WebTestPermissionManager::SubscribePermissionStatusChange(
|
||||
GetPermissionStatus(permission, subscription->permission.origin,
|
||||
subscription->permission.embedding_origin);
|
||||
|
||||
- return subscriptions_.Add(std::move(subscription));
|
||||
+ auto id = subscription_id_generator_.GenerateNextId();
|
||||
+ subscriptions_.AddWithID(std::move(subscription), id);
|
||||
+ return id;
|
||||
}
|
||||
|
||||
void WebTestPermissionManager::UnsubscribePermissionStatusChange(
|
||||
- int subscription_id) {
|
||||
+ SubscriptionId subscription_id) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
- // Whether |subscription_id| is known will be checked by the Remove() call.
|
||||
+ if (!subscriptions_.Lookup(subscription_id))
|
||||
+ return;
|
||||
+
|
||||
subscriptions_.Remove(subscription_id);
|
||||
}
|
||||
|
||||
diff --git a/content/shell/browser/web_test/web_test_permission_manager.h b/content/shell/browser/web_test/web_test_permission_manager.h
|
||||
index 1d15dbb9c7dda0b1e8642435d8a1e8f48af72e5c..46490c28fb013c2f5c8e75d7e7e24761f4498a58 100644
|
||||
--- a/content/shell/browser/web_test/web_test_permission_manager.h
|
||||
+++ b/content/shell/browser/web_test/web_test_permission_manager.h
|
||||
@@ -52,13 +52,14 @@ class WebTestPermissionManager
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin) override;
|
||||
- int SubscribePermissionStatusChange(
|
||||
+ SubscriptionId SubscribePermissionStatusChange(
|
||||
PermissionType permission,
|
||||
RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
|
||||
override;
|
||||
- void UnsubscribePermissionStatusChange(int subscription_id) override;
|
||||
+ void UnsubscribePermissionStatusChange(
|
||||
+ SubscriptionId subscription_id) override;
|
||||
|
||||
void SetPermission(PermissionType permission,
|
||||
blink::mojom::PermissionStatus status,
|
||||
@@ -98,7 +99,8 @@ class WebTestPermissionManager
|
||||
};
|
||||
|
||||
struct Subscription;
|
||||
- using SubscriptionsMap = base::IDMap<std::unique_ptr<Subscription>>;
|
||||
+ using SubscriptionsMap =
|
||||
+ base::IDMap<std::unique_ptr<Subscription>, SubscriptionId>;
|
||||
using PermissionsMap = std::unordered_map<PermissionDescription,
|
||||
blink::mojom::PermissionStatus,
|
||||
PermissionDescription::Hash>;
|
||||
@@ -116,6 +118,7 @@ class WebTestPermissionManager
|
||||
|
||||
// List of subscribers currently listening to permission changes.
|
||||
SubscriptionsMap subscriptions_;
|
||||
+ SubscriptionId::Generator subscription_id_generator_;
|
||||
|
||||
mojo::ReceiverSet<blink::test::mojom::PermissionAutomation> receivers_;
|
||||
|
||||
diff --git a/fuchsia/engine/browser/web_engine_permission_delegate.cc b/fuchsia/engine/browser/web_engine_permission_delegate.cc
|
||||
index 98592f05b6d56108119b106a42d839c28131a324..c18b8be7cdf73720cf02afce9ea75ab98d3f1f64 100644
|
||||
--- a/fuchsia/engine/browser/web_engine_permission_delegate.cc
|
||||
+++ b/fuchsia/engine/browser/web_engine_permission_delegate.cc
|
||||
@@ -83,20 +83,21 @@ WebEnginePermissionDelegate::GetPermissionStatusForFrame(
|
||||
permission, url::Origin::Create(requesting_origin));
|
||||
}
|
||||
|
||||
-int WebEnginePermissionDelegate::SubscribePermissionStatusChange(
|
||||
+WebEnginePermissionDelegate::SubscriptionId
|
||||
+WebEnginePermissionDelegate::SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
|
||||
// TODO(crbug.com/1063094): Implement permission status subscription. It's
|
||||
// used in blink to emit PermissionStatus.onchange notifications.
|
||||
- NOTIMPLEMENTED() << ": " << static_cast<int>(permission);
|
||||
- return content::PermissionController::kNoPendingOperation;
|
||||
+ NOTIMPLEMENTED_LOG_ONCE() << ": " << static_cast<int>(permission);
|
||||
+ return SubscriptionId();
|
||||
}
|
||||
|
||||
void WebEnginePermissionDelegate::UnsubscribePermissionStatusChange(
|
||||
- int subscription_id) {
|
||||
+ SubscriptionId subscription_id) {
|
||||
// TODO(crbug.com/1063094): Implement permission status subscription. It's
|
||||
// used in blink to emit PermissionStatus.onchange notifications.
|
||||
- NOTREACHED();
|
||||
+ NOTIMPLEMENTED_LOG_ONCE();
|
||||
}
|
||||
diff --git a/fuchsia/engine/browser/web_engine_permission_delegate.h b/fuchsia/engine/browser/web_engine_permission_delegate.h
|
||||
index 036207b75d33b752981007a41aa51f3e64db4f0e..c39989b471c2a74ee1a9140e12f205866a0b7aff 100644
|
||||
--- a/fuchsia/engine/browser/web_engine_permission_delegate.h
|
||||
+++ b/fuchsia/engine/browser/web_engine_permission_delegate.h
|
||||
@@ -45,13 +45,14 @@ class WebEnginePermissionDelegate
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin) override;
|
||||
- int SubscribePermissionStatusChange(
|
||||
+ SubscriptionId SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
|
||||
override;
|
||||
- void UnsubscribePermissionStatusChange(int subscription_id) override;
|
||||
+ void UnsubscribePermissionStatusChange(
|
||||
+ SubscriptionId subscription_id) override;
|
||||
};
|
||||
|
||||
#endif // FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_PERMISSION_DELEGATE_H_
|
||||
diff --git a/headless/lib/browser/headless_permission_manager.cc b/headless/lib/browser/headless_permission_manager.cc
|
||||
index 5d4d609fc0c10e57ef3c6a730340dc409789dcdd..359ecdc4b72d560da830c51f23374150e6b30a2d 100644
|
||||
--- a/headless/lib/browser/headless_permission_manager.cc
|
||||
+++ b/headless/lib/browser/headless_permission_manager.cc
|
||||
@@ -71,15 +71,16 @@ HeadlessPermissionManager::GetPermissionStatusForFrame(
|
||||
return blink::mojom::PermissionStatus::ASK;
|
||||
}
|
||||
|
||||
-int HeadlessPermissionManager::SubscribePermissionStatusChange(
|
||||
+HeadlessPermissionManager::SubscriptionId
|
||||
+HeadlessPermissionManager::SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
|
||||
- return content::PermissionController::kNoPendingOperation;
|
||||
+ return SubscriptionId();
|
||||
}
|
||||
|
||||
void HeadlessPermissionManager::UnsubscribePermissionStatusChange(
|
||||
- int subscription_id) {}
|
||||
+ SubscriptionId subscription_id) {}
|
||||
|
||||
} // namespace headless
|
||||
diff --git a/headless/lib/browser/headless_permission_manager.h b/headless/lib/browser/headless_permission_manager.h
|
||||
index 4b83309ab3ada17f7f2ac3323ba5f13ab76b9409..ac30670cb384a79457033a25c13da0c305b8eff2 100644
|
||||
--- a/headless/lib/browser/headless_permission_manager.h
|
||||
+++ b/headless/lib/browser/headless_permission_manager.h
|
||||
@@ -46,13 +46,14 @@ class HeadlessPermissionManager : public content::PermissionControllerDelegate {
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin) override;
|
||||
- int SubscribePermissionStatusChange(
|
||||
+ SubscriptionId SubscribePermissionStatusChange(
|
||||
content::PermissionType permission,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& requesting_origin,
|
||||
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
|
||||
override;
|
||||
- void UnsubscribePermissionStatusChange(int subscription_id) override;
|
||||
+ void UnsubscribePermissionStatusChange(
|
||||
+ SubscriptionId subscription_id) override;
|
||||
|
||||
private:
|
||||
content::BrowserContext* browser_context_;
|
||||
@@ -0,0 +1,92 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Rice <ricea@chromium.org>
|
||||
Date: Fri, 12 Feb 2021 10:43:43 +0000
|
||||
Subject: WebSocket: Don't clear event queue on destruction
|
||||
|
||||
It's unnecessary to clear the event queue as it will be garbage
|
||||
collected anyway. Stop doing it.
|
||||
|
||||
Also add a unit test for GC with pending events. This can only happen if
|
||||
the execution context changes while the events are pending.
|
||||
|
||||
BUG=1170657
|
||||
|
||||
(cherry picked from commit 2dae20b0b3890af23852345a69158c99b47746aa)
|
||||
|
||||
(cherry picked from commit 171d6ee562c3cac850d9705e18745bb1214e5d83)
|
||||
|
||||
Change-Id: I01e5a687587f7471e88640c43f0dfe83e5c01bd1
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2655089
|
||||
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
|
||||
Commit-Queue: Adam Rice <ricea@chromium.org>
|
||||
Cr-Original-Original-Commit-Position: refs/heads/master@{#848065}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2660955
|
||||
Reviewed-by: Adam Rice <ricea@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/branch-heads/4389@{#419}
|
||||
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2690730
|
||||
Auto-Submit: Adam Rice <ricea@chromium.org>
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4324@{#2191}
|
||||
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket.cc b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
|
||||
index 0e9c87462e3bb2ea343abd3120c073f24e9b2d72..b823debc7d4732f304d8ec89f58e5127b4bc8074 100644
|
||||
--- a/third_party/blink/renderer/modules/websockets/dom_websocket.cc
|
||||
+++ b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
|
||||
@@ -81,9 +81,7 @@ namespace blink {
|
||||
DOMWebSocket::EventQueue::EventQueue(EventTarget* target)
|
||||
: state_(kActive), target_(target) {}
|
||||
|
||||
-DOMWebSocket::EventQueue::~EventQueue() {
|
||||
- ContextDestroyed();
|
||||
-}
|
||||
+DOMWebSocket::EventQueue::~EventQueue() = default;
|
||||
|
||||
void DOMWebSocket::EventQueue::Dispatch(Event* event) {
|
||||
switch (state_) {
|
||||
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc b/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
|
||||
index 4c50ae0990b9a76128ffb59f547eb47789d2d693..370c1944dd6f8a094f2f30fa4f03d573b2f430e3 100644
|
||||
--- a/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
|
||||
+++ b/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
|
||||
#include "third_party/blink/renderer/platform/heap/handle.h"
|
||||
#include "third_party/blink/renderer/platform/heap/heap.h"
|
||||
+#include "third_party/blink/renderer/platform/heap/impl/thread_state.h"
|
||||
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
|
||||
@@ -920,6 +921,32 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
DOMWebSocketInvalidClosingCodeTest,
|
||||
testing::Values(0, 1, 998, 999, 1001, 2999, 5000, 9999, 65535));
|
||||
|
||||
+TEST(DOMWebSocketTest, GCWhileEventsPending) {
|
||||
+ V8TestingScope scope;
|
||||
+ {
|
||||
+ DOMWebSocketTestScope websocket_scope(scope.GetExecutionContext());
|
||||
+
|
||||
+ EXPECT_CALL(websocket_scope.Channel(),
|
||||
+ Connect(KURL("ws://example.com/"), String()))
|
||||
+ .WillOnce(Return(true));
|
||||
+ EXPECT_CALL(websocket_scope.Channel(), Disconnect());
|
||||
+
|
||||
+ auto& socket = websocket_scope.Socket();
|
||||
+
|
||||
+ // Cause events to be queued rather than fired.
|
||||
+ socket.ContextLifecycleStateChanged(mojom::FrameLifecycleState::kPaused);
|
||||
+
|
||||
+ socket.Connect("ws://example.com/", Vector<String>(), ASSERT_NO_EXCEPTION);
|
||||
+ socket.DidError();
|
||||
+ socket.DidClose(DOMWebSocket::kClosingHandshakeIncomplete, 1006, "");
|
||||
+
|
||||
+ // Stop HasPendingActivity() from keeping the object alive.
|
||||
+ socket.SetExecutionContext(nullptr);
|
||||
+ }
|
||||
+
|
||||
+ ThreadState::Current()->CollectAllGarbageForTesting();
|
||||
+}
|
||||
+
|
||||
} // namespace
|
||||
|
||||
} // namespace blink
|
||||
@@ -10,8 +10,12 @@
|
||||
"src/electron/patches/usrsctp": "src/third_party/usrsctp/usrsctplib",
|
||||
|
||||
"src/electron/patches/freetype": "src/third_party/freetype/src",
|
||||
|
||||
|
||||
"src/electron/patches/pdfium": "src/third_party/pdfium",
|
||||
|
||||
"src/electron/patches/angle": "src/third_party/angle"
|
||||
|
||||
"src/electron/patches/angle": "src/third_party/angle",
|
||||
|
||||
"src/electron/patches/skia": "src/third_party/skia",
|
||||
|
||||
"src/electron/patches/icu": "src/third_party/icu"
|
||||
}
|
||||
|
||||
1
patches/icu/.patches
Normal file
1
patches/icu/.patches
Normal file
@@ -0,0 +1 @@
|
||||
fix_apply_tzdata2020f_to_icu.patch
|
||||
2552
patches/icu/fix_apply_tzdata2020f_to_icu.patch
Normal file
2552
patches/icu/fix_apply_tzdata2020f_to_icu.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -50,3 +50,4 @@ fix_enable_tls_renegotiation.patch
|
||||
crypto_update_certdata_to_nss_3_56.patch
|
||||
n-api_src_provide_asynchronous_cleanup_hooks.patch
|
||||
chore_expose_v8_initialization_isolate_callbacks.patch
|
||||
fix_add_safeforterminationscopes_for_sigint_interruptions.patch
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Thu, 10 Dec 2020 14:39:33 -0800
|
||||
Subject: fix: add SafeForTerminationScopes for SIGINT interruptions
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We start Node.js with only_terminate_in_safe_scope set to true becuase
|
||||
it's set by gin’s IsolateHolder. In those cases, parts of the API that
|
||||
expect execution termination to happen need to be marked as able to
|
||||
receive those events.
|
||||
|
||||
Upstreamed at https://github.com/nodejs/node/pull/36344.
|
||||
|
||||
diff --git a/src/module_wrap.cc b/src/module_wrap.cc
|
||||
index 29078bf6e58ce1782c08946dae760e7d62de486d..592cdedaa427393296ae5d9cd7c3a0d124b52673 100644
|
||||
--- a/src/module_wrap.cc
|
||||
+++ b/src/module_wrap.cc
|
||||
@@ -313,6 +313,7 @@ void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
ShouldNotAbortOnUncaughtScope no_abort_scope(env);
|
||||
TryCatchScope try_catch(env);
|
||||
+ Isolate::SafeForTerminationScope safe_for_termination(env->isolate());
|
||||
|
||||
bool timed_out = false;
|
||||
bool received_signal = false;
|
||||
diff --git a/src/node_contextify.cc b/src/node_contextify.cc
|
||||
index 2d30e0b8038ce473d1c8740861e13c5eabc2a0be..0902ac29b6f48c86302954a22a6e3318dc29836e 100644
|
||||
--- a/src/node_contextify.cc
|
||||
+++ b/src/node_contextify.cc
|
||||
@@ -902,6 +902,7 @@ bool ContextifyScript::EvalMachine(Environment* env,
|
||||
return false;
|
||||
}
|
||||
TryCatchScope try_catch(env);
|
||||
+ Isolate::SafeForTerminationScope safe_for_termination(env->isolate());
|
||||
ContextifyScript* wrapped_script;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.Holder(), false);
|
||||
Local<UnboundScript> unbound_script =
|
||||
3
patches/skia/.patches
Normal file
3
patches/skia/.patches
Normal file
@@ -0,0 +1,3 @@
|
||||
cherry-pick-6763a713f957.patch
|
||||
cherry-pick-b0d3d3e85fa6.patch
|
||||
skscalercontext_getimage_less_brittle.patch
|
||||
31
patches/skia/cherry-pick-6763a713f957.patch
Normal file
31
patches/skia/cherry-pick-6763a713f957.patch
Normal file
@@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Osman <brianosman@google.com>
|
||||
Date: Thu, 3 Sep 2020 15:19:14 -0400
|
||||
Subject: Limit morphology radius to 100 pixels
|
||||
|
||||
This limit is arbitrary, but hopefully prevents pathological (or
|
||||
malicious) SVG content from consuming huge amounts of CPU/GPU time,
|
||||
without impacting any legitimate uses of feMorphology. (Typical usage
|
||||
has a much smaller radius).
|
||||
|
||||
Bug: chromium:1123035
|
||||
Change-Id: I4405bc595128e9a6287eb5efa1be14621baa3a00
|
||||
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/315219
|
||||
Reviewed-by: Mike Reed <reed@google.com>
|
||||
Commit-Queue: Brian Osman <brianosman@google.com>
|
||||
|
||||
diff --git a/src/effects/imagefilters/SkMorphologyImageFilter.cpp b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
|
||||
index 35f35d7f8d6bb3c9b4aca8057d5b876c237dbb22..a9a617f648e2fa229d6a555610fac4c737dd1459 100644
|
||||
--- a/src/effects/imagefilters/SkMorphologyImageFilter.cpp
|
||||
+++ b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
|
||||
@@ -663,7 +663,9 @@ sk_sp<SkSpecialImage> SkMorphologyImageFilterImpl::onFilterImage(const Context&
|
||||
int height = SkScalarRoundToInt(radius.height());
|
||||
|
||||
// Width (or height) must fit in a signed 32-bit int to avoid UBSAN issues (crbug.com/1018190)
|
||||
- constexpr int kMaxRadius = (std::numeric_limits<int>::max() - 1) / 2;
|
||||
+ // Further, we limit the radius to something much smaller, to avoid extremely slow draw calls:
|
||||
+ // (crbug.com/1123035):
|
||||
+ constexpr int kMaxRadius = 100; // (std::numeric_limits<int>::max() - 1) / 2;
|
||||
|
||||
if (width < 0 || height < 0 || width > kMaxRadius || height > kMaxRadius) {
|
||||
return nullptr;
|
||||
158
patches/skia/cherry-pick-b0d3d3e85fa6.patch
Normal file
158
patches/skia/cherry-pick-b0d3d3e85fa6.patch
Normal file
@@ -0,0 +1,158 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Salomon <bsalomon@google.com>
|
||||
Date: Tue, 19 Jan 2021 10:28:15 -0500
|
||||
Subject: Fix DrawEdgeAAQuad degenerate issue where 3D points don't correctly
|
||||
project to 2D points.
|
||||
|
||||
Bug: chromium:1162942
|
||||
|
||||
Change-Id: Idc1dcb725ff9eae651b84de2fe792b188dcd1c1b
|
||||
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/354671
|
||||
Commit-Queue: Brian Salomon <bsalomon@google.com>
|
||||
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
|
||||
(cherry picked from commit 7656c4b7e89b4ff00480a6d7a8a19e3fd0e5c86e)
|
||||
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/360376
|
||||
Reviewed-by: Brian Salomon <bsalomon@google.com>
|
||||
|
||||
diff --git a/gm/crbug_1162942.cpp b/gm/crbug_1162942.cpp
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e5d1f6360f3d68e1d3e353752e2e676928c93aef
|
||||
--- /dev/null
|
||||
+++ b/gm/crbug_1162942.cpp
|
||||
@@ -0,0 +1,60 @@
|
||||
+/*
|
||||
+ * Copyright 2020 Google LLC
|
||||
+ *
|
||||
+ * Use of this source code is governed by a BSD-style license that can be
|
||||
+ * found in the LICENSE file.
|
||||
+ */
|
||||
+
|
||||
+#include "gm/gm.h"
|
||||
+#include "include/core/SkCanvas.h"
|
||||
+#include "include/core/SkMatrix.h"
|
||||
+#include "include/core/SkRect.h"
|
||||
+
|
||||
+// This tests a scenario where when the 2D projection of a perspective quad is inset we degenerate
|
||||
+// the inset 2d geometry to a triangle because an inset vertex crosses the opposite edge. When we
|
||||
+// project back to 3D and try to move the original verts along the original edges so that they
|
||||
+// project to the 2D points. Whether an edge can be moved along depends on whether the adjacent edge
|
||||
+// at the vertex is AA. However, in the degenerate triangle case the 2D point may not fall along
|
||||
+// either of the edges. Thus, if we're constrained to moving along one edge and solve for X or Y the
|
||||
+// other value may go wildly away from projecting to the 2D value. The current approach is to force
|
||||
+// AA on at both edges that meet at a vertex whose inset point has been replaced by an off-edge
|
||||
+// point if either is AA originally. This gives us an additional vector to move along so that we can
|
||||
+// find a 3D point that projects to the 2D point in both X and Y.
|
||||
+DEF_SIMPLE_GM(crbug_1162942, canvas, 620, 200) {
|
||||
+ // Matrix and quad values taken from Chrome repro scenario.
|
||||
+ SkMatrix ctm = SkMatrix::MakeAll(
|
||||
+ SkBits2Float(0x3FCC7F75), SkBits2Float(0x3D5784FC), SkBits2Float(0x44C48C99),
|
||||
+ SkBits2Float(0x3F699F7F), SkBits2Float(0x3E0A0D37), SkBits2Float(0x43908518),
|
||||
+ SkBits2Float(0x3AA17423), SkBits2Float(0x3A6CCDC3), SkBits2Float(0x3F2EFEEC));
|
||||
+ ctm.postTranslate(-1500.f, -325.f);
|
||||
+
|
||||
+ SkPoint pts[4] = {{SkBits2Float(0x3F39778B), SkBits2Float(0x43FF7FFC)},
|
||||
+ {SkBits2Float(0x0), SkBits2Float(0x43FF7FFA)},
|
||||
+ {SkBits2Float(0xB83B055E), SkBits2Float(0x42500003)},
|
||||
+ {SkBits2Float(0x3F39776F), SkBits2Float(0x4250000D)}};
|
||||
+ SkRect bounds;
|
||||
+ bounds.setBounds(pts, 4);
|
||||
+
|
||||
+ canvas->clear(SK_ColorWHITE);
|
||||
+
|
||||
+ SkCanvas::QuadAAFlags flags[] = {
|
||||
+ (SkCanvas::QuadAAFlags) (SkCanvas::kTop_QuadAAFlag | SkCanvas::kLeft_QuadAAFlag ),
|
||||
+ (SkCanvas::QuadAAFlags) (SkCanvas::kBottom_QuadAAFlag | SkCanvas::kRight_QuadAAFlag),
|
||||
+ (SkCanvas::QuadAAFlags) (SkCanvas::kBottom_QuadAAFlag),
|
||||
+ (SkCanvas::QuadAAFlags) (SkCanvas::kRight_QuadAAFlag),
|
||||
+ (SkCanvas::QuadAAFlags) (SkCanvas::kRight_QuadAAFlag | SkCanvas::kLeft_QuadAAFlag),
|
||||
+ (SkCanvas::QuadAAFlags) (SkCanvas::kTop_QuadAAFlag | SkCanvas::kBottom_QuadAAFlag),
|
||||
+ };
|
||||
+
|
||||
+ SkColor color = SK_ColorGREEN;
|
||||
+ for (auto aaFlags : flags) {
|
||||
+ canvas->save();
|
||||
+ canvas->concat(ctm);
|
||||
+ canvas->experimental_DrawEdgeAAQuad(bounds, pts, aaFlags, color, SkBlendMode::kSrcOver);
|
||||
+ SkColor rgb = color & 0x00FFFFFF;
|
||||
+ color = 0xFF000000 | (rgb << 4) | (rgb >> 20);
|
||||
+ canvas->restore();
|
||||
+ canvas->translate(0, 25);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
diff --git a/gn/gm.gni b/gn/gm.gni
|
||||
index 4ae72fb407084cb13d187ea6e4d0493e1dd4ea95..5ff5cd845765777508949ae24634292d0e6c0f67 100644
|
||||
--- a/gn/gm.gni
|
||||
+++ b/gn/gm.gni
|
||||
@@ -107,6 +107,7 @@ gm_sources = [
|
||||
"$_gm/copy_to_4444.cpp",
|
||||
"$_gm/crbug_1041204.cpp",
|
||||
"$_gm/crbug_1073670.cpp",
|
||||
+ "$_gm/crbug_1162942.cpp",
|
||||
"$_gm/crbug_224618.cpp",
|
||||
"$_gm/crbug_691386.cpp",
|
||||
"$_gm/crbug_788500.cpp",
|
||||
diff --git a/src/gpu/geometry/GrQuadUtils.cpp b/src/gpu/geometry/GrQuadUtils.cpp
|
||||
index 9650758a87695bec8df342d7d645bf7e71301e23..95442e3f678df42c3b5584c78985aa0df151668e 100644
|
||||
--- a/src/gpu/geometry/GrQuadUtils.cpp
|
||||
+++ b/src/gpu/geometry/GrQuadUtils.cpp
|
||||
@@ -717,7 +717,10 @@ V4f TessellationHelper::EdgeEquations::estimateCoverage(const V4f& x2d, const V4
|
||||
}
|
||||
|
||||
int TessellationHelper::EdgeEquations::computeDegenerateQuad(const V4f& signedEdgeDistances,
|
||||
- V4f* x2d, V4f* y2d) const {
|
||||
+ V4f* x2d, V4f* y2d,
|
||||
+ M4f* aaMask) const {
|
||||
+ *aaMask = signedEdgeDistances != 0.f;
|
||||
+
|
||||
// Move the edge by the signed edge adjustment.
|
||||
V4f oc = fC + signedEdgeDistances;
|
||||
|
||||
@@ -792,10 +795,19 @@ int TessellationHelper::EdgeEquations::computeDegenerateQuad(const V4f& signedEd
|
||||
if (SkScalarAbs(eDenom[0]) > kTolerance) {
|
||||
px = if_then_else(d1v0, V4f(ex[0]), px);
|
||||
py = if_then_else(d1v0, V4f(ey[0]), py);
|
||||
+ // If we replace a vertex with an intersection then it will not fall along the
|
||||
+ // edges that intersect at the original vertex. When we apply AA later to the
|
||||
+ // original points we move along the original 3d edges to move towards the 2d
|
||||
+ // points we're computing here. If we have an AA edge and a non-AA edge we
|
||||
+ // can only move along 1 edge, but now the point we're moving toward isn't
|
||||
+ // on that edge. Thus, we provide an additional degree of freedom by turning
|
||||
+ // AA on for both edges if either edge is AA.
|
||||
+ *aaMask = *aaMask | (d1v0 & skvx::shuffle<2, 0, 3, 1>(*aaMask));
|
||||
}
|
||||
if (SkScalarAbs(eDenom[1]) > kTolerance) {
|
||||
px = if_then_else(d2v0, V4f(ex[1]), px);
|
||||
py = if_then_else(d2v0, V4f(ey[1]), py);
|
||||
+ *aaMask = *aaMask | (d2v0 & skvx::shuffle<2, 0, 3, 1>(*aaMask));
|
||||
}
|
||||
|
||||
*x2d = px;
|
||||
@@ -1156,9 +1168,11 @@ int TessellationHelper::adjustDegenerateVertices(const skvx::Vec<4, float>& sign
|
||||
// handles perspective).
|
||||
V4f x2d = fEdgeVectors.fX2D;
|
||||
V4f y2d = fEdgeVectors.fY2D;
|
||||
+
|
||||
+ M4f aaMask;
|
||||
int vertexCount = this->getEdgeEquations().computeDegenerateQuad(signedEdgeDistances,
|
||||
- &x2d, &y2d);
|
||||
- vertices->moveTo(x2d, y2d, signedEdgeDistances != 0.f);
|
||||
+ &x2d, &y2d, &aaMask);
|
||||
+ vertices->moveTo(x2d, y2d, aaMask);
|
||||
return vertexCount;
|
||||
}
|
||||
}
|
||||
diff --git a/src/gpu/geometry/GrQuadUtils.h b/src/gpu/geometry/GrQuadUtils.h
|
||||
index dbbc4626e5cfb16db0e832e47477132f410ff13b..50b647bdb9c0efbf6faf8002f706b24ad0f0a2e3 100644
|
||||
--- a/src/gpu/geometry/GrQuadUtils.h
|
||||
+++ b/src/gpu/geometry/GrQuadUtils.h
|
||||
@@ -111,7 +111,8 @@ namespace GrQuadUtils {
|
||||
// small, edges are near parallel, or edges are very short/zero-length. Returns number
|
||||
// of effective vertices in the degenerate quad.
|
||||
int computeDegenerateQuad(const skvx::Vec<4, float>& signedEdgeDistances,
|
||||
- skvx::Vec<4, float>* x2d, skvx::Vec<4, float>* y2d) const;
|
||||
+ skvx::Vec<4, float>* x2d, skvx::Vec<4, float>* y2d,
|
||||
+ skvx::Vec<4, int32_t>* aaMask) const;
|
||||
};
|
||||
|
||||
struct OutsetRequest {
|
||||
199
patches/skia/skscalercontext_getimage_less_brittle.patch
Normal file
199
patches/skia/skscalercontext_getimage_less_brittle.patch
Normal file
@@ -0,0 +1,199 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Wagner <bungeman@google.com>
|
||||
Date: Thu, 1 Apr 2021 15:02:21 -0400
|
||||
Subject: SkScalerContext::getImage less brittle.
|
||||
|
||||
Properly handle edge cases like
|
||||
* the temporary glyph being a different size than expected
|
||||
* filters which reduce in size
|
||||
* filters which return false to indicate no filtering has been done
|
||||
|
||||
Bug: chromium:1190525
|
||||
Change-Id: Ibc53eb1d7014210019e96cd6bae3e256d967be54
|
||||
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/392156
|
||||
Commit-Queue: Ben Wagner <bungeman@google.com>
|
||||
Reviewed-by: Herb Derby <herb@google.com>
|
||||
(cherry picked from commit 348ee387a96d7d94733d46ad9e82b19cb890dd16)
|
||||
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/392437
|
||||
|
||||
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
|
||||
index a2df87c3ef62790353b8fac8169d83bc657db3d4..d1cb80a631814e995c756dc23764a21b00e97270 100644
|
||||
--- a/src/core/SkScalerContext.cpp
|
||||
+++ b/src/core/SkScalerContext.cpp
|
||||
@@ -534,41 +534,39 @@ static void generateMask(const SkMask& mask, const SkPath& path,
|
||||
}
|
||||
|
||||
void SkScalerContext::getImage(const SkGlyph& origGlyph) {
|
||||
- const SkGlyph* glyph = &origGlyph;
|
||||
+ const SkGlyph* unfilteredGlyph = &origGlyph;
|
||||
SkGlyph tmpGlyph{origGlyph.getPackedID()};
|
||||
|
||||
// in case we need to call generateImage on a mask-format that is different
|
||||
// (i.e. larger) than what our caller allocated by looking at origGlyph.
|
||||
SkAutoMalloc tmpGlyphImageStorage;
|
||||
|
||||
- if (fMaskFilter) { // restore the prefilter bounds
|
||||
-
|
||||
+ if (fMaskFilter) {
|
||||
// need the original bounds, sans our maskfilter
|
||||
sk_sp<SkMaskFilter> mf = std::move(fMaskFilter);
|
||||
this->getMetrics(&tmpGlyph);
|
||||
fMaskFilter = std::move(mf);
|
||||
|
||||
- // we need the prefilter bounds to be <= filter bounds
|
||||
- SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth);
|
||||
- SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight);
|
||||
-
|
||||
- if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat) {
|
||||
+ // Use the origGlyph storage for the temporary unfiltered mask if it will fit.
|
||||
+ if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat &&
|
||||
+ tmpGlyph.imageSize() <= origGlyph.imageSize())
|
||||
+ {
|
||||
tmpGlyph.fImage = origGlyph.fImage;
|
||||
} else {
|
||||
tmpGlyphImageStorage.reset(tmpGlyph.imageSize());
|
||||
tmpGlyph.fImage = tmpGlyphImageStorage.get();
|
||||
}
|
||||
- glyph = &tmpGlyph;
|
||||
+ unfilteredGlyph = &tmpGlyph;
|
||||
}
|
||||
|
||||
if (!fGenerateImageFromPath) {
|
||||
- generateImage(*glyph);
|
||||
+ generateImage(*unfilteredGlyph);
|
||||
} else {
|
||||
SkPath devPath;
|
||||
- SkMask mask = glyph->mask();
|
||||
+ SkMask mask = unfilteredGlyph->mask();
|
||||
|
||||
- if (!this->internalGetPath(glyph->getPackedID(), &devPath)) {
|
||||
- generateImage(*glyph);
|
||||
+ if (!this->internalGetPath(unfilteredGlyph->getPackedID(), &devPath)) {
|
||||
+ generateImage(*unfilteredGlyph);
|
||||
} else {
|
||||
SkASSERT(SkMask::kARGB32_Format != origGlyph.fMaskFormat);
|
||||
SkASSERT(SkMask::kARGB32_Format != mask.fFormat);
|
||||
@@ -579,39 +577,98 @@ void SkScalerContext::getImage(const SkGlyph& origGlyph) {
|
||||
}
|
||||
|
||||
if (fMaskFilter) {
|
||||
- // the src glyph image shouldn't be 3D
|
||||
- SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat);
|
||||
+ // k3D_Format should not be mask filtered.
|
||||
+ SkASSERT(SkMask::k3D_Format != unfilteredGlyph->fMaskFormat);
|
||||
+
|
||||
+ SkMask filteredMask;
|
||||
+ SkMask srcMask;
|
||||
+ SkMatrix m;
|
||||
+ fRec.getMatrixFrom2x2(&m);
|
||||
+
|
||||
+ if (as_MFB(fMaskFilter)->filterMask(&filteredMask, unfilteredGlyph->mask(), m, nullptr)) {
|
||||
+ // Filter succeeded; filteredMask.fImage was allocated.
|
||||
+ srcMask = filteredMask;
|
||||
+ } else if (unfilteredGlyph->fImage == tmpGlyphImageStorage.get()) {
|
||||
+ // Filter did nothing; unfiltered mask is independent of origGlyph.fImage.
|
||||
+ srcMask = unfilteredGlyph->mask();
|
||||
+ } else if (origGlyph.iRect() == unfilteredGlyph->iRect()) {
|
||||
+ // Filter did nothing; the unfiltered mask is in origGlyph.fImage and matches.
|
||||
+ return;
|
||||
+ } else {
|
||||
+ // Filter did nothing; the unfiltered mask is in origGlyph.fImage and conflicts.
|
||||
+ srcMask = unfilteredGlyph->mask();
|
||||
+ size_t imageSize = unfilteredGlyph->imageSize();
|
||||
+ tmpGlyphImageStorage.reset(imageSize);
|
||||
+ srcMask.fImage = static_cast<uint8_t*>(tmpGlyphImageStorage.get());
|
||||
+ memcpy(srcMask.fImage, unfilteredGlyph->fImage, imageSize);
|
||||
+ }
|
||||
|
||||
- SkMask srcM = glyph->mask(),
|
||||
- dstM;
|
||||
- SkMatrix matrix;
|
||||
+ SkASSERT_RELEASE(srcMask.fFormat == origGlyph.fMaskFormat);
|
||||
+ SkMask dstMask = origGlyph.mask();
|
||||
+ SkIRect origBounds = dstMask.fBounds;
|
||||
|
||||
- fRec.getMatrixFrom2x2(&matrix);
|
||||
+ // Find the intersection of src and dst while updating the fImages.
|
||||
+ if (srcMask.fBounds.fTop < dstMask.fBounds.fTop) {
|
||||
+ int32_t topDiff = dstMask.fBounds.fTop - srcMask.fBounds.fTop;
|
||||
+ srcMask.fImage += srcMask.fRowBytes * topDiff;
|
||||
+ srcMask.fBounds.fTop = dstMask.fBounds.fTop;
|
||||
+ }
|
||||
+ if (dstMask.fBounds.fTop < srcMask.fBounds.fTop) {
|
||||
+ int32_t topDiff = srcMask.fBounds.fTop - dstMask.fBounds.fTop;
|
||||
+ dstMask.fImage += dstMask.fRowBytes * topDiff;
|
||||
+ dstMask.fBounds.fTop = srcMask.fBounds.fTop;
|
||||
+ }
|
||||
|
||||
- if (as_MFB(fMaskFilter)->filterMask(&dstM, srcM, matrix, nullptr)) {
|
||||
- int width = std::min<int>(origGlyph.fWidth, dstM.fBounds.width());
|
||||
- int height = std::min<int>(origGlyph.fHeight, dstM.fBounds.height());
|
||||
- int dstRB = origGlyph.rowBytes();
|
||||
- int srcRB = dstM.fRowBytes;
|
||||
+ if (srcMask.fBounds.fLeft < dstMask.fBounds.fLeft) {
|
||||
+ int32_t leftDiff = dstMask.fBounds.fLeft - srcMask.fBounds.fLeft;
|
||||
+ srcMask.fImage += leftDiff;
|
||||
+ srcMask.fBounds.fLeft = dstMask.fBounds.fLeft;
|
||||
+ }
|
||||
+ if (dstMask.fBounds.fLeft < srcMask.fBounds.fLeft) {
|
||||
+ int32_t leftDiff = srcMask.fBounds.fLeft - dstMask.fBounds.fLeft;
|
||||
+ dstMask.fImage += leftDiff;
|
||||
+ dstMask.fBounds.fLeft = srcMask.fBounds.fLeft;
|
||||
+ }
|
||||
|
||||
- const uint8_t* src = (const uint8_t*)dstM.fImage;
|
||||
- uint8_t* dst = (uint8_t*)origGlyph.fImage;
|
||||
+ if (srcMask.fBounds.fBottom < dstMask.fBounds.fBottom) {
|
||||
+ dstMask.fBounds.fBottom = srcMask.fBounds.fBottom;
|
||||
+ }
|
||||
+ if (dstMask.fBounds.fBottom < srcMask.fBounds.fBottom) {
|
||||
+ srcMask.fBounds.fBottom = dstMask.fBounds.fBottom;
|
||||
+ }
|
||||
|
||||
- if (SkMask::k3D_Format == dstM.fFormat) {
|
||||
- // we have to copy 3 times as much
|
||||
- height *= 3;
|
||||
- }
|
||||
+ if (srcMask.fBounds.fRight < dstMask.fBounds.fRight) {
|
||||
+ dstMask.fBounds.fRight = srcMask.fBounds.fRight;
|
||||
+ }
|
||||
+ if (dstMask.fBounds.fRight < srcMask.fBounds.fRight) {
|
||||
+ srcMask.fBounds.fRight = dstMask.fBounds.fRight;
|
||||
+ }
|
||||
|
||||
- // clean out our glyph, since it may be larger than dstM
|
||||
- //sk_bzero(dst, height * dstRB);
|
||||
+ SkASSERT(srcMask.fBounds == dstMask.fBounds);
|
||||
+ int width = srcMask.fBounds.width();
|
||||
+ int height = srcMask.fBounds.height();
|
||||
+ int dstRB = dstMask.fRowBytes;
|
||||
+ int srcRB = srcMask.fRowBytes;
|
||||
|
||||
- while (--height >= 0) {
|
||||
- memcpy(dst, src, width);
|
||||
- src += srcRB;
|
||||
- dst += dstRB;
|
||||
- }
|
||||
- SkMask::FreeImage(dstM.fImage);
|
||||
+ const uint8_t* src = srcMask.fImage;
|
||||
+ uint8_t* dst = dstMask.fImage;
|
||||
+
|
||||
+ if (SkMask::k3D_Format == filteredMask.fFormat) {
|
||||
+ // we have to copy 3 times as much
|
||||
+ height *= 3;
|
||||
+ }
|
||||
+
|
||||
+ // If not filling the full original glyph, clear it out first.
|
||||
+ if (dstMask.fBounds != origBounds) {
|
||||
+ sk_bzero(origGlyph.fImage, origGlyph.fHeight * origGlyph.rowBytes());
|
||||
+ }
|
||||
+
|
||||
+ while (--height >= 0) {
|
||||
+ memcpy(dst, src, width);
|
||||
+ src += srcRB;
|
||||
+ dst += dstRB;
|
||||
}
|
||||
+ SkMask::FreeImage(filteredMask.fImage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
fix_a_use-after-free_bug_for_the_userland_stack.patch
|
||||
cherry_picking_improve_the_input_validation_and_processing_of.patch
|
||||
cherry_picking_clean_up_more_resources_of_an_existing_sctp.patch
|
||||
cherry_picking_harden_the_handling_of_outgoing_streams.patch
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Tuexen <tuexen@fh-muenster.de>
|
||||
Date: Sat, 12 Dec 2020 23:30:59 +0100
|
||||
Subject: Cherry picking: Clean up more resouces of an existing SCTP
|
||||
association in case of a restart.
|
||||
|
||||
This fixes a use-after-free scenario, which was reported by Felix
|
||||
Wilhelm from Google in case a peer is able to modify the cookie.
|
||||
However, this can also be triggered by an assciation restart under
|
||||
some specific conditions.
|
||||
|
||||
diff --git a/usrsctplib/netinet/sctp_input.c b/usrsctplib/netinet/sctp_input.c
|
||||
index b8e1259d8cf0c90cf2dcb03a1fd853c11a6abbd3..5f16f85add50796a2f28227d89cc397d01ed10d4 100755
|
||||
--- a/usrsctplib/netinet/sctp_input.c
|
||||
+++ b/usrsctplib/netinet/sctp_input.c
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 366248 2020-09-29 09:36:06Z tuexen $");
|
||||
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 368593 2020-12-12 22:23:45Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@@ -1607,6 +1607,11 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
struct sctp_association *asoc;
|
||||
struct sctp_init_chunk *init_cp, init_buf;
|
||||
struct sctp_init_ack_chunk *initack_cp, initack_buf;
|
||||
+ struct sctp_asconf_addr *aparam, *naparam;
|
||||
+ struct sctp_asconf_ack *aack, *naack;
|
||||
+ struct sctp_tmit_chunk *chk, *nchk;
|
||||
+ struct sctp_stream_reset_list *strrst, *nstrrst;
|
||||
+ struct sctp_queued_to_read *sq, *nsq;
|
||||
struct sctp_nets *net;
|
||||
struct mbuf *op_err;
|
||||
struct timeval old;
|
||||
@@ -1903,8 +1908,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
* kick us so it COULD still take a timeout
|
||||
* to move these.. but it can't hurt to mark them.
|
||||
*/
|
||||
- struct sctp_tmit_chunk *chk;
|
||||
- TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
|
||||
+ TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
|
||||
if (chk->sent < SCTP_DATAGRAM_RESEND) {
|
||||
chk->sent = SCTP_DATAGRAM_RESEND;
|
||||
sctp_flight_size_decrease(chk);
|
||||
@@ -2096,6 +2100,57 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
stcb->asoc.strmout[i].next_mid_unordered = 0;
|
||||
stcb->asoc.strmout[i].last_msg_incomplete = 0;
|
||||
}
|
||||
+ TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
|
||||
+ TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
|
||||
+ SCTP_FREE(strrst, SCTP_M_STRESET);
|
||||
+ }
|
||||
+ TAILQ_FOREACH_SAFE(sq, &asoc->pending_reply_queue, next, nsq) {
|
||||
+ TAILQ_REMOVE(&asoc->pending_reply_queue, sq, next);
|
||||
+ if (sq->data) {
|
||||
+ sctp_m_freem(sq->data);
|
||||
+ sq->data = NULL;
|
||||
+ }
|
||||
+ sctp_free_remote_addr(sq->whoFrom);
|
||||
+ sq->whoFrom = NULL;
|
||||
+ sq->stcb = NULL;
|
||||
+ sctp_free_a_readq(stcb, sq);
|
||||
+ }
|
||||
+ TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) {
|
||||
+ TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
|
||||
+ if (chk->data) {
|
||||
+ sctp_m_freem(chk->data);
|
||||
+ chk->data = NULL;
|
||||
+ }
|
||||
+ if (chk->holds_key_ref)
|
||||
+ sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
|
||||
+ sctp_free_remote_addr(chk->whoTo);
|
||||
+ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
|
||||
+ SCTP_DECR_CHK_COUNT();
|
||||
+ }
|
||||
+ TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) {
|
||||
+ TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next);
|
||||
+ if (chk->data) {
|
||||
+ sctp_m_freem(chk->data);
|
||||
+ chk->data = NULL;
|
||||
+ }
|
||||
+ if (chk->holds_key_ref)
|
||||
+ sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
|
||||
+ sctp_free_remote_addr(chk->whoTo);
|
||||
+ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
|
||||
+ SCTP_DECR_CHK_COUNT();
|
||||
+ }
|
||||
+ TAILQ_FOREACH_SAFE(aparam, &asoc->asconf_queue, next, naparam) {
|
||||
+ TAILQ_REMOVE(&asoc->asconf_queue, aparam, next);
|
||||
+ SCTP_FREE(aparam,SCTP_M_ASC_ADDR);
|
||||
+ }
|
||||
+ TAILQ_FOREACH_SAFE(aack, &asoc->asconf_ack_sent, next, naack) {
|
||||
+ TAILQ_REMOVE(&asoc->asconf_ack_sent, aack, next);
|
||||
+ if (aack->data != NULL) {
|
||||
+ sctp_m_freem(aack->data);
|
||||
+ }
|
||||
+ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), aack);
|
||||
+ }
|
||||
+
|
||||
/* process the INIT-ACK info (my info) */
|
||||
asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
|
||||
asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
|
||||
@@ -0,0 +1,54 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Tuexen <tuexen@fh-muenster.de>
|
||||
Date: Mon, 14 Dec 2020 00:57:51 +0100
|
||||
Subject: Cherry picking: Harden the handling of outgoing streams in case of an
|
||||
restart or INIT collision.
|
||||
|
||||
This avouds an out-of-bounce access in case the peer can
|
||||
break the cookie signature. Thanks to Felix Wilhelm from Google for
|
||||
reporting the issue.
|
||||
|
||||
diff --git a/usrsctplib/netinet/sctp_input.c b/usrsctplib/netinet/sctp_input.c
|
||||
index 5f16f85add50796a2f28227d89cc397d01ed10d4..d538c347b967b89d99c7cdaf1fef173107319783 100755
|
||||
--- a/usrsctplib/netinet/sctp_input.c
|
||||
+++ b/usrsctplib/netinet/sctp_input.c
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 368593 2020-12-12 22:23:45Z tuexen $");
|
||||
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 368622 2020-12-13 23:51:51Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@@ -1898,7 +1898,9 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
NULL);
|
||||
}
|
||||
asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
|
||||
- asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
|
||||
+ if (asoc->pre_open_streams < asoc->streamoutcnt) {
|
||||
+ asoc->pre_open_streams = asoc->streamoutcnt;
|
||||
+ }
|
||||
|
||||
if (ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) {
|
||||
/* Ok the peer probably discarded our
|
||||
@@ -2052,8 +2054,9 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
/* move to OPEN state, if not in SHUTDOWN_SENT */
|
||||
SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
|
||||
}
|
||||
- asoc->pre_open_streams =
|
||||
- ntohs(initack_cp->init.num_outbound_streams);
|
||||
+ if (asoc->pre_open_streams < asoc->streamoutcnt) {
|
||||
+ asoc->pre_open_streams = asoc->streamoutcnt;
|
||||
+ }
|
||||
asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
|
||||
asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
|
||||
asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
|
||||
@@ -2373,7 +2376,6 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
|
||||
/* process the INIT-ACK info (my info) */
|
||||
asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
|
||||
asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
|
||||
- asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
|
||||
asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
|
||||
asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
|
||||
asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user