Compare commits

..

60 Commits

Author SHA1 Message Date
Sudowoodo Release Bot
8492c10291 Bump v12.2.3 2021-11-15 10:31:45 -08:00
trop[bot]
df8611de59 test: deflake <webview> tag loads devtools extensions on WOA (#31717)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-11-04 16:35:50 -04:00
Pedro Pontes
2141287cb8 chore: cherry-pick 91dd4f79ab5b from chromium (#31683)
* chore: cherry-pick 91dd4f79ab5b from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-11-04 13:02:36 -04:00
Pedro Pontes
bec5e8fc1e chore: cherry-pick 656c2769c5 from v8 (#31679)
* chore: cherry-pick 014e1f857c33 from v8 (#31674)

* chore: cherry-pick 014e1f857c33 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>

* chore: cherry-pick 656c2769c5 from v8

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-11-03 13:03:22 -04:00
Pedro Pontes
e83201297a chore: cherry-pick 014e1f857c33 from v8 (#31674)
* chore: cherry-pick 014e1f857c33 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-11-03 20:39:48 +09:00
Pedro Pontes
a3be71d6e7 chore: cherry-pick feef10137b16 from v8 (#31666)
* chore: cherry-pick feef10137b16 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-11-02 14:36:47 -04:00
trop[bot]
5aa2271ae7 fix: don't use private enterprise APIs in MAS build (#31527)
* fix: don't use private enterprise APIs in MAS build

* chore: update .patches

* chore: update patch

Co-authored-by: VerteDinde <khammond@slack-corp.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-11-02 09:54:12 +09:00
Pedro Pontes
e61cbbd13e chore: cherry-pick 0894af410c4e from chromium (#31546)
* chore: cherry-pick 0894af410c4e from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-10-25 14:59:05 -04:00
Pedro Pontes
6cc7de5c13 chore: cherry-pick 36028012d897 from chromium (#31542)
Co-authored-by: Electron Bot <electron@github.com>
2021-10-25 11:42:18 -04:00
Pedro Pontes
a83d1fe68a chore: cherry-pick c69dddfe1cde from chromium (#31522) 2021-10-22 21:19:58 +09:00
Pedro Pontes
5759a52589 chore: cherry-pick 6de4e210688e from v8 (#31504)
* chore: cherry-pick 6de4e210688e from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-10-22 21:15:29 +09:00
Pedro Pontes
8416737917 chore: cherry-pick 8a822e28adea from pdfium (#31496) 2021-10-22 21:13:34 +09:00
Pedro Pontes
7313f7ebeb chore: cherry-pick 2e7c9b33453b from chromium (#31500) 2021-10-21 16:09:06 -04:00
Pedro Pontes
4b969e90bf chore: cherry-pick 6584528aeb0f0 from webrtc and 36e370cf4db9a from chromium (#31360)
* chore: cherry-pick 6584528aeb0f0 from webrtc and 36e370cf4db9a from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-10-12 09:10:07 +09:00
Sudowoodo Release Bot
9183507c6f Bump v12.2.2 2021-10-11 10:12:26 -07:00
Pedro Pontes
1f6ecd6424 chore: cherry-pick 3a5bafa35def from chromium (#31366) 2021-10-11 13:27:42 +02:00
Pedro Pontes
06b5cf9395 chore: cherry-pick 6a8a2098f9fa from chromium (#31232)
* chore: cherry-pick 6a8a2098f9fa from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-10-09 23:23:48 -07:00
Pedro Pontes
f3e5920f66 refactor: only access memory coordinator interface from browser process (#31305) (#31342)
Backport of #31295

Co-authored-by: Robo <hop2deep@gmail.com>
2021-10-08 03:30:38 -07:00
Pedro Pontes
e2f4ddbc42 chore: cherry-pick efd8e01ac1a6 from chromium (#31244)
* chore: cherry-pick efd8e01ac1a6 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-10-04 06:55:29 -07:00
Pedro Pontes
f5357caafa chore: cherry-pick e8a5cefd1aac from chromium (#31247)
* chore: cherry-pick e8a5cefd1aac from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-10-04 03:04:44 -07:00
Pedro Pontes
b846a32bc5 chore: cherry-pick 4e528a5a8d83 from chromium (#31241)
* chore: cherry-pick 4e528a5a8d83 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-10-03 23:57:48 -07:00
Pedro Pontes
09e40aca61 chore: cherry-pick e8cb0e7aa32 from angle (#31237) 2021-10-03 23:48:39 -07:00
Pedro Pontes
f5e1934fb6 chore: cherry-pick 5c4acf2ae64a from v8 (#31229)
* chore: cherry-pick 5c4acf2ae64a from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-10-03 23:41:27 -07:00
trop[bot]
5c5ccfd178 fix: remove expired DST Root CA X3 (#31269)
* Revert "fix: Enable X509_V_FLAG_TRUSTED_FIRST flag in BoringSSL (#31215)"

This reverts commit 3bb36a62cb.

* fix: remove expired DST Root CA X3

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2021-10-03 20:57:30 -07:00
John Kleinschmidt
e395cd391a fix: persist permission granted to serial ports (#31193)
(cherry picked from commit b36aaa8193)
2021-10-04 10:09:36 +09:00
Sudowoodo Release Bot
9a25e9e010 Bump v12.2.1 2021-09-30 13:59:20 -07:00
trop[bot]
504ecb4931 fix: Enable X509_V_FLAG_TRUSTED_FIRST flag in BoringSSL (#31214)
* fix: Enable X509_V_FLAG_TRUSTED_FIRST flag in BoringSSL

Fixes: https://github.com/electron/electron/issues/31212
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>

* Update .patches

* chore: update patches

Co-authored-by: Juan Cruz Viotti <jv@jviotti.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-09-30 16:58:04 -04:00
Pedro Pontes
8a9811a29d chore: cherry-pick f8a74d72f3 from chromium. (#31211)
Co-authored-by: Electron Bot <electron@github.com>
2021-09-30 13:55:12 -04:00
Pedro Pontes
6370ff866a chore: cherry-pick 85123ea32b from chromium (#31203) 2021-09-30 09:54:16 -04:00
Sudowoodo Release Bot
22373d0d18 Bump v12.2.0 2021-09-28 01:11:40 -07:00
trop[bot]
43de53d78c fix: .lldbinit config stale (unavailable) (#31157)
Co-authored-by: Black-Hole1 <158blackhole@gmail.com>
2021-09-28 09:52:42 +02:00
trop[bot]
4b10899dfa feat: add webContents.fromDevToolsTargetId() (#30730)
* feat: add webContents.fromDevToolsTargetId()

* refactor: avoid using FromOrCreate

Co-authored-by: samuelmaddock <samuel.maddock@gmail.com>
2021-09-22 08:53:31 +09:00
Pedro Pontes
ea36d3a27f chore: cherry-pick ddc4cf156505 from chromium (#30963)
* chore: cherry-pick ddc4cf156505 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-09-21 18:02:16 -04:00
Pedro Pontes
d0b8685d92 chore: cherry-pick 6215793f008f from chromium (#30953)
* chore: cherry-pick 6215793f008f from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-09-21 16:26:22 +09:00
Pedro Pontes
0f47c63860 chore: cherry-pick 72473550f6ff from angle (#30961)
* chore: cherry-pick 72473550f6ff from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-09-21 14:41:30 +09:00
Pedro Pontes
365a10c767 chore: cherry-pick 8623d711677d from chromium (#30946)
* chore: cherry-pick 8623d711677d from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-09-21 14:40:37 +09:00
trop[bot]
2becb29a37 chore: cherry-pick fix for 1233564 from chromium (#30754)
* chore: cherry-pick fix for 1233564 from chromium (#30636)

* chore: cherry-pick fix for 1233564 from chromium

Protect HRTF database loader thread from access by different threads

This patch add a new mutex locker around the HRTF database loader
thread to ensure the safe exclusive access of the loader thread
and the HRTF database.

(cherry picked from commit 6811e850ee10847da16c4d5fdc0f845494586b65)

Bug: 1233564
Change-Id: Ie12b99ffe520d3747e34af387a37637a10aab38a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3068260
Auto-Submit: Hongchan Choi <hongchan@chromium.org>
Commit-Queue: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>

[modify] https://crrev.com/033f0bdcbe538c61f532e97b03cb9c092a94b413/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc
[modify] https://crrev.com/033f0bdcbe538c61f532e97b03cb9c092a94b413/third_party/blink/renderer/platform/audio/hrtf_database_loader.h

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>

* Update .patches

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-09-21 10:40:02 +09:00
Pedro Pontes
b711ec1634 chore: cherry-pick 0c6f5c65fa from chromium (#30951)
Co-authored-by: Electron Bot <electron@github.com>
2021-09-21 10:37:14 +09:00
Pedro Pontes
2afeea4c43 chore: cherry-pick 6048fcd52f42 from chromium (#30944)
* chore: cherry-pick 6048fcd52f42 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-09-21 10:35:23 +09:00
Pedro Pontes
fed1c7993c chore: cherry-pick 13842c96c2 from chromium and 018f85dea1 from angle (#30958) 2021-09-21 08:49:45 +09:00
Pedro Pontes
cdb1961ef5 chore: cherry-pick 7699615c0d and 2f5740f50f from chromium (#30942)
Co-authored-by: Electron Bot <electron@github.com>
2021-09-21 08:48:12 +09:00
Sudowoodo Release Bot
f86a8b21f5 Bump v12.1.2 2021-09-20 11:06:19 -07:00
Pedro Pontes
745a4f9695 chore: cherry pick 9723e3c13c from chromium (#30965) 2021-09-16 18:23:35 -04:00
Pedro Pontes
bf32321f4b chore: cherry-pick 034c2003be31 from v8 (#30940)
* chore: cherry-pick 034c2003be31 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-09-15 10:13:07 -04:00
Sudowoodo Release Bot
05c31e9121 Bump v12.1.1 2021-09-13 14:41:28 -07:00
trop[bot]
b4d322a505 fix: show maximized frameless window (#30863)
* fix: show maximized frameless window

* test: show maximized transparent window

* fix: test using wrong bounds

BrowserWindow will be sized to the workArea when the Windows taskbar is
visible.

Co-authored-by: samuelmaddock <samuel.maddock@gmail.com>
2021-09-08 08:43:05 +09:00
Pedro Pontes
5ff2f654d1 chore: cherry-pick d1eade9d39 from chromium (#30818) 2021-09-06 14:49:20 +09:00
Pedro Pontes
87b55ceacb chore: cherry-pick d727013bb543 from chromium (#30816)
* chore: cherry-pick d727013bb543 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-09-06 14:47:27 +09:00
Pedro Pontes
da5a627201 chore: cherry-pick fbfd2557c2ab from v8 (#30822)
* chore: cherry-pick fbfd2557c2ab from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-09-03 13:50:20 -07:00
trop[bot]
83a3a8995f chore: cherry-pick fix for 1231134 from chromium (#30762)
* chore: cherry-pick fix for 1231134 from chromium (#30637)

* chore: cherry-pick fix for 1231134 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>

* Update .patches

* chore: update patches

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-09-02 12:10:59 -04:00
Sudowoodo Release Bot
ea234f9cb9 Bump v12.1.0 2021-08-31 12:05:51 -07:00
trop[bot]
013825c986 chore: cherry-pick fix for 1234770 from v8 (#30634)
* chore: cherry-pick fix for 1234770 from v8 (#30586)

* chore: cherry-pick fix for 1234770 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>

* Update .patches

* chore: update patches

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-08-30 21:26:02 +09:00
Cheng Zhao
c7d61b6ac6 chore: cherry-pick fix for 1234829 from angle (#30624)
* chore: cherry-pick fix for 1234829 from angle

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-08-30 19:34:03 +09:00
trop[bot]
cdf0387f6f chore: cherry-pick fix for 1234764 from v8 (#30660)
* chore: cherry-pick fix for 1234764 from v8 (#30587)

* chore: cherry-pick fix for 1234764 from v8

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>

* Update .patches

* chore: update patches

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-08-30 19:33:37 +09:00
Jeremy Rose
d3e7f2b302 fix: remove ipc wrapper for nativeImage.createThumbnailFromPath (#30737) 2021-08-30 19:32:36 +09:00
Sudowoodo Release Bot
21258845f0 Bump v12.0.18 2021-08-27 10:19:01 -07:00
trop[bot]
96bcadd290 fix: {exit|enter}-html-fullscreen emitted after esc in webview (#30669)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-08-24 10:47:02 +02:00
trop[bot]
ee1030e044 chore: cherry-pick fix for 1227933 from chromium (#30615)
* chore: cherry-pick 1227933 from chromium

* chore: update patches

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-08-23 17:06:27 +09:00
trop[bot]
11d1bfa071 chore: cherry-pick 4ce2abc17078 from chromium (#30581)
* chore: cherry-pick 4ce2abc17078 from chromium (#30449)

* chore: cherry-pick 4ce2abc17078 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>

* Update .patches

* chore: update patches

Co-authored-by: Steven Barbaro <StevenEBarbaro@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-08-19 15:11:48 +09:00
trop[bot]
131be8cefd chore: cherry-pick e2123a8e0943 from chromium (#30580)
* chore: cherry-pick e2123a8e0943 from chromium

* chore: update patches

* chore: update patches

Co-authored-by: Steven Barbaro <StevenEBarbaro@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-08-19 08:25:58 +09:00
86 changed files with 7154 additions and 105 deletions

View File

@@ -1 +1 @@
12.0.17
12.2.3

View File

@@ -45,6 +45,26 @@ returns `null`.
Returns `WebContents` | undefined - A WebContents instance with the given ID, or
`undefined` if there is no WebContents associated with the given ID.
### `webContents.fromDevToolsTargetId(targetId)`
* `targetId` String - The Chrome DevTools Protocol [TargetID](https://chromedevtools.github.io/devtools-protocol/tot/Target/#type-TargetID) associated with the WebContents instance.
Returns `WebContents` | undefined - A WebContents instance with the given TargetID, or
`undefined` if there is no WebContents associated with the given TargetID.
When communicating with the [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/),
it can be useful to lookup a WebContents instance based on its assigned TargetID.
```js
async function lookupTargetId (browserWindow) {
const wc = browserWindow.webContents
await wc.debugger.attach('1.3')
const { targetInfo } = await wc.debugger.sendCommand('Target.getTargetInfo')
const { targetId } = targetInfo
const targetWebContents = await webContents.fromDevToolsTargetId(targetId)
}
```
## Class: WebContents
> Render and control the contents of a BrowserWindow instance.

View File

@@ -26,7 +26,9 @@ you prefer a graphical interface.
* **.lldbinit**: Create or edit `~/.lldbinit` to allow Chromium code to be properly source-mapped.
```text
command script import ~/electron/src/tools/lldb/lldbinit.py
# e.g: ['~/electron/src/tools/lldb']
script sys.path[:0] = ['<...path/to/electron/src/tools/lldb>']
script import lldbinit
```
## Attaching to and Debugging Electron

View File

@@ -737,6 +737,10 @@ export function fromId (id: string) {
return binding.fromId(id);
}
export function fromDevToolsTargetId (targetId: string) {
return binding.fromDevToolsTargetId(targetId);
}
export function getFocusedWebContents () {
let focused = null;
for (const contents of binding.getAllWebContents()) {

View File

@@ -1,6 +1,6 @@
import { app } from 'electron/main';
import type { WebContents } from 'electron/main';
import { clipboard, nativeImage } from 'electron/common';
import { clipboard } from 'electron/common';
import * as fs from 'fs';
import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils';
@@ -38,6 +38,10 @@ ipcMainInternal.handle(IPC_MESSAGES.BROWSER_GET_LAST_WEB_PREFERENCES, function (
return event.sender.getLastWebPreferences();
});
ipcMainInternal.handle(IPC_MESSAGES.BROWSER_GET_PROCESS_MEMORY_INFO, function (event) {
return event.sender._getProcessMemoryInfo();
});
// Methods not listed in this set are called directly in the renderer process.
const allowedClipboardMethods = (() => {
switch (process.platform) {
@@ -113,7 +117,3 @@ ipcMainUtils.handleSync(IPC_MESSAGES.BROWSER_SANDBOX_LOAD, async function (event
ipcMainInternal.on(IPC_MESSAGES.BROWSER_PRELOAD_ERROR, function (event, preloadPath: string, error: Error) {
event.sender.emit('preload-error', event, preloadPath, error);
});
ipcMainInternal.handle(IPC_MESSAGES.NATIVE_IMAGE_CREATE_THUMBNAIL_FROM_PATH, async (_, path: string, size: Electron.Size) => {
return typeUtils.serialize(await nativeImage.createThumbnailFromPath(path, size));
});

View File

@@ -4,6 +4,7 @@ export const enum IPC_MESSAGES {
BROWSER_PRELOAD_ERROR = 'BROWSER_PRELOAD_ERROR',
BROWSER_SANDBOX_LOAD = 'BROWSER_SANDBOX_LOAD',
BROWSER_WINDOW_CLOSE = 'BROWSER_WINDOW_CLOSE',
BROWSER_GET_PROCESS_MEMORY_INFO = 'BROWSER_GET_PROCESS_MEMORY_INFO',
GUEST_INSTANCE_VISIBILITY_CHANGE = 'GUEST_INSTANCE_VISIBILITY_CHANGE',
@@ -39,5 +40,4 @@ export const enum IPC_MESSAGES {
INSPECTOR_SELECT_FILE = 'INSPECTOR_SELECT_FILE',
DESKTOP_CAPTURER_GET_SOURCES = 'DESKTOP_CAPTURER_GET_SOURCES',
NATIVE_IMAGE_CREATE_THUMBNAIL_FROM_PATH = 'NATIVE_IMAGE_CREATE_THUMBNAIL_FROM_PATH',
}

View File

@@ -1,11 +1,3 @@
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
import { deserialize } from '@electron/internal/common/type-utils';
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
const { nativeImage } = process._linkedBinding('electron_common_native_image');
nativeImage.createThumbnailFromPath = async (path: string, size: Electron.Size) => {
return deserialize(await ipcRendererInternal.invoke(IPC_MESSAGES.NATIVE_IMAGE_CREATE_THUMBNAIL_FROM_PATH, path, size));
};
export default nativeImage;

View File

@@ -1,5 +1,6 @@
import * as path from 'path';
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
import type * as ipcRendererInternalModule from '@electron/internal/renderer/ipc-renderer-internal';
const Module = require('module');
@@ -39,7 +40,7 @@ require('@electron/internal/common/init');
// The global variable will be used by ipc for event dispatching
const v8Util = process._linkedBinding('electron_common_v8_util');
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal');
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal') as typeof ipcRendererInternalModule;
const ipcRenderer = require('@electron/internal/renderer/api/ipc-renderer').default;
v8Util.setHiddenValue(global, 'ipcNative', {
@@ -49,6 +50,10 @@ v8Util.setHiddenValue(global, 'ipcNative', {
}
});
process.getProcessMemoryInfo = () => {
return ipcRendererInternal.invoke<Electron.ProcessMemoryInfo>(IPC_MESSAGES.BROWSER_GET_PROCESS_MEMORY_INFO);
};
// Use electron module after everything is ready.
const { webFrameInit } = require('@electron/internal/renderer/web-frame-init');
webFrameInit();

View File

@@ -2,6 +2,7 @@
/* global binding */
import * as events from 'events';
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
import type * as ipcRendererInternalModule from '@electron/internal/renderer/ipc-renderer-internal';
const { EventEmitter } = events;
@@ -20,7 +21,7 @@ for (const prop of Object.keys(EventEmitter.prototype) as (keyof typeof process)
}
Object.setPrototypeOf(process, EventEmitter.prototype);
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal');
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal') as typeof ipcRendererInternalModule;
const ipcRendererUtils = require('@electron/internal/renderer/ipc-renderer-internal-utils');
const {
@@ -85,6 +86,10 @@ Object.assign(preloadProcess, processProps);
Object.assign(process, binding.process);
Object.assign(process, processProps);
process.getProcessMemoryInfo = preloadProcess.getProcessMemoryInfo = () => {
return ipcRendererInternal.invoke<Electron.ProcessMemoryInfo>(IPC_MESSAGES.BROWSER_GET_PROCESS_MEMORY_INFO);
};
Object.defineProperty(preloadProcess, 'noDeprecation', {
get () {
return process.noDeprecation;

View File

@@ -1,6 +1,6 @@
{
"name": "electron",
"version": "12.0.17",
"version": "12.2.3",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {

View File

@@ -1,2 +1,7 @@
d3d11_skip_blits_if_there_is_no_intersection_of_dest_areas.patch
cherry-pick-3d4f87ab5b9b.patch
cherry-pick-d8cb996.patch
cherry-pick-1fb846c.patch
cherry-pick-72473550f6ff.patch
webgl_make_unsuccessful_links_fail_subsequent_draw_calls.patch
fix_integer_overflow_in_blocklayoutencoder.patch

View File

@@ -0,0 +1,90 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexey Knyazev <lexa.knyazev@gmail.com>
Date: Tue, 3 Aug 2021 01:57:49 +0400
Subject: Validate texStorage dimensions with compressed formats
Bug: angleproject:6230
Change-Id: I501ec1e6974bdc7e6731dcb88045edb0aa22b888
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3067329
Commit-Queue: Alexey Knyazev <lexa.knyazev@gmail.com>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/validationES3.cpp b/src/libANGLE/validationES3.cpp
index 1d93a066580818c7616fa66252e6465f6137aceb..3935c52a894c5584eef66bea34a8684176909358 100644
--- a/src/libANGLE/validationES3.cpp
+++ b/src/libANGLE/validationES3.cpp
@@ -1339,17 +1339,26 @@ bool ValidateES3TexStorageParametersBase(const Context *context,
return false;
}
- if (formatInfo.compressed && target == TextureType::Rectangle)
+ if (formatInfo.compressed)
{
- context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
- return false;
- }
+ if (target == TextureType::Rectangle)
+ {
+ context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
+ return false;
+ }
- if (formatInfo.compressed && target == TextureType::_3D)
- {
- if (!ValidateES3CompressedFormatForTexture3D(context, formatInfo.internalFormat))
+ if (target == TextureType::_3D)
{
- // Error already generated.
+ if (!ValidateES3CompressedFormatForTexture3D(context, formatInfo.internalFormat))
+ {
+ // Error already generated.
+ return false;
+ }
+ }
+
+ if (!ValidCompressedImageSize(context, formatInfo.internalFormat, 0, width, height, depth))
+ {
+ context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
return false;
}
}
diff --git a/src/tests/gl_tests/SRGBTextureTest.cpp b/src/tests/gl_tests/SRGBTextureTest.cpp
index 68fd9f7165ff237ed3c86a42be0b2a24dd9819c7..6c65740cb406e1c598dc41ff0e8998230a926883 100644
--- a/src/tests/gl_tests/SRGBTextureTest.cpp
+++ b/src/tests/gl_tests/SRGBTextureTest.cpp
@@ -340,7 +340,7 @@ TEST_P(SRGBTextureTestES3, SRGBOverrideFormats)
{
GLTexture tex;
glBindTexture(GL_TEXTURE_2D, tex.get());
- glTexStorage2D(GL_TEXTURE_2D, 1, format, 1, 1);
+ glTexStorage2D(GL_TEXTURE_2D, 1, format, 4, 4);
GLenum error = glGetError();
if (error == GL_INVALID_ENUM)
{
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 89eb4d639a3853636524ad112a24f15d46fa1119..b9380bb10ad434acfc858c08db8a629db0bfaecf 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -5023,6 +5023,21 @@ void WebGLCompatibilityTest::testCompressedTexLevelDimension(GLenum format,
{
EXPECT_GL_ERROR(expectedError) << explanation;
}
+
+ if (level == 0 && width > 0 && getClientMajorVersion() >= 3)
+ {
+ GLTexture sourceTextureStorage;
+ glBindTexture(GL_TEXTURE_2D, sourceTextureStorage);
+ glTexStorage2D(GL_TEXTURE_2D, 1, format, width, height);
+ if (expectedError == 0)
+ {
+ EXPECT_GL_NO_ERROR() << explanation << " (texStorage)";
+ }
+ else
+ {
+ EXPECT_GL_ERROR(expectedError) << explanation << " (texStorage)";
+ }
+ }
}
void WebGLCompatibilityTest::testCompressedTexImage(GLenum format)

View File

@@ -0,0 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Wed, 1 Sep 2021 12:17:26 -0400
Subject: D3D11: Fix overflow in GenerateInitialTextureData.
Our use of unchecked math was causing OOB accesses with very large
textures. Unfortunately it's not easy to make a passing test that
reproduces this OOB access.
Bug: chromium:1241036
Change-Id: Icd2749f5b3116bb51390ce769fef22c49a11f307
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3136733
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
(cherry picked from commit 794b13ce9f874d472729ebd69897bc7ab9340a4b)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3149277
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
index 8321bb60cd947349d278167ea2d0343282963268..7588a161ebae2690edc51b755981f6613ca5bb43 100644
--- a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -2179,28 +2179,35 @@ angle::Result GenerateInitialTextureData(
const d3d11::DXGIFormatSize &dxgiFormatInfo =
d3d11::GetDXGIFormatSizeInfo(d3dFormatInfo.texFormat);
- unsigned int rowPitch = dxgiFormatInfo.pixelBytes * width;
- unsigned int depthPitch = rowPitch * height;
- unsigned int maxImageSize = depthPitch * depth;
+ using CheckedSize = angle::CheckedNumeric<size_t>;
+ CheckedSize rowPitch = CheckedSize(dxgiFormatInfo.pixelBytes) * CheckedSize(width);
+ CheckedSize depthPitch = rowPitch * CheckedSize(height);
+ CheckedSize maxImageSize = depthPitch * CheckedSize(depth);
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+ ANGLE_CHECK_GL_ALLOC(context11, maxImageSize.IsValid());
angle::MemoryBuffer *scratchBuffer = nullptr;
- ANGLE_CHECK_GL_ALLOC(GetImplAs<Context11>(context),
- context->getScratchBuffer(maxImageSize, &scratchBuffer));
+ ANGLE_CHECK_GL_ALLOC(context11,
+ context->getScratchBuffer(maxImageSize.ValueOrDie(), &scratchBuffer));
- d3dFormatInfo.dataInitializerFunction(width, height, depth, scratchBuffer->data(), rowPitch,
- depthPitch);
+ d3dFormatInfo.dataInitializerFunction(width, height, depth, scratchBuffer->data(),
+ rowPitch.ValueOrDie(), depthPitch.ValueOrDie());
for (unsigned int i = 0; i < mipLevels; i++)
{
unsigned int mipWidth = std::max(width >> i, 1U);
unsigned int mipHeight = std::max(height >> i, 1U);
- unsigned int mipRowPitch = dxgiFormatInfo.pixelBytes * mipWidth;
- unsigned int mipDepthPitch = mipRowPitch * mipHeight;
+ using CheckedUINT = angle::CheckedNumeric<UINT>;
+ CheckedUINT mipRowPitch = CheckedUINT(dxgiFormatInfo.pixelBytes) * CheckedUINT(mipWidth);
+ CheckedUINT mipDepthPitch = mipRowPitch * CheckedUINT(mipHeight);
+
+ ANGLE_CHECK_GL_ALLOC(context11, mipRowPitch.IsValid() && mipDepthPitch.IsValid());
outSubresourceData->at(i).pSysMem = scratchBuffer->data();
- outSubresourceData->at(i).SysMemPitch = mipRowPitch;
- outSubresourceData->at(i).SysMemSlicePitch = mipDepthPitch;
+ outSubresourceData->at(i).SysMemPitch = mipRowPitch.ValueOrDie();
+ outSubresourceData->at(i).SysMemSlicePitch = mipDepthPitch.ValueOrDie();
}
return angle::Result::Continue;

View File

@@ -0,0 +1,300 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kenneth Russell <kbr@chromium.org>
Date: Wed, 4 Aug 2021 18:15:51 -0700
Subject: In WebGL, constrain base level of compressed textures.
Enforce that if a mipmap level > 0 is specified for a compressed
texture, that it implies that the size of the base level of the
texture is a multiple of the format's block size.
Makes the test changes in
https://github.com/KhronosGroup/WebGL/pull/3304 largely pass. There
are some needed follow-on fixes to that PR, and this CL changes a
sub-test result in the existing S3TC and S3TC-sRGB tests which will
need to be suppressed Chromium-side first.
Bug: angleproject:6245
Change-Id: I7723d7882091b78a353d8d273e80b819dd384021
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3072568
Commit-Queue: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 74acb9e0c4d87c08478dd334a1b38124fab9f94f..4ed0ea4f47c89090d06f706199d32bb0f5b745b9 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -985,6 +985,15 @@ bool ValidCompressedDimension(GLsizei size, GLuint blockSize, GLint level)
return (level > 0) || (size % blockSize == 0);
}
+bool ValidCompressedBaseLevelForWebGL(GLsizei size, GLuint blockSize, GLint level)
+{
+ // Avoid C++ undefined behavior.
+ constexpr int maxValidShifts = 31;
+ if (level > maxValidShifts)
+ return false;
+ return ((size << level) % blockSize) == 0;
+}
+
bool ValidCompressedImageSize(const Context *context,
GLenum internalFormat,
GLint level,
@@ -1005,11 +1014,27 @@ bool ValidCompressedImageSize(const Context *context,
if (CompressedTextureFormatRequiresExactSize(internalFormat))
{
- if (!ValidCompressedDimension(width, formatInfo.compressedBlockWidth, level) ||
- !ValidCompressedDimension(height, formatInfo.compressedBlockHeight, level) ||
- !ValidCompressedDimension(depth, formatInfo.compressedBlockDepth, level))
+ // In WebGL compatibility mode, enforce that the base level implied
+ // by the compressed texture's mip level would conform to the block
+ // size. This is more strict than the non-WebGL check.
+ if (context->getExtensions().webglCompatibility)
{
- return false;
+ if (!ValidCompressedBaseLevelForWebGL(width, formatInfo.compressedBlockWidth, level) ||
+ !ValidCompressedBaseLevelForWebGL(height, formatInfo.compressedBlockHeight,
+ level) ||
+ !ValidCompressedBaseLevelForWebGL(depth, formatInfo.compressedBlockDepth, level))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (!ValidCompressedDimension(width, formatInfo.compressedBlockWidth, level) ||
+ !ValidCompressedDimension(height, formatInfo.compressedBlockHeight, level) ||
+ !ValidCompressedDimension(depth, formatInfo.compressedBlockDepth, level))
+ {
+ return false;
+ }
}
}
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index bfa8f3066fa418c87477dd553e66a34b79974455..89eb4d639a3853636524ad112a24f15d46fa1119 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -296,6 +296,16 @@ void main()
GLsizei blockSize,
const std::string &extName,
bool subImageAllowed);
+
+ GLint expectedByteLength(GLenum format, GLsizei width, GLsizei height);
+ void testCompressedTexLevelDimension(GLenum format,
+ GLint level,
+ GLsizei width,
+ GLsizei height,
+ GLsizei expectedByteLength,
+ GLenum expectedError,
+ const char *explanation);
+ void testCompressedTexImage(GLenum format);
};
class WebGL2CompatibilityTest : public WebGLCompatibilityTest
@@ -3056,6 +3066,84 @@ TEST_P(WebGLCompatibilityTest, CompressedTextureS3TC)
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
}
+// Test WebGL-specific constraints on sizes of S3TC textures' mipmap levels.
+TEST_P(WebGLCompatibilityTest, CompressedTexImageS3TC)
+{
+ const char *extensions[] = {
+ "GL_EXT_texture_compression_dxt1",
+ "GL_ANGLE_texture_compression_dxt3",
+ "GL_ANGLE_texture_compression_dxt5",
+ };
+
+ for (const char *extension : extensions)
+ {
+ if (IsGLExtensionRequestable(extension))
+ {
+ glRequestExtensionANGLE(extension);
+ }
+
+ ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(extension));
+ }
+
+ // Ported from WebGL conformance suite:
+ // sdk/tests/conformance/extensions/s3tc-and-srgb.html
+ constexpr GLenum formats[] = {
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
+ };
+
+ for (GLenum format : formats)
+ {
+ testCompressedTexImage(format);
+ }
+}
+
+// Test WebGL-specific constraints on sizes of RGTC textures' mipmap levels.
+TEST_P(WebGLCompatibilityTest, CompressedTexImageRGTC)
+{
+ if (IsGLExtensionRequestable("GL_EXT_texture_compression_rgtc"))
+ {
+ glRequestExtensionANGLE("GL_EXT_texture_compression_rgtc");
+ }
+
+ ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_rgtc"));
+
+ // Ported from WebGL conformance suite:
+ // sdk/tests/conformance/extensions/ext-texture-compression-rgtc.html
+ constexpr GLenum formats[] = {GL_COMPRESSED_RED_RGTC1_EXT, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT,
+ GL_COMPRESSED_RED_GREEN_RGTC2_EXT,
+ GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT};
+
+ for (GLenum format : formats)
+ {
+ testCompressedTexImage(format);
+ }
+}
+
+// Test WebGL-specific constraints on sizes of BPTC textures' mipmap levels.
+TEST_P(WebGLCompatibilityTest, CompressedTexImageBPTC)
+{
+ if (IsGLExtensionRequestable("GL_EXT_texture_compression_bptc"))
+ {
+ glRequestExtensionANGLE("GL_EXT_texture_compression_bptc");
+ }
+
+ ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
+
+ // Ported from WebGL conformance suite:
+ // sdk/tests/conformance/extensions/ext-texture-compression-bptc.html
+ constexpr GLenum formats[] = {
+ GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT,
+ GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT};
+
+ for (GLenum format : formats)
+ {
+ testCompressedTexImage(format);
+ }
+}
+
TEST_P(WebGLCompatibilityTest, L32FTextures)
{
constexpr float textureData[] = {15.1f, 0.0f, 0.0f, 0.0f};
@@ -4887,6 +4975,119 @@ void WebGLCompatibilityTest::validateCompressedTexImageExtensionFormat(GLenum fo
}
}
+GLint WebGLCompatibilityTest::expectedByteLength(GLenum format, GLsizei width, GLsizei height)
+{
+ switch (format)
+ {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RED_RGTC1_EXT:
+ case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
+ return ((width + 3) / 4) * ((height + 3) / 4) * 8;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
+ case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
+ case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
+ case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
+ return ((width + 3) / 4) * ((height + 3) / 4) * 16;
+ }
+
+ UNREACHABLE();
+ return 0;
+}
+
+void WebGLCompatibilityTest::testCompressedTexLevelDimension(GLenum format,
+ GLint level,
+ GLsizei width,
+ GLsizei height,
+ GLsizei expectedByteLength,
+ GLenum expectedError,
+ const char *explanation)
+{
+ std::vector<uint8_t> tempVector(expectedByteLength, 0);
+
+ EXPECT_GL_NO_ERROR();
+
+ GLTexture sourceTexture;
+ glBindTexture(GL_TEXTURE_2D, sourceTexture);
+ glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height, 0, expectedByteLength,
+ tempVector.data());
+ if (expectedError == 0)
+ {
+ EXPECT_GL_NO_ERROR() << explanation;
+ }
+ else
+ {
+ EXPECT_GL_ERROR(expectedError) << explanation;
+ }
+}
+
+void WebGLCompatibilityTest::testCompressedTexImage(GLenum format)
+{
+ struct TestCase
+ {
+ GLint level;
+ GLsizei width;
+ GLsizei height;
+ GLenum expectedError;
+ const char *explanation;
+ };
+
+ constexpr TestCase testCases[] = {
+ {0, 4, 3, GL_INVALID_OPERATION, "level is 0, height is not a multiple of 4"},
+ {0, 3, 4, GL_INVALID_OPERATION, "level is 0, width is not a multiple of 4"},
+ {0, 2, 2, GL_INVALID_OPERATION, "level is 0, width is not a multiple of 4"},
+ {0, 4, 4, GL_NO_ERROR, "is valid"},
+ {1, 1, 1, GL_INVALID_OPERATION, "implied base mip 2x2 is invalid"},
+ {1, 1, 2, GL_INVALID_OPERATION, "implied base mip 2x4 is invalid"},
+ {1, 2, 1, GL_INVALID_OPERATION, "implied base mip 4x2 is invalid"},
+ {1, 2, 2, GL_NO_ERROR, "implied base mip 4x4 is valid"},
+ };
+
+ constexpr TestCase webgl2TestCases[] = {
+ {0, 0, 0, GL_NO_ERROR, "0: 0x0 is valid"},
+ {0, 1, 1, GL_INVALID_OPERATION, "0: 1x1 is invalid"},
+ {0, 2, 2, GL_INVALID_OPERATION, "0: 2x2 is invalid"},
+ {0, 3, 3, GL_INVALID_OPERATION, "0: 3x3 is invalid"},
+ {0, 10, 10, GL_INVALID_OPERATION, "0: 10x10 is invalid"},
+ {0, 11, 11, GL_INVALID_OPERATION, "0: 11x11 is invalid"},
+ {0, 11, 12, GL_INVALID_OPERATION, "0: 11x12 is invalid"},
+ {0, 12, 11, GL_INVALID_OPERATION, "0: 12x11 is invalid"},
+ {0, 12, 12, GL_NO_ERROR, "0: 12x12 is valid"},
+ {1, 0, 0, GL_NO_ERROR, "1: 0x0 is valid"},
+ {1, 3, 3, GL_INVALID_OPERATION, "1: 3x3 is invalid"},
+ {1, 5, 5, GL_INVALID_OPERATION, "1: 5x5 is invalid"},
+ {1, 5, 6, GL_INVALID_OPERATION, "1: 5x6 is invalid"},
+ {1, 6, 5, GL_INVALID_OPERATION, "1: 6x5 is invalid"},
+ {1, 6, 6, GL_NO_ERROR, "1: 6x6 is valid"},
+ {2, 0, 0, GL_NO_ERROR, "2: 0x0 is valid"},
+ {2, 3, 3, GL_NO_ERROR, "2: 3x3 is valid"},
+ {3, 1, 3, GL_NO_ERROR, "3: 1x3 is valid"},
+ {3, 1, 1, GL_NO_ERROR, "3: 1x1 is valid"},
+ {2, 1, 3, GL_NO_ERROR, "implied base mip 4x12 is valid"},
+ };
+
+ for (const TestCase &test : testCases)
+ {
+ testCompressedTexLevelDimension(format, test.level, test.width, test.height,
+ expectedByteLength(format, test.width, test.height),
+ test.expectedError, test.explanation);
+ }
+
+ if (getClientMajorVersion() >= 3)
+ {
+ for (const TestCase &test : webgl2TestCases)
+ {
+ testCompressedTexLevelDimension(format, test.level, test.width, test.height,
+ expectedByteLength(format, test.width, test.height),
+ test.expectedError, test.explanation);
+ }
+ }
+}
+
// Test enabling GL_EXT_texture_compression_dxt1 for GL_COMPRESSED_RGB_S3TC_DXT1_EXT
TEST_P(WebGLCompatibilityTest, EnableCompressedTextureExtensionDXT1RGB)
{

View File

@@ -0,0 +1,112 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexis Hetu <sugoi@google.com>
Date: Wed, 15 Sep 2021 13:40:28 -0400
Subject: Fix integer overflow in BlockLayoutEncoder
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
BlockLayoutEncoder::mCurrentOffset's computation had the
possibility of causing integer overflows in multiple places,
so this CL adds CheckedNumeric variables in a number of
these occurrences in order to prevent integer overflows and
causing issues.
The issue in this case was an integer overflow causing the
code in ValidateTypeSizeLimitations.cpp to use an invalid
result from "layoutEncoder.getCurrentOffset()", which ended
up compiling a shader which would later cause an OOM error.
Bug: chromium:1248665
Change-Id: I688d669f21c6dc2957e43bdf91f8f8f08180a6f7
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3163356
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Alexis Hétu <sugoi@chromium.org>
(cherry picked from commit 158ef351fc8b827c201e056a8ddba50fd4235671)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3194392
diff --git a/src/compiler/translator/blocklayout.cpp b/src/compiler/translator/blocklayout.cpp
index 65a729e05d9f9abca5ca1ca72466f68751ed602b..f523da7de61a156212ac578481b679fd626b5046 100644
--- a/src/compiler/translator/blocklayout.cpp
+++ b/src/compiler/translator/blocklayout.cpp
@@ -198,6 +198,13 @@ BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type,
return memberInfo;
}
+size_t BlockLayoutEncoder::getCurrentOffset() const
+{
+ angle::base::CheckedNumeric<size_t> checkedOffset(mCurrentOffset);
+ checkedOffset *= kBytesPerComponent;
+ return checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+}
+
size_t BlockLayoutEncoder::getShaderVariableSize(const ShaderVariable &structVar, bool isRowMajor)
{
size_t currentOffset = mCurrentOffset;
@@ -225,7 +232,13 @@ size_t BlockLayoutEncoder::GetBlockRegisterElement(const BlockMemberInfo &info)
void BlockLayoutEncoder::align(size_t baseAlignment)
{
- mCurrentOffset = rx::roundUp<size_t>(mCurrentOffset, baseAlignment);
+ angle::base::CheckedNumeric<size_t> checkedOffset(mCurrentOffset);
+ checkedOffset += baseAlignment;
+ checkedOffset -= 1;
+ angle::base::CheckedNumeric<size_t> checkedAlignmentOffset = checkedOffset;
+ checkedAlignmentOffset %= baseAlignment;
+ checkedOffset -= checkedAlignmentOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
}
// StubBlockEncoder implementation.
@@ -288,7 +301,7 @@ void Std140BlockEncoder::getBlockLayoutInfo(GLenum type,
baseAlignment = ComponentAlignment(numComponents);
}
- mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
+ align(baseAlignment);
*matrixStrideOut = matrixStride;
*arrayStrideOut = arrayStride;
@@ -302,16 +315,23 @@ void Std140BlockEncoder::advanceOffset(GLenum type,
{
if (!arraySizes.empty())
{
- mCurrentOffset += arrayStride * gl::ArraySizeProduct(arraySizes);
+ angle::base::CheckedNumeric<size_t> checkedOffset(arrayStride);
+ checkedOffset *= gl::ArraySizeProduct(arraySizes);
+ checkedOffset += mCurrentOffset;
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
}
else if (gl::IsMatrixType(type))
{
- const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
- mCurrentOffset += matrixStride * numRegisters;
+ angle::base::CheckedNumeric<size_t> checkedOffset(matrixStride);
+ checkedOffset *= gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ checkedOffset += mCurrentOffset;
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
}
else
{
- mCurrentOffset += gl::VariableComponentCount(type);
+ angle::base::CheckedNumeric<size_t> checkedOffset(mCurrentOffset);
+ checkedOffset += gl::VariableComponentCount(type);
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
}
}
diff --git a/src/compiler/translator/blocklayout.h b/src/compiler/translator/blocklayout.h
index 27b2247cb5f14c77577d46c9deec7308bcf1e73c..5004a5c206a6148faba29983044207046de1dcd4 100644
--- a/src/compiler/translator/blocklayout.h
+++ b/src/compiler/translator/blocklayout.h
@@ -80,7 +80,7 @@ class BlockLayoutEncoder
const std::vector<unsigned int> &arraySizes,
bool isRowMajorMatrix);
- size_t getCurrentOffset() const { return mCurrentOffset * kBytesPerComponent; }
+ size_t getCurrentOffset() const;
size_t getShaderVariableSize(const ShaderVariable &structVar, bool isRowMajor);
// Called when entering/exiting a structure variable.

View File

@@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Fri, 3 Sep 2021 09:34:10 -0400
Subject: WebGL: Make unsuccessful links fail subsequent draw calls.
This protects against incomplete state updates during a failed
link call that can interfere with draw calls.
Bug: angleproject:6358
Bug: chromium:1241123
Change-Id: Ie892654c3a58c69d6e35ba3c41758ab6269d8193
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3140496
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Yuly Novikov <ynovikov@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3152556
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 4ed0ea4f47c89090d06f706199d32bb0f5b745b9..40574e58d20363710a1312ddaa39ba2eb685b6b8 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -3881,6 +3881,12 @@ const char *ValidateDrawStates(const Context *context)
{
return kVertexBufferBoundForTransformFeedback;
}
+
+ // Validate that we are rendering with a linked program.
+ if (!program->isLinked())
+ {
+ return kProgramNotLinked;
+ }
}
}

View File

@@ -144,3 +144,33 @@ cherry-pick-3feda0244490.patch
cherry-pick-cd98d7c0dae9.patch
replace_first_of_two_waitableevents_in_creditcardaccessmanager.patch
cherry-pick-ac9dc1235e28.patch
cherry-pick-4ce2abc17078.patch
cherry-pick-e2123a8e0943.patch
cherry-pick-1227933.patch
cherry-pick-1233564.patch
cherry-pick-d727013bb543.patch
cherry-pick-1231134.patch
merge_m92_speculative_fix_for_crash_in.patch
cherry-pick-6048fcd52f42.patch
m93_indexeddb_add_browser-side_checks_for_committing_transactions.patch
m93_indexeddb_don_t_reportbadmessage_for_commit_calls.patch
content-visibility_force_range_base_extent_when_computing_visual.patch
cherry-pick-6215793f008f.patch
cherry-pick-8623d711677d.patch
contentindex_add_origin_checks_to_mojo_methods.patch
skip_webgl_conformance_programs_program-test_html_on_all_platforms.patch
cherry-pick-ddc4cf156505.patch
content-visibility_add_a_clipper_fix_for_content-visibility.patch
kill_a_renderer_if_it_provides_an_unexpected_frameownerelementtype.patch
cherry-pick-efd8e01ac1a6.patch
cherry-pick-e8a5cefd1aac.patch
m90-lts_fsa_fix_race_condition_in_manager.patch
check_direction_of_rtcencodedframes.patch
cherry-pick-6a8a2098f9fa.patch
cherry-pick-3a5bafa35def.patch
mas_gate_private_enterprise_APIs
speculative_fix_for_eye_dropper_getcolor_crash.patch
cherry-pick-0894af410c4e.patch
move_networkstateobserver_from_document_to_window.patch
use_zero_when_the_starting_value_of_exponential_ramp_is_zero.patch
cherry-pick-91dd4f79ab5b.patch

View File

@@ -0,0 +1,174 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tony Herre <toprice@chromium.org>
Date: Fri, 1 Oct 2021 19:18:45 +0000
Subject: Check direction of RTCEncodedFrames
Add a check to RTCEncodedVideoUnderlyingSink of the direction of the
underlying webrtc frame, to make sure a web app doesn't take a received
encoded frame and pass it into a sender insertable stream, which is as
yet unsupported in WebRTC.
Bug: 1247260
Change-Id: I9ed5bd8b2bd5e5ee461f3b553f8a91f6cc2e9ed7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3190473
Commit-Queue: Tony Herre <toprice@chromium.org>
Reviewed-by: Harald Alvestrand <hta@chromium.org>
Cr-Commit-Position: refs/heads/main@{#927323}
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc
index c390ab72418194cb10c3b0bc5a83b95de8dd19f6..775b837fee46836fd292b17ac8d80e4c83bd08a8 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc
@@ -14,8 +14,10 @@ namespace blink {
RTCEncodedVideoUnderlyingSink::RTCEncodedVideoUnderlyingSink(
ScriptState* script_state,
- TransformerCallback transformer_callback)
- : transformer_callback_(std::move(transformer_callback)) {
+ TransformerCallback transformer_callback,
+ webrtc::TransformableFrameInterface::Direction expected_direction)
+ : transformer_callback_(std::move(transformer_callback)),
+ expected_direction_(expected_direction) {
DCHECK(transformer_callback_);
}
@@ -53,6 +55,12 @@ ScriptPromise RTCEncodedVideoUnderlyingSink::write(
return ScriptPromise();
}
+ if (webrtc_frame->GetDirection() != expected_direction_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+ "Invalid frame");
+ return ScriptPromise();
+ }
+
RTCEncodedVideoStreamTransformer* transformer = transformer_callback_.Run();
if (!transformer) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h
index dd1cad227eb7947dd0bf2ec7ba217956cb7a8787..8591fcc6eb1c78d0e107e4f097d3133d111ab959 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/streams/underlying_sink_base.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
namespace blink {
@@ -18,7 +19,9 @@ class MODULES_EXPORT RTCEncodedVideoUnderlyingSink final
public:
using TransformerCallback =
base::RepeatingCallback<RTCEncodedVideoStreamTransformer*()>;
- RTCEncodedVideoUnderlyingSink(ScriptState*, TransformerCallback);
+ RTCEncodedVideoUnderlyingSink(ScriptState*,
+ TransformerCallback,
+ webrtc::TransformableFrameInterface::Direction);
// UnderlyingSinkBase
ScriptPromise start(ScriptState*,
@@ -37,6 +40,7 @@ class MODULES_EXPORT RTCEncodedVideoUnderlyingSink final
private:
TransformerCallback transformer_callback_;
+ webrtc::TransformableFrameInterface::Direction expected_direction_;
};
} // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc
index 614d16e9a43e493c35b82b838f46c4d7c01b83ac..465be4cd1406fdbfe777e68b538ab59bef16a0cd 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc
@@ -74,11 +74,15 @@ class RTCEncodedVideoUnderlyingSinkTest : public testing::Test {
EXPECT_FALSE(transformer_.HasTransformedFrameSinkCallback(kSSRC));
}
- RTCEncodedVideoUnderlyingSink* CreateSink(ScriptState* script_state) {
+ RTCEncodedVideoUnderlyingSink* CreateSink(
+ ScriptState* script_state,
+ webrtc::TransformableFrameInterface::Direction expected_direction =
+ webrtc::TransformableFrameInterface::Direction::kSender) {
return MakeGarbageCollected<RTCEncodedVideoUnderlyingSink>(
script_state,
WTF::BindRepeating(&RTCEncodedVideoUnderlyingSinkTest::GetTransformer,
- WTF::Unretained(this)));
+ WTF::Unretained(this)),
+ expected_direction);
}
RTCEncodedVideoUnderlyingSink* CreateNullCallbackSink(
@@ -86,15 +90,21 @@ class RTCEncodedVideoUnderlyingSinkTest : public testing::Test {
return MakeGarbageCollected<RTCEncodedVideoUnderlyingSink>(
script_state,
WTF::BindRepeating(
- []() -> RTCEncodedVideoStreamTransformer* { return nullptr; }));
+ []() -> RTCEncodedVideoStreamTransformer* { return nullptr; }),
+ webrtc::TransformableFrameInterface::Direction::kSender);
}
RTCEncodedVideoStreamTransformer* GetTransformer() { return &transformer_; }
- ScriptValue CreateEncodedVideoFrameChunk(ScriptState* script_state) {
+ ScriptValue CreateEncodedVideoFrameChunk(
+ ScriptState* script_state,
+ webrtc::TransformableFrameInterface::Direction direction =
+ webrtc::TransformableFrameInterface::Direction::kSender) {
auto mock_frame =
std::make_unique<NiceMock<webrtc::MockTransformableVideoFrame>>();
+
ON_CALL(*mock_frame.get(), GetSsrc).WillByDefault(Return(kSSRC));
+ ON_CALL(*mock_frame.get(), GetDirection).WillByDefault(Return(direction));
RTCEncodedVideoFrame* frame =
MakeGarbageCollected<RTCEncodedVideoFrame>(std::move(mock_frame));
return ScriptValue(script_state->GetIsolate(),
@@ -175,4 +185,21 @@ TEST_F(RTCEncodedVideoUnderlyingSinkTest, WriteToNullCallbackSinkFails) {
DOMExceptionCode::kInvalidStateError));
}
+TEST_F(RTCEncodedVideoUnderlyingSinkTest, WriteInvalidDirectionFails) {
+ V8TestingScope v8_scope;
+ ScriptState* script_state = v8_scope.GetScriptState();
+ auto* sink = CreateSink(
+ script_state, webrtc::TransformableFrameInterface::Direction::kSender);
+
+ // Write an encoded chunk with direction set to Receiver should fail as it
+ // doesn't match the expected direction of our sink.
+ DummyExceptionStateForTesting dummy_exception_state;
+ sink->write(script_state,
+ CreateEncodedVideoFrameChunk(
+ script_state,
+ webrtc::TransformableFrameInterface::Direction::kReceiver),
+ nullptr, dummy_exception_state);
+ EXPECT_TRUE(dummy_exception_state.HadException());
+}
+
} // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
index 173e1965cbc18335c267731ec84e48af6f7c8c9b..72ee6eddfbefc7d745f4ba4b623a3ff1f9fa2baf 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -507,7 +507,8 @@ void RTCRtpReceiver::InitializeEncodedVideoStreams(ScriptState* script_state) {
->GetEncodedVideoStreamTransformer()
: nullptr;
},
- WrapWeakPersistent(this)));
+ WrapWeakPersistent(this)),
+ webrtc::TransformableFrameInterface::Direction::kReceiver);
// The high water mark for the stream is set to 1 so that the stream seems
// ready to write, but without queuing frames.
WritableStream* writable_stream =
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
index c9a9b8f7692cfa37e591789a43169a58c69a0658..c54b671bfda084bc3d1f56b342a344298877435d 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
@@ -907,7 +907,8 @@ void RTCRtpSender::InitializeEncodedVideoStreams(ScriptState* script_state) {
->GetEncodedVideoStreamTransformer()
: nullptr;
},
- WrapWeakPersistent(this)));
+ WrapWeakPersistent(this)),
+ webrtc::TransformableFrameInterface::Direction::kSender);
// The high water mark for the stream is set to 1 so that the stream is
// ready to write, but without queuing frames.
WritableStream* writable_stream =

View File

@@ -0,0 +1,385 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Min Qin <qinmin@chromium.org>
Date: Tue, 31 Aug 2021 23:03:03 +0000
Subject: Quarantine save package items that's downloaded from network
Currently quarantine is not performed for save page downloads. This CL
fixes the issue.
BUG=1243020, 811161
Change-Id: I85d03cc324b0b90a45bd8b3429e4e9eec1aaf857
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3126709
Reviewed-by: Xing Liu <xingliu@chromium.org>
Commit-Queue: Min Qin <qinmin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#917013}
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc
index a5bcd21e190452ca9b3a48c04ee2e78d4737744b..ea8bfaab4d032020988039b3d0d1cc04d7804c25 100644
--- a/chrome/browser/download/save_page_browsertest.cc
+++ b/chrome/browser/download/save_page_browsertest.cc
@@ -49,6 +49,7 @@
#include "components/prefs/pref_member.h"
#include "components/prefs/pref_service.h"
#include "components/security_state/core/security_state.h"
+#include "components/services/quarantine/test_support.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
@@ -433,6 +434,10 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveFileURL) {
EXPECT_TRUE(base::PathExists(full_file_name));
EXPECT_FALSE(base::PathExists(dir));
EXPECT_TRUE(base::ContentsEqual(GetTestDirFile("text.txt"), full_file_name));
+#if defined(OS_WIN)
+ // Local file URL will not be quarantined.
+ EXPECT_FALSE(quarantine::IsFileQuarantined(full_file_name, GURL(), GURL()));
+#endif
}
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest,
@@ -936,6 +941,25 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveUnauthorizedResource) {
EXPECT_FALSE(base::PathExists(dir.AppendASCII("should-not-save.jpg")));
}
+#if defined(OS_WIN)
+// Save a file and confirm that the file is correctly quarantined.
+IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveURLQuarantine) {
+ GURL url = embedded_test_server()->GetURL("/save_page/text.txt");
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ base::FilePath full_file_name, dir;
+ SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_ONLY_HTML, "test", 1, &dir,
+ &full_file_name);
+ ASSERT_FALSE(HasFailure());
+
+ base::ScopedAllowBlockingForTesting allow_blocking;
+ EXPECT_TRUE(base::PathExists(full_file_name));
+ EXPECT_FALSE(base::PathExists(dir));
+ EXPECT_TRUE(base::ContentsEqual(GetTestDirFile("text.txt"), full_file_name));
+ EXPECT_TRUE(quarantine::IsFileQuarantined(full_file_name, url, GURL()));
+}
+#endif
+
// Test suite that allows testing --site-per-process against cross-site frames.
// See http://dev.chromium.org/developers/design-documents/site-isolation.
class SavePageSitePerProcessBrowserTest : public SavePageBrowserTest {
diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h
index 69fcf9abbe975ea35a2869f3601958e88aeb5951..0deb3b7c7781a37b47a5a04169ecd2e0ceaed4c8 100644
--- a/content/browser/download/download_manager_impl.h
+++ b/content/browser/download/download_manager_impl.h
@@ -170,6 +170,11 @@ class CONTENT_EXPORT DownloadManagerImpl
int frame_tree_node_id,
bool from_download_cross_origin_redirect);
+ // DownloadItemImplDelegate overrides.
+ download::QuarantineConnectionCallback GetQuarantineConnectionCallback()
+ override;
+ std::string GetApplicationClientIdForFileScanning() const override;
+
private:
using DownloadSet = std::set<download::DownloadItem*>;
using DownloadGuidMap =
@@ -237,7 +242,6 @@ class CONTENT_EXPORT DownloadManagerImpl
bool ShouldOpenDownload(download::DownloadItemImpl* item,
ShouldOpenDownloadCallback callback) override;
void CheckForFileRemoval(download::DownloadItemImpl* download_item) override;
- std::string GetApplicationClientIdForFileScanning() const override;
void ResumeInterruptedDownload(
std::unique_ptr<download::DownloadUrlParameters> params,
const GURL& site_url) override;
@@ -249,8 +253,6 @@ class CONTENT_EXPORT DownloadManagerImpl
void ReportBytesWasted(download::DownloadItemImpl* download) override;
void BindWakeLockProvider(
mojo::PendingReceiver<device::mojom::WakeLockProvider> receiver) override;
- download::QuarantineConnectionCallback GetQuarantineConnectionCallback()
- override;
std::unique_ptr<download::DownloadItemRenameHandler>
GetRenameHandlerForDownload(
download::DownloadItemImpl* download_item) override;
diff --git a/content/browser/download/save_file.cc b/content/browser/download/save_file.cc
index 72331e60fca942820b39580cee5a1890340401ae..110f66250e9608426b26333203e93045f17e9f99 100644
--- a/content/browser/download/save_file.cc
+++ b/content/browser/download/save_file.cc
@@ -63,10 +63,15 @@ void SaveFile::Finish() {
file_.Finish();
}
-void SaveFile::AnnotateWithSourceInformation() {
- // TODO(gbillock): If this method is called, it should set the
- // file_.SetClientGuid() method first.
- NOTREACHED();
+void SaveFile::AnnotateWithSourceInformation(
+ const std::string& client_guid,
+ const GURL& source_url,
+ const GURL& referrer_url,
+ mojo::PendingRemote<quarantine::mojom::Quarantine> remote_quarantine,
+ download::BaseFile::OnAnnotationDoneCallback on_annotation_done_callback) {
+ file_.AnnotateWithSourceInformation(client_guid, source_url, referrer_url,
+ std::move(remote_quarantine),
+ std::move(on_annotation_done_callback));
}
base::FilePath SaveFile::FullPath() const {
diff --git a/content/browser/download/save_file.h b/content/browser/download/save_file.h
index 688574b07f9374e75a25caaaa13bdb405aea7b0d..1893a0031f4c6642c6c806577da2246e55e49091 100644
--- a/content/browser/download/save_file.h
+++ b/content/browser/download/save_file.h
@@ -34,7 +34,12 @@ class SaveFile {
void Detach();
void Cancel();
void Finish();
- void AnnotateWithSourceInformation();
+ void AnnotateWithSourceInformation(
+ const std::string& client_guid,
+ const GURL& source_url,
+ const GURL& referrer_url,
+ mojo::PendingRemote<quarantine::mojom::Quarantine> remote_quarantine,
+ download::BaseFile::OnAnnotationDoneCallback on_annotation_done_callback);
base::FilePath FullPath() const;
bool InProgress() const;
int64_t BytesSoFar() const;
diff --git a/content/browser/download/save_file_manager.cc b/content/browser/download/save_file_manager.cc
index b140be654b10f6d9c51f7531d5868e722665ae3e..b404bf930f227cc03375c81d5d267bc93929a59f 100644
--- a/content/browser/download/save_file_manager.cc
+++ b/content/browser/download/save_file_manager.cc
@@ -50,6 +50,7 @@ static SaveFileManager* g_save_file_manager = nullptr;
class SaveFileManager::SimpleURLLoaderHelper
: public network::SimpleURLLoaderStreamConsumer {
public:
+ using URLLoaderCompleteCallback = base::OnceCallback<void(bool success)>;
static std::unique_ptr<SimpleURLLoaderHelper> CreateAndStartDownload(
std::unique_ptr<network::ResourceRequest> resource_request,
SaveItemId save_item_id,
@@ -58,11 +59,12 @@ class SaveFileManager::SimpleURLLoaderHelper
int render_frame_routing_id,
const net::NetworkTrafficAnnotationTag& annotation_tag,
network::mojom::URLLoaderFactory* url_loader_factory,
- SaveFileManager* save_file_manager) {
+ SaveFileManager* save_file_manager,
+ URLLoaderCompleteCallback on_complete_cb) {
return std::unique_ptr<SimpleURLLoaderHelper>(new SimpleURLLoaderHelper(
std::move(resource_request), save_item_id, save_package_id,
render_process_id, render_frame_routing_id, annotation_tag,
- url_loader_factory, save_file_manager));
+ url_loader_factory, save_file_manager, std::move(on_complete_cb)));
}
~SimpleURLLoaderHelper() override = default;
@@ -76,10 +78,12 @@ class SaveFileManager::SimpleURLLoaderHelper
int render_frame_routing_id,
const net::NetworkTrafficAnnotationTag& annotation_tag,
network::mojom::URLLoaderFactory* url_loader_factory,
- SaveFileManager* save_file_manager)
+ SaveFileManager* save_file_manager,
+ URLLoaderCompleteCallback on_complete_cb)
: save_file_manager_(save_file_manager),
save_item_id_(save_item_id),
- save_package_id_(save_package_id) {
+ save_package_id_(save_package_id),
+ on_complete_cb_(std::move(on_complete_cb)) {
GURL url = resource_request->url;
url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
annotation_tag);
@@ -124,9 +128,7 @@ class SaveFileManager::SimpleURLLoaderHelper
void OnComplete(bool success) override {
download::GetDownloadTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&SaveFileManager::SaveFinished, save_file_manager_,
- save_item_id_, save_package_id_, success));
+ FROM_HERE, base::BindOnce(std::move(on_complete_cb_), success));
}
void OnRetry(base::OnceClosure start_retry) override {
@@ -138,6 +140,7 @@ class SaveFileManager::SimpleURLLoaderHelper
SaveItemId save_item_id_;
SavePackageId save_package_id_;
std::unique_ptr<network::SimpleURLLoader> url_loader_;
+ URLLoaderCompleteCallback on_complete_cb_;
DISALLOW_COPY_AND_ASSIGN(SimpleURLLoaderHelper);
};
@@ -188,17 +191,20 @@ SavePackage* SaveFileManager::LookupPackage(SaveItemId save_item_id) {
}
// Call from SavePackage for starting a saving job
-void SaveFileManager::SaveURL(SaveItemId save_item_id,
- const GURL& url,
- const Referrer& referrer,
- int render_process_host_id,
- int render_view_routing_id,
- int render_frame_routing_id,
- SaveFileCreateInfo::SaveFileSource save_source,
- const base::FilePath& file_full_path,
- BrowserContext* context,
- StoragePartition* storage_partition,
- SavePackage* save_package) {
+void SaveFileManager::SaveURL(
+ SaveItemId save_item_id,
+ const GURL& url,
+ const Referrer& referrer,
+ int render_process_host_id,
+ int render_view_routing_id,
+ int render_frame_routing_id,
+ SaveFileCreateInfo::SaveFileSource save_source,
+ const base::FilePath& file_full_path,
+ BrowserContext* context,
+ StoragePartition* storage_partition,
+ SavePackage* save_package,
+ const std::string& client_guid,
+ mojo::PendingRemote<quarantine::mojom::Quarantine> remote_quarantine) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Insert started saving job to tracking list.
@@ -284,11 +290,18 @@ void SaveFileManager::SaveURL(SaveItemId save_item_id,
factory = storage_partition->GetURLLoaderFactoryForBrowserProcess().get();
}
+ base::OnceCallback<void(bool /*success*/)> save_finished_cb =
+ base::BindOnce(&SaveFileManager::OnURLLoaderComplete, this,
+ save_item_id, save_package->id(),
+ context->IsOffTheRecord() ? GURL() : url,
+ context->IsOffTheRecord() ? GURL() : referrer.url,
+ client_guid, std::move(remote_quarantine));
+
url_loader_helpers_[save_item_id] =
SimpleURLLoaderHelper::CreateAndStartDownload(
std::move(request), save_item_id, save_package->id(),
render_process_host_id, render_frame_routing_id, traffic_annotation,
- factory, this);
+ factory, this, std::move(save_finished_cb));
} else {
// We manually start the save job.
auto info = std::make_unique<SaveFileCreateInfo>(
@@ -343,6 +356,36 @@ void SaveFileManager::SendCancelRequest(SaveItemId save_item_id) {
base::BindOnce(&SaveFileManager::CancelSave, this, save_item_id));
}
+void SaveFileManager::OnURLLoaderComplete(
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
+ const GURL& url,
+ const GURL& referrer_url,
+ const std::string& client_guid,
+ mojo::PendingRemote<quarantine::mojom::Quarantine> remote_quarantine,
+ bool is_success) {
+ DCHECK(download::GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
+ SaveFile* save_file = LookupSaveFile(save_item_id);
+ if (!is_success || !save_file) {
+ SaveFinished(save_item_id, save_package_id, is_success);
+ return;
+ }
+
+ save_file->AnnotateWithSourceInformation(
+ client_guid, url, referrer_url, std::move(remote_quarantine),
+ base::BindOnce(&SaveFileManager::OnQuarantineComplete, this, save_item_id,
+ save_package_id));
+}
+
+void SaveFileManager::OnQuarantineComplete(
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
+ download::DownloadInterruptReason result) {
+ DCHECK(download::GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
+ SaveFinished(save_item_id, save_package_id,
+ result == download::DOWNLOAD_INTERRUPT_REASON_NONE);
+}
+
// Notifications sent from the IO thread and run on the file thread:
// The IO thread created |info|, but the file thread (this method) uses it
diff --git a/content/browser/download/save_file_manager.h b/content/browser/download/save_file_manager.h
index 51eb63a9b189be388e4dff48e04644956e968345..0d4290b273ba4f150bc9a49418e54b709a601581 100644
--- a/content/browser/download/save_file_manager.h
+++ b/content/browser/download/save_file_manager.h
@@ -61,6 +61,8 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "components/download/public/common/download_interrupt_reasons.h"
+#include "components/services/quarantine/quarantine.h"
#include "content/browser/download/save_types.h"
#include "content/common/content_export.h"
@@ -90,17 +92,20 @@ class CONTENT_EXPORT SaveFileManager
// Saves the specified URL |url|. |save_package| must not be deleted before
// the call to RemoveSaveFile. Should be called on the UI thread,
- void SaveURL(SaveItemId save_item_id,
- const GURL& url,
- const Referrer& referrer,
- int render_process_host_id,
- int render_view_routing_id,
- int render_frame_routing_id,
- SaveFileCreateInfo::SaveFileSource save_source,
- const base::FilePath& file_full_path,
- BrowserContext* context,
- StoragePartition* storage_partition,
- SavePackage* save_package);
+ void SaveURL(
+ SaveItemId save_item_id,
+ const GURL& url,
+ const Referrer& referrer,
+ int render_process_host_id,
+ int render_view_routing_id,
+ int render_frame_routing_id,
+ SaveFileCreateInfo::SaveFileSource save_source,
+ const base::FilePath& file_full_path,
+ BrowserContext* context,
+ StoragePartition* storage_partition,
+ SavePackage* save_package,
+ const std::string& client_guid,
+ mojo::PendingRemote<quarantine::mojom::Quarantine> remote_quarantine);
// Notifications sent from the IO thread and run on the file thread:
void StartSave(std::unique_ptr<SaveFileCreateInfo> info);
@@ -159,6 +164,21 @@ class CONTENT_EXPORT SaveFileManager
// Help function for sending notification of canceling specific request.
void SendCancelRequest(SaveItemId save_item_id);
+ // Called on the file thread when the URLLoader completes saving a SaveItem.
+ void OnURLLoaderComplete(
+ SaveItemId save_item_id,
+ SavePackageId save_package_id,
+ const GURL& url,
+ const GURL& referrer_url,
+ const std::string& client_guid,
+ mojo::PendingRemote<quarantine::mojom::Quarantine> remote_quarantine,
+ bool is_success);
+
+ // Called on the file thread when file quarantine finishes on a SaveItem.
+ void OnQuarantineComplete(SaveItemId save_item_id,
+ SavePackageId save_package_id,
+ download::DownloadInterruptReason result);
+
// Notifications sent from the file thread and run on the UI thread.
// Lookup the SaveManager for this WebContents' saving browser context and
diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc
index 6028a18435ccc29fd0aa56f761f48f2659930f01..4def8a62fc6755ff0613eaec30282a3e3c132206 100644
--- a/content/browser/download/save_package.cc
+++ b/content/browser/download/save_package.cc
@@ -843,6 +843,12 @@ void SavePackage::SaveNextFile(bool process_all_remaining_items) {
RenderFrameHostImpl* requester_frame =
requester_frame_tree_node->current_frame_host();
+ mojo::PendingRemote<quarantine::mojom::Quarantine> quarantine;
+ auto quarantine_callback =
+ download_manager_->GetQuarantineConnectionCallback();
+ if (quarantine_callback)
+ quarantine_callback.Run(quarantine.InitWithNewPipeAndPassReceiver());
+
file_manager_->SaveURL(
save_item_ptr->id(), save_item_ptr->url(), save_item_ptr->referrer(),
requester_frame->GetProcess()->GetID(),
@@ -854,8 +860,8 @@ void SavePackage::SaveNextFile(bool process_all_remaining_items) {
->GetRenderViewHost()
->GetProcess()
->GetStoragePartition(),
- this);
-
+ this, download_manager_->GetApplicationClientIdForFileScanning(),
+ std::move(quarantine));
} while (process_all_remaining_items && !waiting_item_queue_.empty());
}

View File

@@ -0,0 +1,215 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Koji Ishii <kojii@chromium.org>
Date: Mon, 26 Jul 2021 07:09:18 +0000
Subject: Fix nested inline box fragmentation
This patch fixes when nested inline boxes are fragmented in a
line due to bidi reordering.
Before this change, the fragmented boxes are appended to the
end of |box_data_list_|. Then when |NGInlineLayoutStateStack::
CreateBoxFragments| creates inline boxes in the ascending
order of |box_data_list_|, it failed to add the fragmented
boxes into their parent inline boxes.
This is critical for out-of-flow positioned objects whose
containing block is an inline box, because they expect to be
propagated through all ancestor inline boxes.
|UpdateBoxDataFragmentRange| is a little tricky by appending
to a vector it is iterating. Changing it to insert to the
correct position makes the function even trickier. This patch
changes it to add fragmented boxes to a separate vector, and
let later process |UpdateFragmentedBoxDataEdges| to merge the
vector to |box_data_list_|.
(cherry picked from commit 9c8a39c14a9c80556468593cddf436f5047a16ce)
Bug: 1227933, 1229999
Change-Id: I7edcd209e1fdac06bab01b16d660383e7e9c37bd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3038308
Commit-Queue: Koji Ishii <kojii@chromium.org>
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#903356}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3053212
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/branch-heads/4577@{#145}
Cr-Branched-From: 761ddde228655e313424edec06497d0c56b0f3c4-refs/heads/master@{#902210}
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
index b257014513cb881d4531694b86c05fd21edb6732..9a3f6f3af7839ebed24f7d8a32b7f95fba66cd9a 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h"
+#include "base/containers/adapters.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_offset.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h"
@@ -387,13 +388,14 @@ void NGInlineLayoutStateStack::UpdateAfterReorder(
box_data.fragment_start = box_data.fragment_end = 0;
// Scan children and update start/end from their box_data_index.
- unsigned box_count = box_data_list_.size();
+ Vector<BoxData> fragmented_boxes;
for (unsigned index = 0; index < line_box->size();)
- index = UpdateBoxDataFragmentRange(line_box, index);
+ index = UpdateBoxDataFragmentRange(line_box, index, &fragmented_boxes);
- // If any inline fragmentation due to BiDi reorder, adjust box edges.
- if (box_count != box_data_list_.size())
- UpdateFragmentedBoxDataEdges();
+ // If any inline fragmentation occurred due to BiDi reorder, append them and
+ // adjust box edges.
+ if (UNLIKELY(!fragmented_boxes.IsEmpty()))
+ UpdateFragmentedBoxDataEdges(&fragmented_boxes);
#if DCHECK_IS_ON()
// Check all BoxData have ranges.
@@ -410,7 +412,8 @@ void NGInlineLayoutStateStack::UpdateAfterReorder(
unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
NGLogicalLineItems* line_box,
- unsigned index) {
+ unsigned index,
+ Vector<BoxData>* fragmented_boxes) {
// Find the first line box item that should create a box fragment.
for (; index < line_box->size(); index++) {
NGLogicalLineItem* start = &(*line_box)[index];
@@ -438,7 +441,7 @@ unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
// It also changes other BoxData, but not the one we're dealing with here
// because the update is limited only when its |box_data_index| is lower.
while (end->box_data_index && end->box_data_index < box_data_index) {
- UpdateBoxDataFragmentRange(line_box, index);
+ UpdateBoxDataFragmentRange(line_box, index, fragmented_boxes);
}
if (box_data_index != end->box_data_index)
@@ -453,14 +456,9 @@ unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
} else {
// This box is fragmented by BiDi reordering. Add a new BoxData for the
// fragmented range.
- box_data_list_[box_data_index - 1].fragmented_box_data_index =
- box_data_list_.size();
- // Do not use `emplace_back()` here because adding to |box_data_list_| may
- // reallocate the buffer, but the `BoxData` ctor must run before the
- // reallocation. Create a new instance and |push_back()| instead.
- BoxData fragmented_box_data(box_data_list_[box_data_index - 1],
- start_index, index);
- box_data_list_.push_back(fragmented_box_data);
+ BoxData& fragmented_box = fragmented_boxes->emplace_back(
+ box_data_list_[box_data_index - 1], start_index, index);
+ fragmented_box.fragmented_box_data_index = box_data_index;
}
// If this box has parent boxes, we need to process it again.
if (box_data_list_[box_data_index - 1].parent_box_data_index)
@@ -470,7 +468,43 @@ unsigned NGInlineLayoutStateStack::UpdateBoxDataFragmentRange(
return index;
}
-void NGInlineLayoutStateStack::UpdateFragmentedBoxDataEdges() {
+void NGInlineLayoutStateStack::UpdateFragmentedBoxDataEdges(
+ Vector<BoxData>* fragmented_boxes) {
+ DCHECK(!fragmented_boxes->IsEmpty());
+ // Append in the descending order of |fragmented_box_data_index| because the
+ // indices will change as boxes are inserted into |box_data_list_|.
+ std::sort(fragmented_boxes->begin(), fragmented_boxes->end(),
+ [](const BoxData& a, const BoxData& b) {
+ if (a.fragmented_box_data_index != b.fragmented_box_data_index) {
+ return a.fragmented_box_data_index <
+ b.fragmented_box_data_index;
+ }
+ DCHECK_NE(a.fragment_start, b.fragment_start);
+ return a.fragment_start < b.fragment_start;
+ });
+ for (BoxData& fragmented_box : base::Reversed(*fragmented_boxes)) {
+ // Insert the fragmented box to right after the box it was fragmented from.
+ // The order in the |box_data_list_| is critical when propagating child
+ // fragment data such as OOF to ancestors.
+ const unsigned insert_at = fragmented_box.fragmented_box_data_index;
+ DCHECK_GT(insert_at, 0u);
+ fragmented_box.fragmented_box_data_index = 0;
+ box_data_list_.insert(insert_at, fragmented_box);
+
+ // Adjust box data indices by the insertion.
+ for (BoxData& box_data : box_data_list_) {
+ if (box_data.fragmented_box_data_index >= insert_at)
+ ++box_data.fragmented_box_data_index;
+ }
+
+ // Set the index of the last fragment to the original box. This is needed to
+ // update fragment edges.
+ const unsigned fragmented_from = insert_at - 1;
+ if (!box_data_list_[fragmented_from].fragmented_box_data_index)
+ box_data_list_[fragmented_from].fragmented_box_data_index = insert_at;
+ }
+
+ // Move the line-right edge to the last fragment.
for (BoxData& box_data : box_data_list_) {
if (box_data.fragmented_box_data_index)
box_data.UpdateFragmentEdges(box_data_list_);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
index 82ecfef8fe4d404d5713f0f67d83b38ecfbfca4c..9d079266efd7f2ccc43cef40d8d89e4fc6edda9e 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
@@ -156,17 +156,6 @@ class CORE_EXPORT NGInlineLayoutStateStack {
// reordering.
void UpdateAfterReorder(NGLogicalLineItems*);
- // Update start/end of the first BoxData found at |index|.
- //
- // If inline fragmentation is found, a new BoxData is added.
- //
- // Returns the index to process next. It should be given to the next call to
- // this function.
- unsigned UpdateBoxDataFragmentRange(NGLogicalLineItems*, unsigned index);
-
- // Update edges of inline fragmented boxes.
- void UpdateFragmentedBoxDataEdges();
-
// Compute inline positions of fragments and boxes.
LayoutUnit ComputeInlinePositions(NGLogicalLineItems*, LayoutUnit position);
@@ -259,6 +248,19 @@ class CORE_EXPORT NGInlineLayoutStateStack {
scoped_refptr<const NGLayoutResult> CreateBoxFragment(NGLogicalLineItems*);
};
+ // Update start/end of the first BoxData found at |index|.
+ //
+ // If inline fragmentation is found, a new BoxData is added.
+ //
+ // Returns the index to process next. It should be given to the next call to
+ // this function.
+ unsigned UpdateBoxDataFragmentRange(NGLogicalLineItems*,
+ unsigned index,
+ Vector<BoxData>* fragmented_boxes);
+
+ // Update edges of inline fragmented boxes.
+ void UpdateFragmentedBoxDataEdges(Vector<BoxData>* fragmented_boxes);
+
Vector<NGInlineBoxState, 4> stack_;
Vector<BoxData, 4> box_data_list_;
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/text/crashtests/bidi-inline-fragment-oof-crash.html b/third_party/blink/web_tests/external/wpt/css/CSS2/text/crashtests/bidi-inline-fragment-oof-crash.html
new file mode 100644
index 0000000000000000000000000000000000000000..b701d2b5688ace54aa99530c12fa8143f1e6a508
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/CSS2/text/crashtests/bidi-inline-fragment-oof-crash.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<link rel="author" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://crbug.com/1229999">
+<div style="direction:rtl; width:500px">
+ <span style="border:solid">
+ <span style="position:relative">
+ <div style="display:inline-block; width:1000%; height:10px"></div>
+ <span dir="ltr">
+ <div style="position:absolute"></div>
+ </span>
+ </span>
+ </span>
+</div>

View File

@@ -0,0 +1,163 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lei Zhang <thestig@chromium.org>
Date: Tue, 10 Aug 2021 21:38:36 +0000
Subject: Do more class validity checks in PrintViewManagerBase.
PrintViewManagerBase runs a nested loop. In some situations,
PrintViewManagerBase and related classes like PrintViewManager and
PrintPreviewHandler can get deleted while the nested loop is running.
When this happens, the nested loop exists to a PrintViewManagerBase
that is no longer valid.
Use base::WeakPtrs liberally to check for this condition and exit
safely.
(cherry picked from commit a2cb1fb333d2faacb2fe1380f8d2621b5ee6af7e)
Bug: 1231134
Change-Id: I21ec131574331ce973d22594c11e70088147e149
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3057880
Reviewed-by: Alan Screen <awscreen@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#906269}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3086110
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4515@{#2024}
Cr-Branched-From: 488fc70865ddaa05324ac00a54a6eb783b4bc41c-refs/heads/master@{#885287}
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc
index 2153c11769e0c015bdfb5f54b4706b40b7c7ec96..6f65d6d968461a3001eeafa6b117852d6efe4a39 100644
--- a/chrome/browser/printing/print_view_manager.cc
+++ b/chrome/browser/printing/print_view_manager.cc
@@ -101,7 +101,11 @@ bool PrintViewManager::PrintForSystemDialogNow(
DCHECK(!on_print_dialog_shown_callback_);
on_print_dialog_shown_callback_ = std::move(dialog_shown_callback);
is_switching_to_system_dialog_ = true;
+
+ auto weak_this = weak_factory_.GetWeakPtr();
DisconnectFromCurrentPrintJob();
+ if (!weak_this)
+ return false;
// Don't print / print preview crashed tabs.
if (IsCrashed())
diff --git a/chrome/browser/printing/print_view_manager.h b/chrome/browser/printing/print_view_manager.h
index 6ee0600dc5fd598cdc63ab3469ee0d23f3f2c463..55ff9ef5e86514b3e65326eef473af16269438b7 100644
--- a/chrome/browser/printing/print_view_manager.h
+++ b/chrome/browser/printing/print_view_manager.h
@@ -133,6 +133,11 @@ class PrintViewManager : public PrintViewManagerBase,
WEB_CONTENTS_USER_DATA_KEY_DECL();
+ // Keep this last so that all weak pointers will be invalidated at the
+ // beginning of destruction. Note that PrintViewManagerBase has its own
+ // base::WeakPtrFactory as well, but PrintViewManager should use this one.
+ base::WeakPtrFactory<PrintViewManager> weak_factory_{this};
+
DISALLOW_COPY_AND_ASSIGN(PrintViewManager);
};
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index 3a7eff03f034e71d8f493b425ea2a922c1e6106d..7bced11a564332e3973ac818ece3a203dd4722bc 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -373,7 +373,10 @@ bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh,
bool silent,
base::Value settings,
CompletionCallback callback) {
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
DisconnectFromCurrentPrintJob();
+ if (!weak_this)
+ return false;
// Don't print / print preview crashed tabs.
if (IsCrashed())
@@ -858,6 +861,8 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() {
// or in DidPrintDocument(). The check is done in
// ShouldQuitFromInnerMessageLoop().
// BLOCKS until all the pages are received. (Need to enable recursive task)
+ // WARNING: Do not do any work after RunInnerMessageLoop() returns, as `this`
+ // may have gone away.
if (!RunInnerMessageLoop()) {
// This function is always called from DisconnectFromCurrentPrintJob() so we
// know that the job will be stopped/canceled in any case.
@@ -884,8 +889,11 @@ bool PrintViewManagerBase::CreateNewPrintJob(
DCHECK(query);
if (callback_.is_null()) {
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
// Disconnect the current |print_job_| only when calling window.print()
DisconnectFromCurrentPrintJob();
+ if (!weak_this)
+ return false;
}
// We can't print if there is no renderer.
@@ -917,7 +925,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
void PrintViewManagerBase::DisconnectFromCurrentPrintJob() {
// Make sure all the necessary rendered page are done. Don't bother with the
// return value.
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
bool result = RenderAllMissingPagesNow();
+ if (!weak_this)
+ return;
// Verify that assertion.
if (print_job_ && print_job_->document() &&
@@ -999,7 +1010,10 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
quit_inner_loop_ = run_loop.QuitClosure();
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
run_loop.Run();
+ if (!weak_this)
+ return false;
// If the inner-loop quit closure is still set then we timed out.
bool success = !quit_inner_loop_;
diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h
index fcbf4c69d1b6cd30124444158e3f2c6da3371977..652f8a54dca556d74fd405691593f805373d8bba 100644
--- a/chrome/browser/printing/print_view_manager_base.h
+++ b/chrome/browser/printing/print_view_manager_base.h
@@ -122,6 +122,8 @@ class PrintViewManagerBase : public content::NotificationObserver,
// Makes sure the current print_job_ has all its data before continuing, and
// disconnect from it.
+ // WARNING: `this` may not be alive after DisconnectFromCurrentPrintJob()
+ // returns.
void DisconnectFromCurrentPrintJob();
// Manages the low-level talk to the printer.
@@ -168,6 +170,7 @@ class PrintViewManagerBase : public content::NotificationObserver,
// Requests the RenderView to render all the missing pages for the print job.
// No-op if no print job is pending. Returns true if at least one page has
// been requested to the renderer.
+ // WARNING: `this` may not be alive after RenderAllMissingPagesNow() returns.
bool RenderAllMissingPagesNow();
// Checks that synchronization is correct with |print_job_| based on |cookie|.
@@ -201,6 +204,7 @@ class PrintViewManagerBase : public content::NotificationObserver,
// while the blocking inner message loop is running. This is useful in cases
// where the RenderView is about to be destroyed while a printing job isn't
// finished.
+ // WARNING: `this` may not be alive after RunInnerMessageLoop() returns.
bool RunInnerMessageLoop();
// In the case of Scripted Printing, where the renderer is controlling the
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index 67aa6bc0d76ef8d830bb7d9f49a70480748b61cb..8b5436c93fe146f04f0c63d4d8e8ee536ef6e866 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -749,9 +749,12 @@ void PrintPreviewHandler::HandleShowSystemDialog(
if (!initiator)
return;
+ auto weak_this = weak_factory_.GetWeakPtr();
auto* print_view_manager = PrintViewManager::FromWebContents(initiator);
print_view_manager->PrintForSystemDialogNow(base::BindOnce(
&PrintPreviewHandler::ClosePreviewDialog, weak_factory_.GetWeakPtr()));
+ if (!weak_this)
+ return;
// Cancel the pending preview request if exists.
print_preview_ui()->OnCancelPendingPreviewRequest();

View File

@@ -0,0 +1,77 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hongchan Choi <hongchan@chromium.org>
Date: Mon, 9 Aug 2021 18:43:22 +0000
Subject: Protect HRTF database loader thread from access by different threads
This patch add a new mutex locker around the HRTF database loader
thread to ensure the safe exclusive access of the loader thread
and the HRTF database.
(cherry picked from commit 6811e850ee10847da16c4d5fdc0f845494586b65)
Bug: 1233564
Change-Id: Ie12b99ffe520d3747e34af387a37637a10aab38a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3068260
Auto-Submit: Hongchan Choi <hongchan@chromium.org>
Commit-Queue: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#908269}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3082114
Reviewed-by: Chris Mumford <cmumford@google.com>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/branch-heads/4577@{#601}
Cr-Branched-From: 761ddde228655e313424edec06497d0c56b0f3c4-refs/heads/master@{#902210}
diff --git a/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc b/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc
index 034ded03d11fa42f0d0f62c6a91f6e20ee5f93e1..01cb98a1116fe1eb6a13ff6345b6bdf4e136badc 100644
--- a/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc
+++ b/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc
@@ -86,6 +86,8 @@ void HRTFDatabaseLoader::LoadTask() {
void HRTFDatabaseLoader::LoadAsynchronously() {
DCHECK(IsMainThread());
+ MutexLocker locker(lock_);
+
// m_hrtfDatabase and m_thread should both be unset because this should be a
// new HRTFDatabaseLoader object that was just created by
// createAndLoadAsynchronouslyIfNecessary and because we haven't started
@@ -122,6 +124,10 @@ void HRTFDatabaseLoader::CleanupTask(base::WaitableEvent* sync) {
}
void HRTFDatabaseLoader::WaitForLoaderThreadCompletion() {
+ // We can lock this because this is called from either the main thread or
+ // the offline audio rendering thread.
+ MutexLocker locker(lock_);
+
if (!thread_)
return;
diff --git a/third_party/blink/renderer/platform/audio/hrtf_database_loader.h b/third_party/blink/renderer/platform/audio/hrtf_database_loader.h
index 3ce476fa68e066d6faf40011e94203f0fb778e71..a94997b4f7e06f96018187967faa524d4acfd5f6 100644
--- a/third_party/blink/renderer/platform/audio/hrtf_database_loader.h
+++ b/third_party/blink/renderer/platform/audio/hrtf_database_loader.h
@@ -64,8 +64,8 @@ class PLATFORM_EXPORT HRTFDatabaseLoader final
// must be called from the audio thread.
bool IsLoaded() { return Database(); }
- // waitForLoaderThreadCompletion() may be called more than once and is
- // thread-safe.
+ // May be called from both main and audio thread, and also can be called more
+ // than once.
void WaitForLoaderThreadCompletion();
// Returns the database or nullptr if the database doesn't yet exist. Must
@@ -87,11 +87,10 @@ class PLATFORM_EXPORT HRTFDatabaseLoader final
void LoadTask();
void CleanupTask(base::WaitableEvent*);
- // Holding a m_lock is required when accessing m_hrtfDatabase since we access
- // it from multiple threads.
+ // |lock_| MUST be held when accessing |hrtf_database_| or |thread_| because
+ // it can be accessed by multiple threads (e.g multiple AudioContexts).
Mutex lock_;
std::unique_ptr<HRTFDatabase> hrtf_database_;
-
std::unique_ptr<Thread> thread_;
float database_sample_rate_;

View File

@@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alex Gough <ajgo@chromium.org>
Date: Fri, 1 Oct 2021 23:30:09 +0000
Subject: Tell clang not to devirtualize TargetServices
Before this change in official builds a child process's delayed
integrity level was not being set correctly. With this change
renderers run at Untrusted IL as intended.
(cherry picked from commit 19d2be5d47e0edc406ef7d93096f54009e47937f)
Tests: https://bugs.chromium.org/p/chromium/issues/detail?id=1254631#c13
Bug: 1254631
Change-Id: I52c149cca3de5218033ed0f37d9f76782b9a6302
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3198382
Reviewed-by: Will Harris <wfh@chromium.org>
Commit-Queue: Will Harris <wfh@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#926934}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3200146
Commit-Queue: Alex Gough <ajgo@chromium.org>
Cr-Commit-Position: refs/branch-heads/4606@{#1285}
Cr-Branched-From: 35b0d5a9dc8362adfd44e2614f0d5b7402ef63d0-refs/heads/master@{#911515}
diff --git a/sandbox/win/src/sandbox.h b/sandbox/win/src/sandbox.h
index 9dfebfcc1721a2c2c34397666976e67b78812d7b..d4ab27f084aeb1b9db54eacf227250cf2364c4e2 100644
--- a/sandbox/win/src/sandbox.h
+++ b/sandbox/win/src/sandbox.h
@@ -140,7 +140,7 @@ class BrokerServices {
// }
//
// For more information see the BrokerServices API documentation.
-class TargetServices {
+class [[clang::lto_visibility_public]] TargetServices {
public:
// Initializes the target. Must call this function before any other.
// returns ALL_OK if successful. All other return values imply failure.

View File

@@ -0,0 +1,135 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robert Flack <flackr@chromium.org>
Date: Fri, 30 Jul 2021 18:51:38 +0000
Subject: Forbid script execution for entire lifecycle update
We should not execute script during the lifecycle update except in cases where we we know it is safe to do so, either because we will rerun the lifecycle steps if anything is invalidated (resize observers, intersection observers) or because the script does not have access to invalidate the DOM (e.g. paint worklets).
(cherry picked from commit a73237da91de8aa49aaa5d9479bae51cf387f090)
Bug: 1196853
Change-Id: Id1fdbbb25107cfdc6c234123f845406c28d32914
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2815619
Reviewed-by: Stefan Zager <szager@chromium.org>
Commit-Queue: Robert Flack <flackr@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#901110}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3058973
Auto-Submit: Robert Flack <flackr@chromium.org>
Commit-Queue: Stefan Zager <szager@chromium.org>
Cr-Commit-Position: refs/branch-heads/4472@{#1588}
Cr-Branched-From: 3d60439cfb36485e76a1c5bb7f513d3721b20da1-refs/heads/master@{#870763}
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
index d3512edd4cad7b7dafbb1c3a6da5cd45ea367e79..69f8e8a598a4aefef652e603f1590c702e288b59 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -96,6 +96,7 @@
#include "third_party/blink/renderer/core/script/classic_script.h"
#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
+#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
@@ -804,6 +805,8 @@ void WebPluginContainerImpl::Dispose() {
}
if (web_plugin_) {
+ // Plugins may execute script on being detached during the lifecycle update.
+ ScriptForbiddenScope::AllowUserAgentScript allow_script;
CHECK(web_plugin_->Container() == this);
web_plugin_->Destroy();
web_plugin_ = nullptr;
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 dd320dd900b7f556c9216c7faedc2ad35588b0d7..a9e724432440c05d1b3bb9863acb4345e07f77b4 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2484,6 +2484,7 @@ bool LocalFrameView::UpdateLifecyclePhases(
void LocalFrameView::UpdateLifecyclePhasesInternal(
DocumentLifecycle::LifecycleState target_state) {
+ ScriptForbiddenScope forbid_script;
// RunScrollTimelineSteps must not run more than once.
bool should_run_scroll_timeline_steps = true;
@@ -2564,6 +2565,10 @@ void LocalFrameView::UpdateLifecyclePhasesInternal(
continue;
}
+ // At this point in time, script is allowed to run as we will repeat the
+ // lifecycle update if anything is invalidated.
+ ScriptForbiddenScope::AllowUserAgentScript allow_script;
+
// ResizeObserver and post-layout IntersectionObserver observation
// deliveries may dirty style and layout. RunResizeObserverSteps will return
// true if any observer ran that may have dirtied style or layout;
@@ -2816,6 +2821,7 @@ bool LocalFrameView::AnyFrameIsPrintingOrPaintingPreview() {
}
void LocalFrameView::RunPaintLifecyclePhase(PaintBenchmarkMode benchmark_mode) {
+ DCHECK(ScriptForbiddenScope::IsScriptForbidden());
TRACE_EVENT0("blink,benchmark", "LocalFrameView::RunPaintLifecyclePhase");
// While printing or capturing a paint preview of a document, the paint walk
// is done into a special canvas. There is no point doing a normal paint step
@@ -2850,17 +2856,11 @@ void LocalFrameView::RunPaintLifecyclePhase(PaintBenchmarkMode benchmark_mode) {
for (PaintLayerScrollableArea* area : *animating_scrollable_areas)
area->UpdateCompositorScrollAnimations();
}
- {
- // Updating animations can notify ready promises which could mutate
- // the DOM. We should delay these until we have finished the lifecycle
- // update. https://crbug.com/1196781
- ScriptForbiddenScope forbid_script;
- frame_view.GetLayoutView()
- ->GetDocument()
- .GetDocumentAnimations()
- .UpdateAnimations(DocumentLifecycle::kPaintClean,
- paint_artifact_compositor_.get());
- }
+ frame_view.GetLayoutView()
+ ->GetDocument()
+ .GetDocumentAnimations()
+ .UpdateAnimations(DocumentLifecycle::kPaintClean,
+ paint_artifact_compositor_.get());
Document& document = frame_view.GetLayoutView()->GetDocument();
total_animations_count +=
document.GetDocumentAnimations().GetAnimationsCount();
@@ -4454,6 +4454,7 @@ void LocalFrameView::RenderThrottlingStatusChanged() {
// so painting the tree should just clear the previous painted output.
DCHECK(!IsUpdatingLifecycle());
AllowThrottlingScope allow_throtting(*this);
+ ScriptForbiddenScope forbid_script;
RunPaintLifecyclePhase();
}
@@ -4989,6 +4990,7 @@ void LocalFrameView::RunPaintBenchmark(int repeat_count,
// quantization when the time is very small.
base::LapTimer timer(kWarmupRuns, kTimeLimit, kTimeCheckInterval);
do {
+ ScriptForbiddenScope forbid_script;
RunPaintLifecyclePhase(mode);
timer.NextLap();
} while (!timer.HasTimeLimitExpired());
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
index e6e0c5b909c4d073963bcbb074bfb091a6ccb83b..618e08fbb5157c06348feee5f0120bd28ed0bc44 100644
--- a/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
+++ b/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_id_generator.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h"
+#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/graphics/paint_generated_image.h"
namespace blink {
@@ -126,6 +127,10 @@ scoped_refptr<Image> PaintWorklet::Paint(const String& name,
layout_object.GetDocument(), layout_object.StyleRef(),
paint_definition->NativeInvalidationProperties(),
paint_definition->CustomInvalidationProperties());
+ // The PaintWorkletGlobalScope is sufficiently isolated that it is safe to
+ // run during the lifecycle update without concern for it causing
+ // invalidations to the lifecycle.
+ ScriptForbiddenScope::AllowUserAgentScript allow_script;
sk_sp<PaintRecord> paint_record = paint_definition->Paint(
container_size, zoom, style_map, data, device_scale_factor);
if (!paint_record)

View File

@@ -0,0 +1,65 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Koji Ishii <kojii@chromium.org>
Date: Thu, 9 Sep 2021 23:25:48 +0000
Subject: Merge 4577: Apply list item quirks only when the nested list is
block-level
This patch changes to apply quirks for a list-item occupying
the whole line only if the nested list is block-level.
When applying this quirks, list markers are handled like a
regular child. r883403 crrev.com/c/2885398 changed to handle
list markers at |NGBlockLayoutAlgorithm| to support NG block
fragmentation. These two when combined causes the list marker
not laid out if the nested list is not block-level.
This may change some visual behaviors, but I think this is ok:
a) This quirks is not in the quirks spec[1] and not
implemented in Gecko.
b) The previous CL had a visual difference in this case in M92
but no reports so far.
[1]: https://quirks.spec.whatwg.org/
(cherry picked from commit 6f5d97da873f0e193a732fb7281d3484258aef6d)
Bug: 1246932, 1206409
Change-Id: Ia58a1b788313d3d9f221fd010cdd1a906551ab8b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3145018
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#919158}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3151681
Auto-Submit: Koji Ishii <kojii@chromium.org>
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/branch-heads/4577@{#1225}
Cr-Branched-From: 761ddde228655e313424edec06497d0c56b0f3c4-refs/heads/master@{#902210}
diff --git a/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.cc b/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.cc
index a05731c51149ce7ee9f3a62bb2a50742d420f95a..e8c55dedcd3e731cc231d37a78883d9efad1071e 100644
--- a/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.cc
+++ b/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.cc
@@ -26,8 +26,11 @@ bool LayoutNGOutsideListMarker::NeedsOccupyWholeLine() const {
if (!GetDocument().InQuirksMode())
return false;
+ // Apply the quirks when the next sibling is a block-level `<ul>` or `<ol>`.
LayoutObject* next_sibling = NextSibling();
- if (next_sibling && next_sibling->GetNode() &&
+ if (next_sibling && !next_sibling->IsInline() &&
+ !next_sibling->IsFloatingOrOutOfFlowPositioned() &&
+ next_sibling->GetNode() &&
(IsA<HTMLUListElement>(*next_sibling->GetNode()) ||
IsA<HTMLOListElement>(*next_sibling->GetNode())))
return true;
diff --git a/third_party/blink/web_tests/external/wpt/quirks/crashtests/list-item-whole-line-quirks-crash.html b/third_party/blink/web_tests/external/wpt/quirks/crashtests/list-item-whole-line-quirks-crash.html
new file mode 100644
index 0000000000000000000000000000000000000000..b91b09db0e37727e2d3a3e13ca2c7cae25b8d761
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/quirks/crashtests/list-item-whole-line-quirks-crash.html
@@ -0,0 +1,5 @@
+<!-- quirks -->
+<div>a<ul><li><ul style='float: left'></ul></li></ul></div>
+<div>a<ul><li><ul style='position: absolute'></ul></li></ul></div>
+<div>a<ul><li><ul style='display: inline'></ul></li></ul></div>
+<div>a<ul><li><ul style='display: inline-block'></ul></li></ul></div>

View File

@@ -0,0 +1,121 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Scott Violet <sky@chromium.org>
Date: Wed, 8 Sep 2021 18:45:42 +0000
Subject: compositor: fix bug in sending damage regions
Specifically if a layer is added when sending damaged regions the
iterator would be invalidated. This converts to iterating over the
size.
BUG=1242257
TEST=CompositorTestWithMessageLoop.AddLayerDuringUpdateVisualState
(cherry picked from commit 7c0b0577c3ac1060945b7d05ad69f0dec33479b4)
Change-Id: I09f2bd34afce5d3c9402ef470f14923bbc76b8ae
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3140178
Reviewed-by: Ian Vollick <vollick@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#917886}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3149110
Commit-Queue: enne <enne@chromium.org>
Auto-Submit: Scott Violet <sky@chromium.org>
Reviewed-by: enne <enne@chromium.org>
Cr-Commit-Position: refs/branch-heads/4577@{#1206}
Cr-Branched-From: 761ddde228655e313424edec06497d0c56b0f3c4-refs/heads/master@{#902210}
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index 98fd0921a422da7c211eecda361ead41ace85911..e80c49d63346fdbb083b251a2d3e2a1739286eff 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -646,8 +646,10 @@ void Compositor::BeginMainFrameNotExpectedUntil(base::TimeTicks time) {}
static void SendDamagedRectsRecursive(ui::Layer* layer) {
layer->SendDamagedRects();
- for (auto* child : layer->children())
- SendDamagedRectsRecursive(child);
+ // Iterate using the size for the case of mutation during sending damaged
+ // regions. https://crbug.com/1242257.
+ for (size_t i = 0; i < layer->children().size(); ++i)
+ SendDamagedRectsRecursive(layer->children()[i]);
}
void Compositor::UpdateLayerTreeHost() {
diff --git a/ui/compositor/compositor_unittest.cc b/ui/compositor/compositor_unittest.cc
index 242a508436d752893540d992c08f13a6e53ad2d5..952f13bcc2654c411c0f0a965bb7835a34bc5b71 100644
--- a/ui/compositor/compositor_unittest.cc
+++ b/ui/compositor/compositor_unittest.cc
@@ -12,12 +12,14 @@
#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "cc/metrics/frame_sequence_tracker.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/layer.h"
+#include "ui/compositor/layer_delegate.h"
#include "ui/compositor/test/draw_waiter_for_test.h"
#include "ui/compositor/test/in_process_context_factory.h"
#include "ui/compositor/test/test_context_factories.h"
@@ -311,4 +313,58 @@ TEST_F(CompositorTestWithMessageLoop, MAYBE_CreateAndReleaseOutputSurface) {
compositor()->SetRootLayer(nullptr);
}
+class LayerDelegateThatAddsDuringUpdateVisualState : public LayerDelegate {
+ public:
+ explicit LayerDelegateThatAddsDuringUpdateVisualState(Layer* parent)
+ : parent_(parent) {}
+
+ bool update_visual_state_called() const {
+ return update_visual_state_called_;
+ }
+
+ // LayerDelegate:
+ void UpdateVisualState() override {
+ added_layers_.push_back(std::make_unique<Layer>(ui::LAYER_SOLID_COLOR));
+ parent_->Add(added_layers_.back().get());
+ update_visual_state_called_ = true;
+ }
+ void OnPaintLayer(const PaintContext& context) override {}
+ void OnDeviceScaleFactorChanged(float old_device_scale_factor,
+ float new_device_scale_factor) override {}
+
+ private:
+ Layer* parent_;
+ std::vector<std::unique_ptr<Layer>> added_layers_;
+ bool update_visual_state_called_ = false;
+};
+
+TEST_F(CompositorTestWithMessageLoop, AddLayerDuringUpdateVisualState) {
+ std::unique_ptr<Layer> root_layer =
+ std::make_unique<Layer>(ui::LAYER_SOLID_COLOR);
+ std::unique_ptr<Layer> child_layer =
+ std::make_unique<Layer>(ui::LAYER_TEXTURED);
+ std::unique_ptr<Layer> child_layer2 =
+ std::make_unique<Layer>(ui::LAYER_SOLID_COLOR);
+ LayerDelegateThatAddsDuringUpdateVisualState child_layer_delegate(
+ root_layer.get());
+ child_layer->set_delegate(&child_layer_delegate);
+ root_layer->Add(child_layer.get());
+ root_layer->Add(child_layer2.get());
+
+ viz::ParentLocalSurfaceIdAllocator allocator;
+ allocator.GenerateId();
+ root_layer->SetBounds(gfx::Rect(10, 10));
+ compositor()->SetRootLayer(root_layer.get());
+ compositor()->SetScaleAndSize(1.0f, gfx::Size(10, 10),
+ allocator.GetCurrentLocalSurfaceId());
+ ASSERT_TRUE(compositor()->IsVisible());
+ compositor()->ScheduleDraw();
+ DrawWaiterForTest::WaitForCompositingEnded(compositor());
+ EXPECT_TRUE(child_layer_delegate.update_visual_state_called());
+ compositor()->SetRootLayer(nullptr);
+ child_layer2.reset();
+ child_layer.reset();
+ root_layer.reset();
+}
+
} // namespace ui

View File

@@ -0,0 +1,230 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Erik Chen <erikchen@chromium.org>
Date: Wed, 29 Sep 2021 21:16:47 +0000
Subject: Prevents non-browser processes from requesting memory dumps.
This CL makes several changes:
(1) Causes the browser to reset non-browser
mojo::PendingReceiver<Coordinator>. This means that non-browser
processes will never be able to use the Coordinator interface.
(2) Add CHECKs to existing code to prevent non-browser processes from
attempting to use the Coordinator interface.
A code audit shows that all Coordinator usages should already only be
from the browser process.
Note that (2) is important since attempting to use an unbound interface
will trigger a nullptr dereference, which is undefined behavior.
(cherry picked from commit d9cc471e122e9a2391a68fa7cd72ea50587d8d97)
Bug: 1251787
Change-Id: Ifbe9610cc0e373edaaa60fad46b447e8bdb3ec04
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3174305
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Reviewed-by: ssid <ssid@chromium.org>
Auto-Submit: Erik Chen <erikchen@chromium.org>
Commit-Queue: Erik Chen <erikchen@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#923693}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3194811
Reviewed-by: Avi Drissman <avi@chromium.org>
Reviewed-by: Krishna Govind <govind@chromium.org>
Commit-Queue: Krishna Govind <govind@chromium.org>
Owners-Override: Krishna Govind <govind@chromium.org>
Cr-Commit-Position: refs/branch-heads/4606@{#1253}
Cr-Branched-From: 35b0d5a9dc8362adfd44e2614f0d5b7402ef63d0-refs/heads/master@{#911515}
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc
index e3a67915c8a828524da64e88f1e07c7bc960d36f..dd89731d031a2092bc7eb0fe5af16ad535b12957 100644
--- a/content/browser/browser_child_process_host_impl.cc
+++ b/content/browser/browser_child_process_host_impl.cc
@@ -662,6 +662,9 @@ void BrowserChildProcessHostImpl::RegisterCoordinatorClient(
mojo::PendingReceiver<memory_instrumentation::mojom::Coordinator> receiver,
mojo::PendingRemote<memory_instrumentation::mojom::ClientProcess>
client_process) {
+ // Intentionally disallow non-browser processes from getting a Coordinator.
+ receiver.reset();
+
// The child process may have already terminated by the time this message is
// dispatched. We do nothing in that case.
if (!IsProcessLaunched())
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 34a066bf4ec85ec4ec5606861320b0e1a1f9793b..f27b2eb04487cbabe499e70319643f64db7812be 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2592,6 +2592,9 @@ void RenderProcessHostImpl::RegisterCoordinatorClient(
mojo::PendingReceiver<memory_instrumentation::mojom::Coordinator> receiver,
mojo::PendingRemote<memory_instrumentation::mojom::ClientProcess>
client_process) {
+ // Intentionally disallow non-browser processes from getting a Coordinator.
+ receiver.reset();
+
if (!GetProcess().IsValid()) {
// If the process dies before we get this message. we have no valid PID
// and there's nothing to register.
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
index d78430c058b429c5abd8f3e533d7c108b34d2010..fdc67aef27ec4bfb0f59ff1c40d005259bd2699e 100644
--- a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
+++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
@@ -105,7 +105,8 @@ void CoordinatorImpl::RegisterClientProcess(
const base::Optional<std::string>& service_name) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
mojo::Remote<mojom::ClientProcess> process(std::move(client_process));
- coordinator_receivers_.Add(this, std::move(receiver), process_id);
+ if (receiver.is_valid())
+ coordinator_receivers_.Add(this, std::move(receiver), process_id);
process.set_disconnect_handler(
base::BindOnce(&CoordinatorImpl::UnregisterClientProcess,
base::Unretained(this), process_id));
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc
index ca0e8d8441a53fce370b375930b149a0b8dd6974..ae9ef93eafe0196c7a16743211f04eebe2c87d34 100644
--- a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc
+++ b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc
@@ -24,6 +24,11 @@ void ClientProcessImpl::CreateInstance(
mojo::PendingReceiver<mojom::ClientProcess> receiver,
mojo::PendingRemote<mojom::Coordinator> coordinator,
bool is_browser_process) {
+ // Intentionally disallow non-browser processes from ever holding a
+ // Coordinator.
+ if (!is_browser_process)
+ coordinator.reset();
+
static ClientProcessImpl* instance = nullptr;
if (!instance) {
instance = new ClientProcessImpl(
@@ -39,10 +44,12 @@ ClientProcessImpl::ClientProcessImpl(
mojo::PendingRemote<mojom::Coordinator> coordinator,
bool is_browser_process,
bool initialize_memory_instrumentation)
- : receiver_(this, std::move(receiver)) {
+ : receiver_(this, std::move(receiver)),
+ is_browser_process_(is_browser_process) {
if (initialize_memory_instrumentation) {
// Initialize the public-facing MemoryInstrumentation helper.
- MemoryInstrumentation::CreateInstance(std::move(coordinator));
+ MemoryInstrumentation::CreateInstance(std::move(coordinator),
+ is_browser_process);
} else {
coordinator_.Bind(std::move(coordinator));
}
@@ -109,6 +116,8 @@ void ClientProcessImpl::OnChromeMemoryDumpDone(
void ClientProcessImpl::RequestGlobalMemoryDump_NoCallback(
base::trace_event::MemoryDumpType dump_type,
base::trace_event::MemoryDumpLevelOfDetail level_of_detail) {
+ CHECK(is_browser_process_);
+
if (!task_runner_->RunsTasksInCurrentSequence()) {
task_runner_->PostTask(
FROM_HERE,
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h
index 6dd8c55823de34ccef4244036b4d4c8cda92f74a..8c2c20c449a2e3bf8c7465ccbc2fba6fd1cb402b 100644
--- a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h
+++ b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h
@@ -96,6 +96,9 @@ class COMPONENT_EXPORT(RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION)
mojo::Remote<mojom::Coordinator> coordinator_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ // Only browser process is allowed to request memory dumps.
+ const bool is_browser_process_;
+
// TODO(crbug.com/728199): The observer is only used to setup and tear down
// MemoryDumpManager in each process. Setting up MemoryDumpManager should
// be moved away from TracingObserver.
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.cc
index c81d5f83bf9e1ad5e7a77d7c187fa33bd02812d5..ec90ab9211ede586d441f40e3e2bc2c820658fb1 100644
--- a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.cc
+++ b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.cc
@@ -21,10 +21,11 @@ void WrapGlobalMemoryDump(
// static
void MemoryInstrumentation::CreateInstance(
- mojo::PendingRemote<memory_instrumentation::mojom::Coordinator>
- coordinator) {
+ mojo::PendingRemote<memory_instrumentation::mojom::Coordinator> coordinator,
+ bool is_browser_process) {
DCHECK(!g_instance);
- g_instance = new MemoryInstrumentation(std::move(coordinator));
+ g_instance =
+ new MemoryInstrumentation(std::move(coordinator), is_browser_process);
}
// static
@@ -33,8 +34,10 @@ MemoryInstrumentation* MemoryInstrumentation::GetInstance() {
}
MemoryInstrumentation::MemoryInstrumentation(
- mojo::PendingRemote<memory_instrumentation::mojom::Coordinator> coordinator)
- : coordinator_(std::move(coordinator)) {}
+ mojo::PendingRemote<memory_instrumentation::mojom::Coordinator> coordinator,
+ bool is_browser_process)
+ : coordinator_(std::move(coordinator)),
+ is_browser_process_(is_browser_process) {}
MemoryInstrumentation::~MemoryInstrumentation() {
g_instance = nullptr;
@@ -43,6 +46,7 @@ MemoryInstrumentation::~MemoryInstrumentation() {
void MemoryInstrumentation::RequestGlobalDump(
const std::vector<std::string>& allocator_dump_names,
RequestGlobalDumpCallback callback) {
+ CHECK(is_browser_process_);
coordinator_->RequestGlobalMemoryDump(
MemoryDumpType::SUMMARY_ONLY, MemoryDumpLevelOfDetail::BACKGROUND,
MemoryDumpDeterminism::NONE, allocator_dump_names,
@@ -52,6 +56,7 @@ void MemoryInstrumentation::RequestGlobalDump(
void MemoryInstrumentation::RequestPrivateMemoryFootprint(
base::ProcessId pid,
RequestGlobalDumpCallback callback) {
+ CHECK(is_browser_process_);
coordinator_->RequestPrivateMemoryFootprint(
pid, base::BindOnce(&WrapGlobalMemoryDump, std::move(callback)));
}
@@ -60,6 +65,7 @@ void MemoryInstrumentation::RequestGlobalDumpForPid(
base::ProcessId pid,
const std::vector<std::string>& allocator_dump_names,
RequestGlobalDumpCallback callback) {
+ CHECK(is_browser_process_);
coordinator_->RequestGlobalMemoryDumpForPid(
pid, allocator_dump_names,
base::BindOnce(&WrapGlobalMemoryDump, std::move(callback)));
@@ -70,6 +76,7 @@ void MemoryInstrumentation::RequestGlobalDumpAndAppendToTrace(
MemoryDumpLevelOfDetail level_of_detail,
MemoryDumpDeterminism determinism,
RequestGlobalMemoryDumpAndAppendToTraceCallback callback) {
+ CHECK(is_browser_process_);
coordinator_->RequestGlobalMemoryDumpAndAppendToTrace(
dump_type, level_of_detail, determinism, std::move(callback));
}
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h
index 3264917890cc30179c4477657158fd359a9d1e01..72157b5345fb003452f67045e2b2c984e748958a 100644
--- a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h
+++ b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h
@@ -34,7 +34,8 @@ class COMPONENT_EXPORT(RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION)
static void CreateInstance(
mojo::PendingRemote<memory_instrumentation::mojom::Coordinator>
- coordinator);
+ coordinator,
+ bool is_browser_process);
static MemoryInstrumentation* GetInstance();
// Retrieves a Coordinator interface to communicate with the service. This is
@@ -100,12 +101,16 @@ class COMPONENT_EXPORT(RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION)
private:
explicit MemoryInstrumentation(
mojo::PendingRemote<memory_instrumentation::mojom::Coordinator>
- coordinator);
+ coordinator,
+ bool is_browser_process);
~MemoryInstrumentation();
const mojo::SharedRemote<memory_instrumentation::mojom::Coordinator>
coordinator_;
+ // Only browser process is allowed to request memory dumps.
+ const bool is_browser_process_;
+
DISALLOW_COPY_AND_ASSIGN(MemoryInstrumentation);
};

View File

@@ -0,0 +1,274 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ian Kilpatrick <ikilpatrick@chromium.org>
Date: Thu, 9 Sep 2021 23:20:48 +0000
Subject: Remove limit from LayoutInline::SplitInlines.
After 200 elements the code "gave up" causing the layout tree to be
"strange".
This caused a To<LayoutInline> to fail in the OOF code. Relaxing this
To<> to a DynamicTo<> caused additional CHECKs / DCHECKs all over the
place (not just in NG but in Legacy as well).
This patch removes the limit at which we "give up". This may cause
additional render hangs.
However we currently have a project "block-in-inline" which will (for
most cases) stop inline-splitting for occuring (except in legacy
fallback).
(cherry picked from commit bbd315efb49a4ae257509dd0f0d85c6b5906e0e4)
(cherry picked from commit d760d2ae1d51c0b4fda87a0a3af4e7ed30d2ff4c)
Bug: 1245786
Change-Id: I5f1c4d6a4b81a8345974de40c0c50a27a839b7b4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3140144
Reviewed-by: Koji Ishii <kojii@chromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/main@{#917771}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3149698
Cr-Original-Commit-Position: refs/branch-heads/4606@{#876}
Cr-Original-Branched-From: 35b0d5a9dc8362adfd44e2614f0d5b7402ef63d0-refs/heads/master@{#911515}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3152301
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4577@{#1224}
Cr-Branched-From: 761ddde228655e313424edec06497d0c56b0f3c4-refs/heads/master@{#902210}
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc
index 06497bec8c4d774539693c45c6cc2f038ce5a160..7b599014ba2ac8ec5403a48aefd39b639034d60e 100644
--- a/third_party/blink/renderer/core/layout/layout_inline.cc
+++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -577,15 +577,13 @@ void LayoutInline::SplitInlines(LayoutBlockFlow* from_block,
// nest to a much greater depth (see bugzilla bug 13430) but for now we have a
// limit. This *will* result in incorrect rendering, but the alternative is to
// hang forever.
- const unsigned kCMaxSplitDepth = 200;
Vector<LayoutInline*> inlines_to_clone;
LayoutInline* top_most_inline = this;
for (LayoutObject* o = this; o != from_block; o = o->Parent()) {
if (o->IsLayoutNGInsideListMarker())
continue;
top_most_inline = To<LayoutInline>(o);
- if (inlines_to_clone.size() < kCMaxSplitDepth)
- inlines_to_clone.push_back(top_most_inline);
+ inlines_to_clone.push_back(top_most_inline);
// Keep walking up the chain to ensure |topMostInline| is a child of
// |fromBlock|, to avoid assertion failure when |fromBlock|'s children are
// moved to |toBlock| below.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-inline/inline-crash.html b/third_party/blink/web_tests/external/wpt/css/css-inline/inline-crash.html
new file mode 100644
index 0000000000000000000000000000000000000000..65008f74ce6e0b4397a5b333099c692382d64353
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-inline/inline-crash.html
@@ -0,0 +1,210 @@
+<!DOCTYPE html>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1245786">
+<style>
+ nav{ position: absolute; }
+ body > * { position: relative; }
+</style>
+<body>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<span>
+<div>
+<nav>

View File

@@ -0,0 +1,48 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Mon, 25 Oct 2021 18:22:50 +0000
Subject: Validate INTRODUCE source node
INTRODUCE NodeChannel messages should only be acknowledged when coming
from the broker process.
(cherry picked from commit 6e74f7b5cb2f48b17403f0431f3e4f3a2e716265)
Fixed: 1252858
Change-Id: I2dff6d5cab102ce744ad2ad66a9f24b4202cbea8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3193798
Reviewed-by: Alex Gough <ajgo@chromium.org>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#926430}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3229034
Auto-Submit: Ken Rockot <rockot@google.com>
Reviewed-by: Oksana Zhuravlova <oksamyt@chromium.org>
Commit-Queue: Oksana Zhuravlova <oksamyt@chromium.org>
Cr-Commit-Position: refs/branch-heads/4638@{#964}
Cr-Branched-From: 159257cab5585bc8421abf347984bb32fdfe9eb9-refs/heads/main@{#920003}
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc
index 351a34a40f0613ce167fd8158f5e3f494e95ce5e..44dd2a8fb1c546693b75675260fdc70db9b99ff7 100644
--- a/mojo/core/node_controller.cc
+++ b/mojo/core/node_controller.cc
@@ -21,6 +21,7 @@
#include "mojo/core/broker.h"
#include "mojo/core/broker_host.h"
#include "mojo/core/configuration.h"
+#include "mojo/core/ports/name.h"
#include "mojo/core/request_context.h"
#include "mojo/core/user_message_impl.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
@@ -1109,6 +1110,12 @@ void NodeController::OnIntroduce(const ports::NodeName& from_node,
PlatformHandle channel_handle) {
DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
+ if (broker_name_ == ports::kInvalidNodeName || from_node != broker_name_) {
+ DVLOG(1) << "Ignoring introduction from non-broker process.";
+ DropPeer(from_node, nullptr);
+ return;
+ }
+
if (!channel_handle.is_valid()) {
node_->LostConnectionToNode(name);

View File

@@ -0,0 +1,85 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Bostr=C3=B6m?= <hbos@chromium.org>
Date: Thu, 8 Jul 2021 12:16:10 +0000
Subject: Fix UAF in VideoCaptureDeviceAVFoundation's dealloc.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Despite dealloc performing stopCapture prior to clearing variables like
_sampleBufferTransformer, it appears possible for callbacks that are
already running concurrently to be using these variables, resulting in
rare use-after-free races. By grabbing the _lock, we avoid this issue.
We also have to introduce a new lock, _destructionLock, to ensure |this|
is not destroyed while -captureOutput is still running.
Bug: chromium:1227228
Change-Id: I8c2c4d9834ee995d3f4154fae13e262398e6f2e2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3013796
Reviewed-by: Evan Shrubsole <eshr@google.com>
Reviewed-by: Ilya Nikolaevskiy <ilnik@chromium.org>
Commit-Queue: Henrik Boström <hbos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#899503}
diff --git a/media/capture/video/mac/video_capture_device_avfoundation_mac.h b/media/capture/video/mac/video_capture_device_avfoundation_mac.h
index 4ecd25491967d001f71e01f88ca415c5bbe788c7..134423d6bee933ab4bebcd7bb99b874b93eb847c 100644
--- a/media/capture/video/mac/video_capture_device_avfoundation_mac.h
+++ b/media/capture/video/mac/video_capture_device_avfoundation_mac.h
@@ -52,6 +52,8 @@ CAPTURE_EXPORT
// Protects concurrent setting and using |frameReceiver_|. Note that the
// GUARDED_BY decoration below does not have any effect.
base::Lock _lock;
+ // Used to avoid UAF in -captureOutput.
+ base::Lock _destructionLock;
media::VideoCaptureDeviceAVFoundationFrameReceiver* _frameReceiver
GUARDED_BY(_lock); // weak.
diff --git a/media/capture/video/mac/video_capture_device_avfoundation_mac.mm b/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
index 7367fbdb4b9216f012c263007170fbc70b1ad823..d1a7997a08ec9ce87278822c8f4c6156db489e7c 100644
--- a/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
+++ b/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
@@ -180,12 +180,26 @@ - (id)initWithFrameReceiver:
}
- (void)dealloc {
- [self stopStillImageOutput];
- [self stopCapture];
- _sampleBufferTransformer.reset();
- _weakPtrFactoryForTakePhoto = nullptr;
- _mainThreadTaskRunner = nullptr;
- _sampleQueue.reset();
+ {
+ // To avoid races with concurrent callbacks, grab the lock before stopping
+ // capture and clearing all the variables.
+ base::AutoLock lock(_lock);
+ [self stopStillImageOutput];
+ [self stopCapture];
+ _frameReceiver = nullptr;
+ _sampleBufferTransformer.reset();
+ _weakPtrFactoryForTakePhoto = nullptr;
+ _mainThreadTaskRunner = nullptr;
+ _sampleQueue.reset();
+ }
+ {
+ // Ensures -captureOutput has finished before we continue the destruction
+ // steps. If -captureOutput grabbed the destruction lock before us this
+ // prevents UAF. If -captureOutput grabbed the destruction lock after us
+ // it will exit early because |_frameReceiver| is already null at this
+ // point.
+ base::AutoLock destructionLock(_destructionLock);
+ }
[super dealloc];
}
@@ -709,7 +723,9 @@ - (void)captureOutput:(AVCaptureOutput*)captureOutput
VLOG(3) << __func__;
// Concurrent calls into |_frameReceiver| are not supported, so take |_lock|
- // before any of the subsequent paths.
+ // before any of the subsequent paths. The |_destructionLock| must be grabbed
+ // first to avoid races with -dealloc.
+ base::AutoLock destructionLock(_destructionLock);
base::AutoLock lock(_lock);
if (!_frameReceiver)
return;

View File

@@ -0,0 +1,336 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jiewei Qian <qjw@chromium.org>
Date: Fri, 3 Sep 2021 04:38:53 +0000
Subject: webui: make WebUIAllowlist and WebUIAllowlistProvider thread-safe
This CL adds synchronization lock to WebUIAllowlist, and expose it as
scoped_refptr, so it provides thread-safety when used in
WebUIAllowlistProvider (per requirements of HostContentSettingsMap).
(cherry picked from commit 56489e04b7c39e7b6d2b3fb33549d2657dad23a9)
(cherry picked from commit 58eda7adb82e7fcc8001482334bfa6f9482aee78)
Fixed: 1238178
Change-Id: I4d8112f7792a7113b412af2eb67cbcef0bdcec1d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3102499
Commit-Queue: Jiewei Qian <qjw@chromium.org>
Reviewed-by: Christian Dullweber <dullweber@chromium.org>
Reviewed-by: calamity <calamity@chromium.org>
Reviewed-by: Victor Costan <pwnall@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/main@{#914567}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3115817
Auto-Submit: Jiewei Qian <qjw@chromium.org>
Commit-Queue: calamity <calamity@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4606@{#340}
Cr-Original-Branched-From: 35b0d5a9dc8362adfd44e2614f0d5b7402ef63d0-refs/heads/master@{#911515}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3141052
Cr-Commit-Position: refs/branch-heads/4577@{#1170}
Cr-Branched-From: 761ddde228655e313424edec06497d0c56b0f3c4-refs/heads/master@{#902210}
diff --git a/ui/webui/webui_allowlist.cc b/ui/webui/webui_allowlist.cc
index 525848a9d2f9baccc95b59581ad2aa53494c449e..cd231550094e410d26a5267427bcb578af451530 100644
--- a/ui/webui/webui_allowlist.cc
+++ b/ui/webui/webui_allowlist.cc
@@ -6,7 +6,11 @@
#include <memory>
+#include "base/memory/scoped_refptr.h"
+#include "base/sequence_checker.h"
+#include "base/supports_user_data.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/common/url_constants.h"
#include "ui/webui/webui_allowlist_provider.h"
#include "url/gurl.h"
@@ -19,15 +23,27 @@ class AllowlistRuleIterator : public content_settings::RuleIterator {
using MapType = std::map<url::Origin, ContentSetting>;
public:
- explicit AllowlistRuleIterator(const MapType& map)
- : it_(map.cbegin()), end_(map.cend()) {}
+ // Hold a reference to `allowlist` to keep it alive during iteration.
+ explicit AllowlistRuleIterator(scoped_refptr<const WebUIAllowlist> allowlist,
+ const MapType& map,
+ std::unique_ptr<base::AutoLock> auto_lock)
+ : auto_lock_(std::move(auto_lock)),
+ allowlist_(std::move(allowlist)),
+ it_(map.cbegin()),
+ end_(map.cend()) {}
AllowlistRuleIterator(const AllowlistRuleIterator&) = delete;
void operator=(const AllowlistRuleIterator&) = delete;
- ~AllowlistRuleIterator() override = default;
+ ~AllowlistRuleIterator() override {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ }
- bool HasNext() const override { return it_ != end_; }
+ bool HasNext() const override {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ return it_ != end_;
+ }
content_settings::Rule Next() override {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const auto& origin = it_->first;
const auto& setting = it_->second;
it_++;
@@ -38,8 +54,18 @@ class AllowlistRuleIterator : public content_settings::RuleIterator {
}
private:
- MapType::const_iterator it_;
- const MapType::const_iterator end_;
+ const std::unique_ptr<base::AutoLock> auto_lock_;
+ const scoped_refptr<const WebUIAllowlist> allowlist_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+ MapType::const_iterator it_ GUARDED_BY_CONTEXT(sequence_checker_);
+ MapType::const_iterator end_ GUARDED_BY_CONTEXT(sequence_checker_);
+};
+
+struct WebUIAllowlistHolder : base::SupportsUserData::Data {
+ explicit WebUIAllowlistHolder(scoped_refptr<WebUIAllowlist> list)
+ : allow_list(std::move(list)) {}
+ const scoped_refptr<WebUIAllowlist> allow_list;
};
} // namespace
@@ -48,11 +74,14 @@ class AllowlistRuleIterator : public content_settings::RuleIterator {
WebUIAllowlist* WebUIAllowlist::GetOrCreate(
content::BrowserContext* browser_context) {
if (!browser_context->GetUserData(kWebUIAllowlistKeyName)) {
- browser_context->SetUserData(kWebUIAllowlistKeyName,
- std::make_unique<WebUIAllowlist>());
+ auto list = base::MakeRefCounted<WebUIAllowlist>();
+ browser_context->SetUserData(
+ kWebUIAllowlistKeyName,
+ std::make_unique<WebUIAllowlistHolder>(std::move(list)));
}
- return static_cast<WebUIAllowlist*>(
- browser_context->GetUserData(kWebUIAllowlistKeyName));
+ return static_cast<WebUIAllowlistHolder*>(
+ browser_context->GetUserData(kWebUIAllowlistKeyName))
+ ->allow_list.get();
}
WebUIAllowlist::WebUIAllowlist() = default;
@@ -62,6 +91,9 @@ WebUIAllowlist::~WebUIAllowlist() = default;
void WebUIAllowlist::RegisterAutoGrantedPermission(const url::Origin& origin,
ContentSettingsType type,
ContentSetting setting) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
// It doesn't make sense to grant a default content setting.
DCHECK_NE(CONTENT_SETTING_DEFAULT, setting);
@@ -70,13 +102,16 @@ void WebUIAllowlist::RegisterAutoGrantedPermission(const url::Origin& origin,
DCHECK(origin.scheme() == content::kChromeUIScheme ||
origin.scheme() == content::kChromeUIUntrustedScheme ||
origin.scheme() == content::kChromeDevToolsScheme);
+ {
+ base::AutoLock auto_lock(lock_);
- // If the same permission is already registered, do nothing. We don't want to
- // notify the provider of ContentSettingChange when it is unnecessary.
- if (permissions_[type][origin] == setting)
- return;
+ // If the same permission is already registered, do nothing. We don't want
+ // to notify the provider of ContentSettingChange when it is unnecessary.
+ if (permissions_[type][origin] == setting)
+ return;
- permissions_[type][origin] = setting;
+ permissions_[type][origin] = setting;
+ }
// Notify the provider. |provider_| can be nullptr if
// HostContentSettingsRegistry is shutting down i.e. when Chrome shuts down.
@@ -92,25 +127,36 @@ void WebUIAllowlist::RegisterAutoGrantedPermission(const url::Origin& origin,
void WebUIAllowlist::RegisterAutoGrantedPermissions(
const url::Origin& origin,
std::initializer_list<ContentSettingsType> types) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
for (const ContentSettingsType& type : types)
RegisterAutoGrantedPermission(origin, type);
}
void WebUIAllowlist::SetWebUIAllowlistProvider(
WebUIAllowlistProvider* provider) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
provider_ = provider;
}
void WebUIAllowlist::ResetWebUIAllowlistProvider() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
provider_ = nullptr;
}
std::unique_ptr<content_settings::RuleIterator> WebUIAllowlist::GetRuleIterator(
ContentSettingsType content_type) const {
- const auto& type_to_origin_rules = permissions_.find(content_type);
- if (type_to_origin_rules != permissions_.cend()) {
- return std::make_unique<AllowlistRuleIterator>(
- type_to_origin_rules->second);
+ auto auto_lock_ = std::make_unique<base::AutoLock>(lock_);
+
+ auto permissions_it = permissions_.find(content_type);
+ if (permissions_it != permissions_.end()) {
+ return std::make_unique<AllowlistRuleIterator>(this, permissions_it->second,
+ std::move(auto_lock_));
}
return nullptr;
diff --git a/ui/webui/webui_allowlist.h b/ui/webui/webui_allowlist.h
index b1623b89f5ed12416e71d5f1505d57b74073f764..9c6ab47b16a4fcc6478e6ad4672ce5c95166156f 100644
--- a/ui/webui/webui_allowlist.h
+++ b/ui/webui/webui_allowlist.h
@@ -8,7 +8,9 @@
#include <initializer_list>
#include <map>
-#include "base/supports_user_data.h"
+#include "base/memory/ref_counted.h"
+#include "base/thread_annotations.h"
+#include "base/threading/thread_checker.h"
#include "components/content_settings/core/browser/content_settings_rule.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
@@ -23,14 +25,13 @@ class WebUIAllowlistProvider;
// list of origins and permissions to be auto-granted to WebUIs. This class is
// created before HostContentSettingsMap is registered and has the same lifetime
// as the profile it's attached to. It outlives WebUIAllowlistProvider.
-class WebUIAllowlist : public base::SupportsUserData::Data {
+class WebUIAllowlist : public base::RefCountedThreadSafe<WebUIAllowlist> {
public:
static WebUIAllowlist* GetOrCreate(content::BrowserContext* browser_context);
WebUIAllowlist();
WebUIAllowlist(const WebUIAllowlist&) = delete;
void operator=(const WebUIAllowlist&) = delete;
- ~WebUIAllowlist() override;
// Register auto-granted |type| permission for |origin|.
//
@@ -53,16 +54,29 @@ class WebUIAllowlist : public base::SupportsUserData::Data {
const url::Origin& origin,
std::initializer_list<ContentSettingsType> types);
+ // Returns a content_settings::RuleIterator, this method is thread-safe.
+ //
+ // This method acquires `lock_` and transfers it to the returned iterator.
+ // NO_THREAD_SAFETY_ANALYSIS because the analyzer doesn't recognize acquiring
+ // the lock in a unique_ptr.
std::unique_ptr<content_settings::RuleIterator> GetRuleIterator(
- ContentSettingsType content_type) const;
+ ContentSettingsType content_type) const NO_THREAD_SAFETY_ANALYSIS;
void SetWebUIAllowlistProvider(WebUIAllowlistProvider* provider);
void ResetWebUIAllowlistProvider();
private:
+ friend class base::RefCountedThreadSafe<WebUIAllowlist>;
+ ~WebUIAllowlist();
+
+ THREAD_CHECKER(thread_checker_);
+
+ mutable base::Lock lock_;
std::map<ContentSettingsType, std::map<url::Origin, ContentSetting>>
- permissions_;
- WebUIAllowlistProvider* provider_ = nullptr;
+ permissions_ GUARDED_BY(lock_);
+
+ WebUIAllowlistProvider* provider_ GUARDED_BY_CONTEXT(thread_checker_) =
+ nullptr;
};
#endif // UI_WEBUI_WEBUI_ALLOWLIST_H_
diff --git a/ui/webui/webui_allowlist_provider.cc b/ui/webui/webui_allowlist_provider.cc
index 779e8022fce378d2a64c78e6e20c36202e9261ac..055a3cf3934ed43373a4a3fdd4166bd3c096e922 100644
--- a/ui/webui/webui_allowlist_provider.cc
+++ b/ui/webui/webui_allowlist_provider.cc
@@ -7,8 +7,9 @@
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "ui/webui/webui_allowlist.h"
-WebUIAllowlistProvider::WebUIAllowlistProvider(WebUIAllowlist* allowlist)
- : allowlist_(allowlist) {
+WebUIAllowlistProvider::WebUIAllowlistProvider(
+ scoped_refptr<WebUIAllowlist> allowlist)
+ : allowlist_(std::move(allowlist)) {
DCHECK(allowlist_);
allowlist_->SetWebUIAllowlistProvider(this);
}
@@ -16,12 +17,8 @@ WebUIAllowlistProvider::WebUIAllowlistProvider(WebUIAllowlist* allowlist)
WebUIAllowlistProvider::~WebUIAllowlistProvider() = default;
std::unique_ptr<content_settings::RuleIterator>
-WebUIAllowlistProvider::GetRuleIterator(
- ContentSettingsType content_type,
- bool incognito) const {
- if (!allowlist_)
- return nullptr;
-
+WebUIAllowlistProvider::GetRuleIterator(ContentSettingsType content_type,
+ bool incognito) const {
return allowlist_->GetRuleIterator(content_type);
}
@@ -48,7 +45,8 @@ void WebUIAllowlistProvider::ClearAllContentSettingsRules(
}
void WebUIAllowlistProvider::ShutdownOnUIThread() {
+ DCHECK(CalledOnValidThread());
+
RemoveAllObservers();
allowlist_->ResetWebUIAllowlistProvider();
- allowlist_ = nullptr;
}
diff --git a/ui/webui/webui_allowlist_provider.h b/ui/webui/webui_allowlist_provider.h
index 9f7f9776fd6e8212d3dbd196698b036f24f75f2e..c18f64e6f2051091f40504c2ba47feb62103aee3 100644
--- a/ui/webui/webui_allowlist_provider.h
+++ b/ui/webui/webui_allowlist_provider.h
@@ -5,6 +5,8 @@
#ifndef UI_WEBUI_WEBUI_ALLOWLIST_PROVIDER_H_
#define UI_WEBUI_WEBUI_ALLOWLIST_PROVIDER_H_
+#include "base/synchronization/lock.h"
+#include "base/thread_annotations.h"
#include "components/content_settings/core/browser/content_settings_observable_provider.h"
#include "components/content_settings/core/common/content_settings.h"
#include "ui/webui/webui_allowlist.h"
@@ -15,8 +17,7 @@ class ContentSettingsPattern;
// permissions from the underlying WebUIAllowlist.
class WebUIAllowlistProvider : public content_settings::ObservableProvider {
public:
- // Note, |allowlist| must outlive this instance.
- explicit WebUIAllowlistProvider(WebUIAllowlist* allowlist);
+ explicit WebUIAllowlistProvider(scoped_refptr<WebUIAllowlist> allowlist);
WebUIAllowlistProvider(const WebUIAllowlistProvider&) = delete;
void operator=(const WebUIAllowlistProvider&) = delete;
~WebUIAllowlistProvider() override;
@@ -27,6 +28,7 @@ class WebUIAllowlistProvider : public content_settings::ObservableProvider {
ContentSettingsType content_type);
// content_settings::ObservableProvider:
+ // The following methods are thread-safe.
std::unique_ptr<content_settings::RuleIterator> GetRuleIterator(
ContentSettingsType content_type,
bool incognito) const override;
@@ -40,7 +42,7 @@ class WebUIAllowlistProvider : public content_settings::ObservableProvider {
void ClearAllContentSettingsRules(ContentSettingsType content_type) override;
private:
- WebUIAllowlist* allowlist_;
+ const scoped_refptr<WebUIAllowlist> allowlist_;
};
#endif // UI_WEBUI_WEBUI_ALLOWLIST_PROVIDER_H_

View File

@@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tal Pressman <talp@chromium.org>
Date: Wed, 21 Jul 2021 09:11:13 +0000
Subject: Manually post task to bind FileUtilitiesHost.
The FileUtilitiesHost binder is posted to a separate sequence, and the
ServiceWorkerHost may be destroyed by the time the it runs, causing a
UAF.
This CL changes it so that, when we try to bind a new receiver, the
host's worker_process_id() is obtained first (on the service worker's
core thread) and then a task is posted to do the actual binding on a
USER_VISIBLE task runner.
Credit: This issue was first reported (with analysis) by
soulchen8650@gmail.com.
Bug: 1229298
Change-Id: I6d5c05a830ba30f6cb98bf2df70a3df3333f3dd9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3041006
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
Commit-Queue: Tal Pressman <talp@google.com>
Cr-Commit-Position: refs/heads/master@{#903832}
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc
index a45f9d3db09dbc4827c41c254b2b532968930e96..b6f69c1813fc9c66cc6a20205c02cb6e5d810fc5 100644
--- a/content/browser/browser_interface_binders.cc
+++ b/content/browser/browser_interface_binders.cc
@@ -367,10 +367,22 @@ void BindTextSuggestionHostForFrame(
}
#endif
+// Get the service worker's worker process ID and post a task to bind the
+// receiver on a USER_VISIBLE task runner.
+// This is necessary because:
+// - Binding the host itself and checking the ID on the task's thread may cause
+// a UAF if the host has been deleted in the meantime.
+// - The process ID is not yet populated at the time `PopulateInterfaceBinders`
+// is called.
void BindFileUtilitiesHost(
- const ServiceWorkerHost* host,
+ ServiceWorkerHost* host,
mojo::PendingReceiver<blink::mojom::FileUtilitiesHost> receiver) {
- FileUtilitiesHostImpl::Create(host->worker_process_id(), std::move(receiver));
+ auto task_runner = base::ThreadPool::CreateSequencedTaskRunner(
+ {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&FileUtilitiesHostImpl::Create, host->worker_process_id(),
+ std::move(receiver)));
}
template <typename WorkerHost, typename Interface>
@@ -1122,9 +1134,7 @@ void PopulateServiceWorkerBinders(ServiceWorkerHost* host,
// static binders
map->Add<blink::mojom::FileUtilitiesHost>(
- base::BindRepeating(&BindFileUtilitiesHost, host),
- base::ThreadPool::CreateSequencedTaskRunner(
- {base::MayBlock(), base::TaskPriority::USER_VISIBLE}));
+ base::BindRepeating(&BindFileUtilitiesHost, host));
map->Add<shape_detection::mojom::BarcodeDetectionProvider>(
base::BindRepeating(&BindBarcodeDetectionProvider));
map->Add<shape_detection::mojom::FaceDetectionProvider>(

View File

@@ -0,0 +1,108 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rayan Kanso <rayankans@google.com>
Date: Wed, 29 Sep 2021 14:40:47 +0000
Subject: Use less-specific error codes for CORS-failing fetches
(cherry picked from commit 26be5702dab1d98e4d4b076a73d4688d20c043be)
Bug: 1245053
Change-Id: If0343157a3ba41a6c946b5f7401a9d114f834779
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3135676
Commit-Queue: Rayan Kanso <rayankans@chromium.org>
Reviewed-by: Richard Knoll <knollr@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#918109}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3190112
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Zakhar Voit <voit@google.com>
Cr-Commit-Position: refs/branch-heads/4430@{#1628}
Cr-Branched-From: e5ce7dc4f7518237b3d9bb93cccca35d25216cbe-refs/heads/master@{#857950}
diff --git a/content/browser/background_fetch/background_fetch_job_controller.cc b/content/browser/background_fetch/background_fetch_job_controller.cc
index f424cadba0f42ce007c85a50b2bdb37a3a3a3499..0d08d1f744edd432c9615be811a60daff3b3c541 100644
--- a/content/browser/background_fetch/background_fetch_job_controller.cc
+++ b/content/browser/background_fetch/background_fetch_job_controller.cc
@@ -173,6 +173,8 @@ void BackgroundFetchJobController::DidStartRequest(
// TODO(crbug.com/884672): Stop the fetch if the cross origin filter fails.
BackgroundFetchCrossOriginFilter filter(registration_id_.origin(), *request);
request->set_can_populate_body(filter.CanPopulateBody());
+ if (!request->can_populate_body())
+ has_failed_cors_request_ = true;
}
void BackgroundFetchJobController::DidUpdateRequest(const std::string& guid,
@@ -253,7 +255,14 @@ uint64_t BackgroundFetchJobController::GetInProgressUploadedBytes() {
void BackgroundFetchJobController::AbortFromDelegate(
BackgroundFetchFailureReason failure_reason) {
- failure_reason_ = failure_reason;
+ if (failure_reason == BackgroundFetchFailureReason::DOWNLOAD_TOTAL_EXCEEDED &&
+ has_failed_cors_request_) {
+ // Don't expose that the download total has been exceeded. Use a less
+ // specific error.
+ failure_reason_ = BackgroundFetchFailureReason::FETCH_ERROR;
+ } else {
+ failure_reason_ = failure_reason;
+ }
Finish(failure_reason_, base::DoNothing());
}
diff --git a/content/browser/background_fetch/background_fetch_job_controller.h b/content/browser/background_fetch/background_fetch_job_controller.h
index e635c86c1eb4237e2b107e3d6fae0242e99dcb4c..66a1c94e9dd79663fbc301c1c91918ef4ac67036 100644
--- a/content/browser/background_fetch/background_fetch_job_controller.h
+++ b/content/browser/background_fetch/background_fetch_job_controller.h
@@ -210,6 +210,10 @@ class CONTENT_EXPORT BackgroundFetchJobController
blink::mojom::BackgroundFetchFailureReason failure_reason_ =
blink::mojom::BackgroundFetchFailureReason::NONE;
+ // Whether one of the requests handled by the controller failed
+ // the CORS checks and should not have its response exposed.
+ bool has_failed_cors_request_ = false;
+
// Custom callback that runs after the controller is finished.
FinishedCallback finished_callback_;
diff --git a/content/browser/background_fetch/background_fetch_job_controller_unittest.cc b/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
index b36154c40a7013bbd02e5a57a2a3c33f7d86775a..d98b2f13b4fdaec84cd4fc21117a38397219deed 100644
--- a/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
@@ -434,6 +434,39 @@ TEST_F(BackgroundFetchJobControllerTest, Abort) {
GetCompletionStatus(registration_id));
}
+TEST_F(BackgroundFetchJobControllerTest, AbortDownloadExceededCrossOrigin) {
+ BackgroundFetchRegistrationId registration_id;
+
+ auto requests = CreateRegistrationForRequests(
+ &registration_id, {{GURL("https://example2.com/funny_cat.png"), "GET"}},
+ /* auto_complete_requests= */ true);
+
+ EXPECT_EQ(JobCompletionStatus::kRunning,
+ GetCompletionStatus(registration_id));
+
+ std::unique_ptr<BackgroundFetchJobController> controller =
+ CreateJobController(registration_id, requests.size());
+
+ controller->StartRequest(requests[0], base::DoNothing());
+
+ controller->DidStartRequest(
+ requests[0]->download_guid(),
+ std::make_unique<BackgroundFetchResponse>(
+ std::vector<GURL>{GURL("https://example2.com/funny_cat.png")},
+ nullptr));
+ EXPECT_FALSE(requests[0]->can_populate_body());
+
+ controller->AbortFromDelegate(
+ blink::mojom::BackgroundFetchFailureReason::DOWNLOAD_TOTAL_EXCEEDED);
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(JobCompletionStatus::kAborted,
+ GetCompletionStatus(registration_id));
+ EXPECT_EQ(finished_requests_[registration_id],
+ blink::mojom::BackgroundFetchFailureReason::FETCH_ERROR);
+}
+
TEST_F(BackgroundFetchJobControllerTest, Progress) {
BackgroundFetchRegistrationId registration_id;

View File

@@ -0,0 +1,119 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zakhar Voit <voit@google.com>
Date: Wed, 29 Sep 2021 14:24:18 +0000
Subject: Check whether the SW ID is valid for GetIds().
M90-LTS merge conflicts solved by using origin instead of storage key
because the storage key migration happened after M90.
(cherry picked from commit d97b8b86be732448cbc57b47f6b46547c9866df3)
Bug: 1243622
Change-Id: I93a40db0e71c7a087d279653e741800015232d7f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3135479
Reviewed-by: Richard Knoll <knollr@chromium.org>
Commit-Queue: Rayan Kanso <rayankans@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#917314}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3190253
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Zakhar Voit <voit@google.com>
Cr-Commit-Position: refs/branch-heads/4430@{#1627}
Cr-Branched-From: e5ce7dc4f7518237b3d9bb93cccca35d25216cbe-refs/heads/master@{#857950}
diff --git a/content/browser/background_fetch/background_fetch_service_unittest.cc b/content/browser/background_fetch/background_fetch_service_unittest.cc
index 8e75e6f059f139fdcc8cbbd0fd448ce321609d51..49783567a33cf36262af665f1aa764ad54a116a8 100644
--- a/content/browser/background_fetch/background_fetch_service_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_service_unittest.cc
@@ -1089,12 +1089,8 @@ TEST_F(BackgroundFetchServiceTest, GetDeveloperIds) {
std::vector<std::string> developer_ids;
GetDeveloperIds(service_worker_registration_id, &error, &developer_ids);
- ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
-
- // TODO(crbug.com/850076): The Storage Worker Database access is not
- // checking the origin. In a non-test environment this won't happen since a
- // ServiceWorker registration ID is tied to the origin.
- ASSERT_EQ(developer_ids.size(), 2u);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ EXPECT_TRUE(developer_ids.empty());
}
// Verify that using the wrong service worker id does not return developer ids
@@ -1108,9 +1104,8 @@ TEST_F(BackgroundFetchServiceTest, GetDeveloperIds) {
GetDeveloperIds(bogus_service_worker_registration_id, &error,
&developer_ids);
- ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
-
- ASSERT_EQ(developer_ids.size(), 0u);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ EXPECT_TRUE(developer_ids.empty());
}
}
diff --git a/content/browser/background_fetch/storage/get_developer_ids_task.cc b/content/browser/background_fetch/storage/get_developer_ids_task.cc
index 57114a79379a605105d10633e2658103cb5af2aa..53b9062c2d7da82b48d36d6d9eb8af01262b2dd0 100644
--- a/content/browser/background_fetch/storage/get_developer_ids_task.cc
+++ b/content/browser/background_fetch/storage/get_developer_ids_task.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "content/browser/background_fetch/storage/database_helpers.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_registration.h"
namespace content {
namespace background_fetch {
@@ -26,6 +27,28 @@ GetDeveloperIdsTask::GetDeveloperIdsTask(
GetDeveloperIdsTask::~GetDeveloperIdsTask() = default;
void GetDeveloperIdsTask::Start() {
+ service_worker_context()->FindReadyRegistrationForIdOnly(
+ service_worker_registration_id_,
+ base::BindOnce(&GetDeveloperIdsTask::DidGetServiceWorkerRegistration,
+ weak_factory_.GetWeakPtr()));
+}
+
+void GetDeveloperIdsTask::DidGetServiceWorkerRegistration(
+ blink::ServiceWorkerStatusCode status,
+ scoped_refptr<ServiceWorkerRegistration> registration) {
+ if (ToDatabaseStatus(status) != DatabaseStatus::kOk || !registration) {
+ SetStorageErrorAndFinish(
+ BackgroundFetchStorageError::kServiceWorkerStorageError);
+ return;
+ }
+
+ // TODO(crbug.com/1199077): Move this check into the SW context.
+ if (registration->origin() != origin_) {
+ SetStorageErrorAndFinish(
+ BackgroundFetchStorageError::kServiceWorkerStorageError);
+ return;
+ }
+
service_worker_context()->GetRegistrationUserKeysAndDataByKeyPrefix(
service_worker_registration_id_, {kActiveRegistrationUniqueIdKeyPrefix},
base::BindOnce(&GetDeveloperIdsTask::DidGetUniqueIds,
diff --git a/content/browser/background_fetch/storage/get_developer_ids_task.h b/content/browser/background_fetch/storage/get_developer_ids_task.h
index abdcda4b819ae5479d44f9cffcd93cb45c479841..ceef2219ba706aee0e8c355f97aec1c4e3e01fa2 100644
--- a/content/browser/background_fetch/storage/get_developer_ids_task.h
+++ b/content/browser/background_fetch/storage/get_developer_ids_task.h
@@ -16,6 +16,9 @@
#include "url/origin.h"
namespace content {
+
+class ServiceWorkerRegistration;
+
namespace background_fetch {
// Gets the developer ids for all active registrations - registrations that have
@@ -34,6 +37,9 @@ class GetDeveloperIdsTask : public DatabaseTask {
void Start() override;
private:
+ void DidGetServiceWorkerRegistration(
+ blink::ServiceWorkerStatusCode status,
+ scoped_refptr<ServiceWorkerRegistration> registration);
void DidGetUniqueIds(
blink::ServiceWorkerStatusCode status,
const base::flat_map<std::string, std::string>& data_map);

View File

@@ -0,0 +1,292 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Vladimir Levin <vmpstr@chromium.org>
Date: Tue, 14 Sep 2021 00:06:00 +0000
Subject: content-visibility: Add a clipper fix for content-visibility.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch adds a few checks in the svg painting code which may access
a content-visibility locked element via an svg reference.
R=fs@opera.com,jarhar@chromium.org
(cherry picked from commit e0d8a4f20bf98bbda2dc58199fca5caf0add1b00)
Bug: 1247196
Change-Id: I4dcb4ef298fb8d51aa0ec1a3b3bc130cfb560791
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3149811
Reviewed-by: Fredrik Söderquist <fs@opera.com>
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: vmpstr <vmpstr@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#920209}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3158958
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Auto-Submit: Joey Arhar <jarhar@chromium.org>
Reviewed-by: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/branch-heads/4606@{#1011}
Cr-Branched-From: 35b0d5a9dc8362adfd44e2614f0d5b7402ef63d0-refs/heads/master@{#911515}
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_container_test.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_container_test.cc
index 57e3540f9dc9419261ed7be84bd951df75380009..a625a03d0cc3e120e26f104d564db10ef78601e4 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_container_test.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_container_test.cc
@@ -117,4 +117,34 @@ TEST_F(LayoutSVGContainerTest,
EXPECT_TRUE(use->SlowFirstChild()->TransformAffectsVectorEffect());
}
+TEST_F(LayoutSVGContainerTest, PatternWithContentVisibility) {
+ SetBodyInnerHTML(R"HTML(
+ <svg viewBox="0 0 230 100" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <pattern id="pattern" viewBox="0,0,10,10" width="10%" height="10%">
+ <polygon id="polygon" points="0,0 2,5 0,10 5,8 10,10 8,5 10,0 5,2"/>
+ </pattern>
+ </defs>
+
+ <circle id="circle" cx="50" cy="50" r="50" fill="url(#pattern)"/>
+ </svg>
+ )HTML");
+
+ auto* pattern = GetDocument().getElementById("pattern");
+ auto* polygon = GetDocument().getElementById("polygon");
+
+ pattern->setAttribute("style", "contain: strict; content-visibility: hidden");
+
+ UpdateAllLifecyclePhasesForTest();
+
+ polygon->setAttribute("points", "0,0 2,5 0,10");
+
+ // This shouldn't cause a DCHECK, even though the pattern needs layout because
+ // it's under a content-visibility: hidden subtree.
+ UpdateAllLifecyclePhasesForTest();
+
+ EXPECT_TRUE(pattern->GetLayoutObject()->NeedsLayout());
+ EXPECT_FALSE(pattern->GetLayoutObject()->SelfNeedsLayout());
+}
+
} // namespace blink
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
index f00325cb831e7037a7c61e8e185c73d6a09cb34c..d3d6fa311d3e22b5d9256d2d737d33f770ce4f4f 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
@@ -54,6 +55,8 @@ ClipStrategy DetermineClipStrategy(const SVGGraphicsElement& element) {
const LayoutObject* layout_object = element.GetLayoutObject();
if (!layout_object)
return ClipStrategy::kNone;
+ if (DisplayLockUtilities::LockedAncestorPreventingLayout(*layout_object))
+ return ClipStrategy::kNone;
const ComputedStyle& style = layout_object->StyleRef();
if (style.Display() == EDisplay::kNone ||
style.Visibility() != EVisibility::kVisible)
@@ -74,8 +77,12 @@ ClipStrategy DetermineClipStrategy(const SVGElement& element) {
// (https://drafts.fxtf.org/css-masking/#ClipPathElement)
if (auto* svg_use_element = DynamicTo<SVGUseElement>(element)) {
const LayoutObject* use_layout_object = element.GetLayoutObject();
- if (!use_layout_object ||
- use_layout_object->StyleRef().Display() == EDisplay::kNone)
+ if (!use_layout_object)
+ return ClipStrategy::kNone;
+ if (DisplayLockUtilities::LockedAncestorPreventingLayout(
+ *use_layout_object))
+ return ClipStrategy::kNone;
+ if (use_layout_object->StyleRef().Display() == EDisplay::kNone)
return ClipStrategy::kNone;
const SVGGraphicsElement* shape_element =
svg_use_element->VisibleTargetGraphicsElementForClipping();
@@ -271,7 +278,7 @@ bool LayoutSVGResourceClipper::HitTestClipContent(
FloatRect LayoutSVGResourceClipper::ResourceBoundingBox(
const FloatRect& reference_box) {
NOT_DESTROYED();
- DCHECK(!NeedsLayout());
+ DCHECK(!SelfNeedsLayout());
if (local_clip_bounds_.IsEmpty())
CalculateLocalClipBounds();
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc
index d20bb36c00b84e200e518d2282a9db69072ca5f0..0b598d713f03e574dbd390225e81781b86e53d5e 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc
@@ -19,6 +19,7 @@
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
#include "third_party/blink/renderer/core/paint/svg_object_painter.h"
@@ -65,7 +66,9 @@ sk_sp<const PaintRecord> LayoutSVGResourceMasker::CreatePaintRecord(
for (const SVGElement& child_element :
Traversal<SVGElement>::ChildrenOf(*GetElement())) {
const LayoutObject* layout_object = child_element.GetLayoutObject();
- if (!layout_object ||
+ if (!layout_object)
+ continue;
+ if (DisplayLockUtilities::LockedAncestorPreventingLayout(*layout_object) ||
layout_object->StyleRef().Display() == EDisplay::kNone)
continue;
SVGObjectPainter(*layout_object).PaintResourceSubtree(builder.Context());
@@ -91,7 +94,7 @@ FloatRect LayoutSVGResourceMasker::ResourceBoundingBox(
const FloatRect& reference_box,
float reference_box_zoom) {
NOT_DESTROYED();
- DCHECK(!NeedsLayout());
+ DCHECK(!SelfNeedsLayout());
auto* mask_element = To<SVGMaskElement>(GetElement());
DCHECK(mask_element);
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
index 1b9f67bc9e186654bfd03410b8e2d73654a7f1e2..c246bcd5a1d524302586cd145f39a1a2b47adef8 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
@@ -24,6 +24,7 @@
#include <memory>
#include "base/memory/ptr_util.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
#include "third_party/blink/renderer/core/paint/svg_object_painter.h"
@@ -205,8 +206,20 @@ sk_sp<PaintRecord> LayoutSVGResourcePattern::AsPaintRecord(
content_transform = tile_transform;
FloatRect bounds(FloatPoint(), size);
+ PaintRecorder paint_recorder;
+ cc::PaintCanvas* canvas = paint_recorder.beginRecording(bounds);
+
+ auto* pattern_content_element = Attributes().PatternContentElement();
+ DCHECK(pattern_content_element);
+ // If the element or some of its ancestor prevents us from doing paint, we can
+ // early out. Note that any locked ancestor would prevent paint.
+ if (DisplayLockUtilities::NearestLockedInclusiveAncestor(
+ *pattern_content_element)) {
+ return paint_recorder.finishRecordingAsPicture();
+ }
+
const auto* pattern_layout_object = To<LayoutSVGResourceContainer>(
- Attributes().PatternContentElement()->GetLayoutObject());
+ pattern_content_element->GetLayoutObject());
DCHECK(pattern_layout_object);
DCHECK(!pattern_layout_object->NeedsLayout());
@@ -216,8 +229,6 @@ sk_sp<PaintRecord> LayoutSVGResourcePattern::AsPaintRecord(
for (LayoutObject* child = pattern_layout_object->FirstChild(); child;
child = child->NextSibling())
SVGObjectPainter(*child).PaintResourceSubtree(builder.Context());
- PaintRecorder paint_recorder;
- cc::PaintCanvas* canvas = paint_recorder.beginRecording(bounds);
canvas->save();
canvas->concat(AffineTransformToSkMatrix(tile_transform));
builder.EndRecording(*canvas);
diff --git a/third_party/blink/renderer/core/paint/clip_path_clipper.cc b/third_party/blink/renderer/core/paint/clip_path_clipper.cc
index 66b6d44961aa7e2b534dcd402d9e9eede4447b52..7a7fa937d96641284ebbfc8b083965d7eb6e287d 100644
--- a/third_party/blink/renderer/core/paint/clip_path_clipper.cc
+++ b/third_party/blink/renderer/core/paint/clip_path_clipper.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/paint/clip_path_clipper.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
@@ -42,10 +43,14 @@ LayoutSVGResourceClipper* ResolveElementReference(
return nullptr;
LayoutSVGResourceClipper* resource_clipper =
GetSVGResourceAsType(*client, reference_clip_path_operation);
- if (resource_clipper) {
- SECURITY_DCHECK(!resource_clipper->NeedsLayout());
- resource_clipper->ClearInvalidationMask();
- }
+ if (!resource_clipper)
+ return nullptr;
+
+ resource_clipper->ClearInvalidationMask();
+ if (DisplayLockUtilities::LockedAncestorPreventingLayout(*resource_clipper))
+ return nullptr;
+
+ SECURITY_DCHECK(!resource_clipper->SelfNeedsLayout());
return resource_clipper;
}
diff --git a/third_party/blink/renderer/core/paint/svg_mask_painter.cc b/third_party/blink/renderer/core/paint/svg_mask_painter.cc
index d049d3e18eed09ed4755ef483e9cd4b60925232c..2d40adb1ff99f3d29dce027995871cba399af3fb 100644
--- a/third_party/blink/renderer/core/paint/svg_mask_painter.cc
+++ b/third_party/blink/renderer/core/paint/svg_mask_painter.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/paint/svg_mask_painter.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
#include "third_party/blink/renderer/core/paint/object_paint_properties.h"
@@ -46,7 +47,9 @@ void SVGMaskPainter::Paint(GraphicsContext& context,
auto* masker = GetSVGResourceAsType<LayoutSVGResourceMasker>(
*client, svg_style.MaskerResource());
DCHECK(masker);
- SECURITY_DCHECK(!masker->NeedsLayout());
+ if (DisplayLockUtilities::LockedAncestorPreventingLayout(*masker))
+ return;
+ SECURITY_DCHECK(!masker->SelfNeedsLayout());
masker->ClearInvalidationMask();
FloatRect reference_box = SVGResources::ReferenceBoxForEffects(layout_object);
diff --git a/third_party/blink/renderer/core/paint/svg_object_painter.cc b/third_party/blink/renderer/core/paint/svg_object_painter.cc
index 8454ad348bd7d3daf8e24a0e8e7360c0888ca0e6..56d8732423028bf9850ee2b640dd335de5f2c67a 100644
--- a/third_party/blink/renderer/core/paint/svg_object_painter.cc
+++ b/third_party/blink/renderer/core/paint/svg_object_painter.cc
@@ -31,7 +31,7 @@ void CopyStateFromGraphicsContext(GraphicsContext& context, PaintFlags& flags) {
} // namespace
void SVGObjectPainter::PaintResourceSubtree(GraphicsContext& context) {
- DCHECK(!layout_object_.NeedsLayout());
+ DCHECK(!layout_object_.SelfNeedsLayout());
PaintInfo info(context, LayoutRect::InfiniteIntRect(),
PaintPhase::kForeground,
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-in-svg-000-crash.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-in-svg-000-crash.html
new file mode 100644
index 0000000000000000000000000000000000000000..d1084f7216510386f159033e2f7b0e3966bd2758
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-in-svg-000-crash.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://crbug.com/1247196">
+<meta name="assert" content="Clip path with content-visibility does not cause an assert">
+
+<svg width="138">
+ <defs>
+ <clipPath id="snowglobe_clipPath">
+ <circle cx="34" />
+ </clipPath>
+ </defs>
+ <circle />
+ <g class="group-snow" clip-path="url(#snowglobe_clipPath)">
+ <g class="snowContainer">
+ <circle class="snow" />
+ </g>
+ </g>
+</svg>
+<script type="text/javascript">
+onload = () => {
+ var test0 = document.getElementById("snowglobe_clipPath");
+ test0.style.setProperty("content-visibility", "auto ", "important");
+ test0.innerHTML = "";
+ test0.offsetHeight;
+
+ requestAnimationFrame(() => document.documentElement.classList.remove('test-wait'));
+};
+</script>
+</html>

View File

@@ -0,0 +1,119 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Vladimir Levin <vmpstr@chromium.org>
Date: Tue, 7 Sep 2021 21:32:03 +0000
Subject: content-visibility: Force range base/extent when computing visual
selection.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some of the code that does visual selection ends up updating style and
layout for node. This means that it will temporarily unlock c-v nodes
and may cause a state rewind from layout clean to visual update pending.
That's not an operation we support, verified by DCHECKs. So, instead
we should unlock any c-v nodes prior to getting to layout clean.
R=chrishtr@chromium.org, yosin@chromium.org
(cherry picked from commit 484bc1abffcdee33648695244c86daca15ab6539)
Bug: 1237533
Change-Id: Ib30036c4536bea3da2ae4fa54c19ad5684829597
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3114230
Commit-Queue: Yoshifumi Inoue <yosin@chromium.org>
Reviewed-by: Chris Harrelson <chrishtr@chromium.org>
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#914631}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3145452
Auto-Submit: vmpstr <vmpstr@chromium.org>
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/branch-heads/4515@{#2115}
Cr-Branched-From: 488fc70865ddaa05324ac00a54a6eb783b4bc41c-refs/heads/master@{#885287}
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
index bebc5dbeb82cdbe5803b547686b246229d9b41b8..1106cb73f0ffe789c48d2048006771effa0f01ae 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
@@ -173,6 +173,9 @@ DisplayLockUtilities::ScopedForcedUpdate::Impl::Impl(const Node* node,
if (!RuntimeEnabledFeatures::CSSContentVisibilityEnabled())
return;
+ if (!node_)
+ return;
+
auto* owner_node = GetFrameOwnerNode(node);
if (owner_node)
parent_frame_impl_ = MakeGarbageCollected<Impl>(owner_node, true);
@@ -215,6 +218,8 @@ DisplayLockUtilities::ScopedForcedUpdate::Impl::Impl(const Node* node,
}
void DisplayLockUtilities::ScopedForcedUpdate::Impl::Destroy() {
+ if (!node_)
+ return;
if (RuntimeEnabledFeatures::CSSContentVisibilityEnabled())
node_->GetDocument().GetDisplayLockDocumentState().EndNodeForcedScope(this);
if (parent_frame_impl_)
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities.h b/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
index 6e6839e2c1222a6f05d89dca97e7513989476165..022ac073ca6eb92023014933f2f1d12d774f8a30 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
+++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
+#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
@@ -51,6 +52,8 @@ class CORE_EXPORT DisplayLockUtilities {
friend void Document::EnsurePaintLocationDataValidForNode(
const Node* node,
DocumentUpdateReason reason);
+ friend VisibleSelection
+ FrameSelection::ComputeVisibleSelectionInDOMTreeDeprecated() const;
friend class DisplayLockContext;
diff --git a/third_party/blink/renderer/core/editing/frame_selection.cc b/third_party/blink/renderer/core/editing/frame_selection.cc
index d0133cc8da39300c4fc3b5ae225afd9e3aeceeca..f59557caeb9fa1bc460e199a7dae8d218d27c089 100644
--- a/third_party/blink/renderer/core/editing/frame_selection.cc
+++ b/third_party/blink/renderer/core/editing/frame_selection.cc
@@ -158,6 +158,10 @@ VisibleSelection FrameSelection::ComputeVisibleSelectionInDOMTreeDeprecated()
const {
// TODO(editing-dev): Hoist UpdateStyleAndLayout
// to caller. See http://crbug.com/590369 for more details.
+ DisplayLockUtilities::ScopedForcedUpdate base_scope(
+ GetSelectionInDOMTree().Base().AnchorNode());
+ DisplayLockUtilities::ScopedForcedUpdate extent_scope(
+ GetSelectionInDOMTree().Extent().AnchorNode());
GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kSelection);
return ComputeVisibleSelectionInDOMTree();
}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/meter-selection-crash.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/meter-selection-crash.html
new file mode 100644
index 0000000000000000000000000000000000000000..9edca97568e288c0231ac942eeadfe397ea9e00f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/meter-selection-crash.html
@@ -0,0 +1,21 @@
+<!doctype HTML>
+<link rel=author href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
+<meta name="assert" content="meter, iframe, and selection API should not crash">
+
+<style>
+* {
+ all: initial;
+ content-visibility: hidden;
+}
+</style>
+
+<meter></meter><iframe id="frame"></iframe>
+<script>
+function runTest() {
+ var range_beadc = window.getSelection();
+ var elem1 = document.getElementById("frame");
+ range_beadc.setBaseAndExtent(elem1, 0, document.getElementById("none"), 0);
+}
+onload = runTest;
+</script>

View File

@@ -0,0 +1,214 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rayan Kanso <rayankans@google.com>
Date: Thu, 9 Sep 2021 11:16:13 +0000
Subject: Add Origin checks to mojo methods.
(cherry picked from commit 6ef569fd764a8e5f8fba4dcff830d460e406362b)
Bug: 1244568
Change-Id: I5a63a2e478577913a3b35154464c1808f7291f40
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3140385
Reviewed-by: Richard Knoll <knollr@chromium.org>
Commit-Queue: Rayan Kanso <rayankans@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#918606}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3149996
Reviewed-by: Michael van Ouwerkerk <mvanouwerkerk@chromium.org>
Cr-Commit-Position: refs/branch-heads/4577@{#1220}
Cr-Branched-From: 761ddde228655e313424edec06497d0c56b0f3c4-refs/heads/master@{#902210}
diff --git a/content/browser/content_index/content_index_database.cc b/content/browser/content_index/content_index_database.cc
index 2ce59c40e2d8e319b68d9df61a496606f4bf5bb6..438798fe658bf148c09a9bcf65c3b40dbf96325e 100644
--- a/content/browser/content_index/content_index_database.cc
+++ b/content/browser/content_index/content_index_database.cc
@@ -183,6 +183,11 @@ void ContentIndexDatabase::AddEntryOnCoreThread(
return;
}
+ if (!service_worker_registration->origin().IsSameOriginWith(origin)) {
+ std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR);
+ return;
+ }
+
auto serialized_icons = std::make_unique<proto::SerializedIcons>();
proto::SerializedIcons* serialized_icons_ptr = serialized_icons.get();
@@ -284,6 +289,15 @@ void ContentIndexDatabase::DeleteEntryOnCoreThread(
blink::mojom::ContentIndexService::DeleteCallback callback) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
+ scoped_refptr<ServiceWorkerRegistration> service_worker_registration =
+ service_worker_context_->GetLiveRegistration(
+ service_worker_registration_id);
+ if (!service_worker_registration ||
+ !service_worker_registration->origin().IsSameOriginWith(origin)) {
+ std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR);
+ return;
+ }
+
service_worker_context_->ClearRegistrationUserData(
service_worker_registration_id, {EntryKey(entry_id), IconsKey(entry_id)},
base::BindOnce(&ContentIndexDatabase::DidDeleteEntry,
@@ -316,6 +330,7 @@ void ContentIndexDatabase::DidDeleteEntry(
void ContentIndexDatabase::GetDescriptions(
int64_t service_worker_registration_id,
+ const url::Origin& origin,
blink::mojom::ContentIndexService::GetDescriptionsCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -333,15 +348,26 @@ void ContentIndexDatabase::GetDescriptions(
FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
base::BindOnce(&ContentIndexDatabase::GetDescriptionsOnCoreThread,
weak_ptr_factory_core_.GetWeakPtr(),
- service_worker_registration_id,
+ service_worker_registration_id, origin,
std::move(wrapped_callback)));
}
void ContentIndexDatabase::GetDescriptionsOnCoreThread(
int64_t service_worker_registration_id,
+ const url::Origin& origin,
blink::mojom::ContentIndexService::GetDescriptionsCallback callback) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
+ scoped_refptr<ServiceWorkerRegistration> service_worker_registration =
+ service_worker_context_->GetLiveRegistration(
+ service_worker_registration_id);
+ if (!service_worker_registration ||
+ !service_worker_registration->origin().IsSameOriginWith(origin)) {
+ std::move(callback).Run(blink::mojom::ContentIndexError::STORAGE_ERROR,
+ /* descriptions= */ {});
+ return;
+ }
+
service_worker_context_->GetRegistrationUserDataByKeyPrefix(
service_worker_registration_id, kEntryPrefix,
base::BindOnce(&ContentIndexDatabase::DidGetDescriptions,
diff --git a/content/browser/content_index/content_index_database.h b/content/browser/content_index/content_index_database.h
index 89c23e8d3595a114c3a24530c8afd1e3a67b79a3..86a7830a72b25fc4a76575138e29284a2debba52 100644
--- a/content/browser/content_index/content_index_database.h
+++ b/content/browser/content_index/content_index_database.h
@@ -51,6 +51,7 @@ class CONTENT_EXPORT ContentIndexDatabase {
void GetDescriptions(
int64_t service_worker_registration_id,
+ const url::Origin& origin,
blink::mojom::ContentIndexService::GetDescriptionsCallback callback);
// Gets the icon for |description_id| and invokes |callback| on the UI
@@ -95,6 +96,7 @@ class CONTENT_EXPORT ContentIndexDatabase {
blink::mojom::ContentIndexService::DeleteCallback callback);
void GetDescriptionsOnCoreThread(
int64_t service_worker_registration_id,
+ const url::Origin& origin,
blink::mojom::ContentIndexService::GetDescriptionsCallback callback);
void GetIconsOnCoreThread(int64_t service_worker_registration_id,
const std::string& description_id,
diff --git a/content/browser/content_index/content_index_database_unittest.cc b/content/browser/content_index/content_index_database_unittest.cc
index 3787ffbff591410f90065b78fd5c177567e335b3..4058a334ee229c0e2bf58e78f3884e6ad910eb7e 100644
--- a/content/browser/content_index/content_index_database_unittest.cc
+++ b/content/browser/content_index/content_index_database_unittest.cc
@@ -114,7 +114,7 @@ class ContentIndexDatabaseTest : public ::testing::Test {
void SetUp() override {
// Register Service Worker.
- service_worker_registration_id_ = RegisterServiceWorker();
+ service_worker_registration_id_ = RegisterServiceWorker(origin_);
ASSERT_NE(service_worker_registration_id_,
blink::mojom::kInvalidServiceWorkerRegistrationId);
database_ = std::make_unique<ContentIndexDatabase>(
@@ -164,7 +164,7 @@ class ContentIndexDatabaseTest : public ::testing::Test {
base::RunLoop run_loop;
std::vector<blink::mojom::ContentDescriptionPtr> descriptions;
database_->GetDescriptions(
- service_worker_registration_id_,
+ service_worker_registration_id_, origin_,
base::BindOnce(&GetDescriptionsCallback, run_loop.QuitClosure(),
out_error, &descriptions));
run_loop.Run();
@@ -222,6 +222,11 @@ class ContentIndexDatabaseTest : public ::testing::Test {
return service_worker_registration_id_;
}
+ void set_service_worker_registration_id(
+ int64_t service_worker_registration_id) {
+ service_worker_registration_id_ = service_worker_registration_id;
+ }
+
ContentIndexDatabase* database() { return database_.get(); }
BrowserTaskEnvironment& task_environment() { return task_environment_; }
@@ -230,15 +235,14 @@ class ContentIndexDatabaseTest : public ::testing::Test {
GURL launch_url() { return origin_.GetURL(); }
- private:
- int64_t RegisterServiceWorker() {
- GURL script_url(origin_.GetURL().spec() + "sw.js");
+ int64_t RegisterServiceWorker(const url::Origin& origin) {
+ GURL script_url(origin.GetURL().spec() + "sw.js");
int64_t service_worker_registration_id =
blink::mojom::kInvalidServiceWorkerRegistrationId;
{
blink::mojom::ServiceWorkerRegistrationOptions options;
- options.scope = origin_.GetURL();
+ options.scope = origin.GetURL();
base::RunLoop run_loop;
embedded_worker_test_helper_.context()->RegisterServiceWorker(
script_url, options, blink::mojom::FetchClientSettingsObject::New(),
@@ -258,7 +262,7 @@ class ContentIndexDatabaseTest : public ::testing::Test {
{
base::RunLoop run_loop;
embedded_worker_test_helper_.context()->registry()->FindRegistrationForId(
- service_worker_registration_id, origin_,
+ service_worker_registration_id, origin,
base::BindOnce(&DidFindServiceWorkerRegistration,
&service_worker_registration_,
run_loop.QuitClosure()));
@@ -276,6 +280,7 @@ class ContentIndexDatabaseTest : public ::testing::Test {
return service_worker_registration_id;
}
+ private:
BrowserTaskEnvironment task_environment_; // Must be first member.
ContentIndexTestBrowserContext browser_context_;
url::Origin origin_ = url::Origin::Create(GURL("https://example.com"));
@@ -314,6 +319,24 @@ TEST_F(ContentIndexDatabaseTest, DatabaseOperations) {
EXPECT_TRUE(descriptions[0]->Equals(*expected_description));
}
+TEST_F(ContentIndexDatabaseTest, DatabaseOperationsBadSWID) {
+ url::Origin other_origin = url::Origin::Create(GURL("https://other.com"));
+ int64_t other_service_worker_registration_id =
+ RegisterServiceWorker(other_origin);
+ ASSERT_NE(other_service_worker_registration_id,
+ blink::mojom::kInvalidServiceWorkerRegistrationId);
+ set_service_worker_registration_id(other_service_worker_registration_id);
+
+ blink::mojom::ContentIndexError error;
+ auto descriptions = GetDescriptions(&error);
+ EXPECT_TRUE(descriptions.empty());
+ EXPECT_EQ(error, blink::mojom::ContentIndexError::STORAGE_ERROR);
+
+ EXPECT_EQ(AddEntry(CreateDescription("id1")),
+ blink::mojom::ContentIndexError::STORAGE_ERROR);
+ EXPECT_EQ(DeleteEntry("id2"), blink::mojom::ContentIndexError::STORAGE_ERROR);
+}
+
TEST_F(ContentIndexDatabaseTest, AddDuplicateIdWillOverwrite) {
auto description1 = CreateDescription("id");
description1->title = "title1";
diff --git a/content/browser/content_index/content_index_service_impl.cc b/content/browser/content_index/content_index_service_impl.cc
index 81135e8b431d87ee371c0ca8912ee5dc93adfc17..73d54a16bb759156eb2869d2e8a6293f9cf0de0a 100644
--- a/content/browser/content_index/content_index_service_impl.cc
+++ b/content/browser/content_index/content_index_service_impl.cc
@@ -153,7 +153,7 @@ void ContentIndexServiceImpl::GetDescriptions(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content_index_context_->database().GetDescriptions(
- service_worker_registration_id, std::move(callback));
+ service_worker_registration_id, origin_, std::move(callback));
}
} // namespace content

View File

@@ -0,0 +1,72 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jorge Lucangeli Obes <jorgelo@chromium.org>
Date: Wed, 22 Sep 2021 20:27:54 +0000
Subject: Kill a renderer if it provides an unexpected FrameOwnerElementType
(Merge to M93.)
Portals and MPArch based Fenced Frames are not created as normal
subframes.
(cherry picked from commit beebc8aec0f8f9e627e69ad67ef311903924b384)
Bug: 1251727
Change-Id: I81326d2caf2038aec2f77cf577161a24bb9b65b2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3174272
Commit-Queue: Kevin McNee <mcnee@chromium.org>
Commit-Queue: Adrian Taylor <adetaylor@chromium.org>
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#923644}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3174713
Auto-Submit: Jorge Lucangeli Obes <jorgelo@chromium.org>
Reviewed-by: Dominic Farolino <dom@chromium.org>
Reviewed-by: Kevin McNee <mcnee@chromium.org>
Commit-Queue: Jorge Lucangeli Obes <jorgelo@chromium.org>
Cr-Commit-Position: refs/branch-heads/4577@{#1266}
Cr-Branched-From: 761ddde228655e313424edec06497d0c56b0f3c4-refs/heads/master@{#902210}
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h
index e198d661c711dc648a4e4c2249e0a60f69c406da..d1821c863d998cb010d8f5d12c12d79b18075a9d 100644
--- a/content/browser/bad_message.h
+++ b/content/browser/bad_message.h
@@ -269,6 +269,8 @@ enum BadMessageReason {
PAYMENTS_WITHOUT_PERMISSION = 241,
WEB_BUNDLE_INVALID_NAVIGATION_URL = 242,
WCI_INVALID_DOWNLOAD_IMAGE_RESULT = 243,
+ FARI_LOGOUT_BAD_ENDPOINT = 250,
+ RFH_CHILD_FRAME_UNEXPECTED_OWNER_ELEMENT_TYPE = 251,
// Please add new elements here. The naming convention is abbreviated class
// name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 385080e04ed3fb6b82a1ed993889913546f0ba20..85f18081e82e730edd2883e5f75fe35179f8ac82 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -2629,6 +2629,14 @@ void RenderFrameHostImpl::OnCreateChildFrame(
// is invalid.
bad_message::ReceivedBadMessage(
GetProcess(), bad_message::RFH_CHILD_FRAME_NEEDS_OWNER_ELEMENT_TYPE);
+ return;
+ }
+ if (owner_type == blink::mojom::FrameOwnerElementType::kPortal) {
+ // Portals are not created through this child frame code path.
+ bad_message::ReceivedBadMessage(
+ GetProcess(),
+ bad_message::RFH_CHILD_FRAME_UNEXPECTED_OWNER_ELEMENT_TYPE);
+ return;
}
DCHECK(frame_token);
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 37c0027b6581d498413acb114cfc8ac05d3ff52e..0cb62e228ba2497276b40ba272e9ac52255ecb63 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -6796,6 +6796,8 @@ Called by update_bad_message_reasons.py.-->
<int value="238" label="CSDH_BAD_OWNER"/>
<int value="239" label="SYNC_COMPOSITOR_NO_LOCAL_SURFACE_ID"/>
<int value="240" label="WCI_INVALID_FULLSCREEN_OPTIONS"/>
+ <int value="250" label="FARI_LOGOUT_BAD_ENDPOINT"/>
+ <int value="251" label="RFH_CHILD_FRAME_UNEXPECTED_OWNER_ELEMENT_TYPE"/>
</enum>
<enum name="BadMessageReasonExtensions">

View File

@@ -0,0 +1,65 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Austin Sullivan <asully@chromium.org>
Date: Wed, 29 Sep 2021 08:20:51 +0000
Subject: FSA: Fix race condition in manager
(cherry picked from commit 951339b41022b08a67ad94ba5960b05c84bf4cf2)
Bug: 1248030
Change-Id: I1ea819d1d6ac63ec8f400a45c893da49596235ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3154425
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Auto-Submit: Austin Sullivan <asully@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#920376}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3182123
Reviewed-by: Austin Sullivan <asully@chromium.org>
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Owners-Override: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com>
Cr-Commit-Position: refs/branch-heads/4430@{#1624}
Cr-Branched-From: e5ce7dc4f7518237b3d9bb93cccca35d25216cbe-refs/heads/master@{#857950}
diff --git a/content/browser/file_system_access/native_file_system_manager_impl.cc b/content/browser/file_system_access/native_file_system_manager_impl.cc
index 060855d387ad18daf23015c52642742e128e49e8..0c1347fdad9db0bea27bd9db509d2f1b476e4272 100644
--- a/content/browser/file_system_access/native_file_system_manager_impl.cc
+++ b/content/browser/file_system_access/native_file_system_manager_impl.cc
@@ -357,6 +357,11 @@ void NativeFileSystemManagerImpl::ChooseEntries(
base::SequencedTaskRunnerHandle::Get()));
}
+void NativeFileSystemManagerImpl::Shutdown() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ permission_context_ = nullptr;
+}
+
void NativeFileSystemManagerImpl::SetDefaultPathAndShowPicker(
const BindingContext& context,
blink::mojom::ChooseFileSystemEntryType type,
diff --git a/content/browser/file_system_access/native_file_system_manager_impl.h b/content/browser/file_system_access/native_file_system_manager_impl.h
index 2a0085c06ef869f741be1a0821d79dbb71f7794a..313c6ed9f9e11e63869ba003f5a04ad17065593d 100644
--- a/content/browser/file_system_access/native_file_system_manager_impl.h
+++ b/content/browser/file_system_access/native_file_system_manager_impl.h
@@ -259,6 +259,8 @@ class CONTENT_EXPORT NativeFileSystemManagerImpl
PathType path_type,
const base::FilePath& path);
+ void Shutdown();
+
private:
friend class NativeFileSystemFileHandleImpl;
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index c28ce91036fb99fbcd08d2a64c6b67f79f57b0d8..8eaf276f741482e5000110b11f965c6451ab6ef1 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -1086,6 +1086,10 @@ StoragePartitionImpl::~StoragePartitionImpl() {
GetDatabaseTracker()));
}
+ if (GetNativeFileSystemManager()) {
+ GetNativeFileSystemManager()->Shutdown();
+ }
+
if (GetFileSystemContext())
GetFileSystemContext()->Shutdown();

View File

@@ -0,0 +1,290 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marijn Kruisselbrink <mek@chromium.org>
Date: Fri, 10 Sep 2021 21:31:17 +0000
Subject: M93: [IndexedDB] Add browser-side checks for committing transactions.
No new IPCs should come in for a transaction after it starts committing.
This CL adds browser-side checks in addition to the existing
renderer-side checks for this.
(cherry picked from commit ec3ddd67bae4c491ec1faba7be7cc988c425506c)
Bug: 1247766
Change-Id: If9d69d5a0320bfd3b615446710358dd439074795
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3149409
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Reviewed-by: Joshua Bell <jsbell@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#919898}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3154684
Auto-Submit: Victor Costan <pwnall@chromium.org>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4577@{#1234}
Cr-Branched-From: 761ddde228655e313424edec06497d0c56b0f3c4-refs/heads/master@{#902210}
diff --git a/content/browser/indexed_db/database_impl.cc b/content/browser/indexed_db/database_impl.cc
index 1bfbd8263fafc4cb727a01fdcf8dbd093c5bff4e..004b6e587b8525b8a0d1a91857a128c982273e23 100644
--- a/content/browser/indexed_db/database_impl.cc
+++ b/content/browser/indexed_db/database_impl.cc
@@ -86,6 +86,13 @@ void DatabaseImpl::RenameObjectStore(int64_t transaction_id,
return;
}
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "RenameObjectStore was called after committing or aborting the "
+ "transaction");
+ return;
+ }
+
transaction->ScheduleTask(
blink::mojom::IDBTaskType::Preemptive,
BindWeakOperation(&IndexedDBDatabase::RenameObjectStoreOperation,
@@ -203,6 +210,12 @@ void DatabaseImpl::Get(int64_t transaction_id,
return;
}
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "Get was called after committing or aborting the transaction");
+ return;
+ }
+
blink::mojom::IDBDatabase::GetCallback aborting_callback =
CreateCallbackAbortOnDestruct<blink::mojom::IDBDatabase::GetCallback,
blink::mojom::IDBDatabaseGetResultPtr>(
@@ -253,6 +266,12 @@ void DatabaseImpl::GetAll(int64_t transaction_id,
return;
}
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "GetAll was called after committing or aborting the transaction");
+ return;
+ }
+
// Hypothetically, this could pass the receiver to the callback immediately.
// However, for result ordering issues, we need to PostTask to mimic
// all of the other operations.
@@ -292,6 +311,12 @@ void DatabaseImpl::SetIndexKeys(
return;
}
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "SetIndexKeys was called after committing or aborting the transaction");
+ return;
+ }
+
transaction->ScheduleTask(
blink::mojom::IDBTaskType::Preemptive,
BindWeakOperation(&IndexedDBDatabase::SetIndexKeysOperation,
@@ -318,6 +343,13 @@ void DatabaseImpl::SetIndexesReady(int64_t transaction_id,
return;
}
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "SetIndexesReady was called after committing or aborting the "
+ "transaction");
+ return;
+ }
+
transaction->ScheduleTask(
blink::mojom::IDBTaskType::Preemptive,
BindWeakOperation(&IndexedDBDatabase::SetIndexesReadyOperation,
@@ -355,6 +387,12 @@ void DatabaseImpl::OpenCursor(
return;
}
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "OpenCursor was called after committing or aborting the transaction");
+ return;
+ }
+
blink::mojom::IDBDatabase::OpenCursorCallback aborting_callback =
CreateCallbackAbortOnDestruct<
blink::mojom::IDBDatabase::OpenCursorCallback,
@@ -404,6 +442,12 @@ void DatabaseImpl::Count(
if (!transaction)
return;
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "Count was called after committing or aborting the transaction");
+ return;
+ }
+
transaction->ScheduleTask(BindWeakOperation(
&IndexedDBDatabase::CountOperation, connection_->database()->AsWeakPtr(),
object_store_id, index_id,
@@ -429,6 +473,12 @@ void DatabaseImpl::DeleteRange(
if (!transaction)
return;
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "DeleteRange was called after committing or aborting the transaction");
+ return;
+ }
+
transaction->ScheduleTask(BindWeakOperation(
&IndexedDBDatabase::DeleteRangeOperation,
connection_->database()->AsWeakPtr(), object_store_id,
@@ -452,6 +502,13 @@ void DatabaseImpl::GetKeyGeneratorCurrentNumber(
if (!transaction)
return;
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "GetKeyGeneratorCurrentNumber was called after committing or aborting "
+ "the transaction");
+ return;
+ }
+
transaction->ScheduleTask(BindWeakOperation(
&IndexedDBDatabase::GetKeyGeneratorCurrentNumberOperation,
connection_->database()->AsWeakPtr(), object_store_id,
@@ -475,6 +532,12 @@ void DatabaseImpl::Clear(
if (!transaction)
return;
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "Clear was called after committing or aborting the transaction");
+ return;
+ }
+
transaction->ScheduleTask(BindWeakOperation(
&IndexedDBDatabase::ClearOperation, connection_->database()->AsWeakPtr(),
object_store_id, std::move(callbacks)));
@@ -502,6 +565,12 @@ void DatabaseImpl::CreateIndex(int64_t transaction_id,
return;
}
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "CreateIndex was called after committing or aborting the transaction");
+ return;
+ }
+
transaction->ScheduleTask(
blink::mojom::IDBTaskType::Preemptive,
BindWeakOperation(&IndexedDBDatabase::CreateIndexOperation,
@@ -527,6 +596,12 @@ void DatabaseImpl::DeleteIndex(int64_t transaction_id,
return;
}
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "DeleteIndex was called after committing or aborting the transaction");
+ return;
+ }
+
transaction->ScheduleTask(BindWeakOperation(
&IndexedDBDatabase::DeleteIndexOperation,
connection_->database()->AsWeakPtr(), object_store_id, index_id));
@@ -551,6 +626,12 @@ void DatabaseImpl::RenameIndex(int64_t transaction_id,
return;
}
+ if (!transaction->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "RenameIndex was called after committing or aborting the transaction");
+ return;
+ }
+
transaction->ScheduleTask(
BindWeakOperation(&IndexedDBDatabase::RenameIndexOperation,
connection_->database()->AsWeakPtr(), object_store_id,
diff --git a/content/browser/indexed_db/indexed_db_transaction.h b/content/browser/indexed_db/indexed_db_transaction.h
index 10f708590aac7138db16631c56c716363ba5678f..bb73a18830ea0391fc5b89567f5ab78a682d85f7 100644
--- a/content/browser/indexed_db/indexed_db_transaction.h
+++ b/content/browser/indexed_db/indexed_db_transaction.h
@@ -69,6 +69,14 @@ class CONTENT_EXPORT IndexedDBTransaction {
// Signals the transaction for commit.
void SetCommitFlag();
+ // Returns false if the transaction has been signalled to commit, is in the
+ // process of committing, or finished committing or was aborted. Essentially
+ // when this returns false no tasks should be scheduled that try to modify
+ // the transaction.
+ bool IsAcceptingRequests() {
+ return !is_commit_pending_ && state_ != COMMITTING && state_ != FINISHED;
+ }
+
// This transaction is ultimately backed by a LevelDBScope. Aborting a
// transaction rolls back the LevelDBScopes, which (if LevelDBScopes is in
// single-sequence mode) can fail. This returns the result of that rollback,
diff --git a/content/browser/indexed_db/transaction_impl.cc b/content/browser/indexed_db/transaction_impl.cc
index 9f97786f09fdd0768e015abb1c85d4e17ad4a374..a6e040a32718af0d995cf87aadaeef2a9e3fadbc 100644
--- a/content/browser/indexed_db/transaction_impl.cc
+++ b/content/browser/indexed_db/transaction_impl.cc
@@ -57,6 +57,13 @@ void TransactionImpl::CreateObjectStore(int64_t object_store_id,
return;
}
+ if (!transaction_->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "CreateObjectStore was called after committing or aborting the "
+ "transaction");
+ return;
+ }
+
IndexedDBConnection* connection = transaction_->connection();
if (!connection->IsConnected())
return;
@@ -79,6 +86,13 @@ void TransactionImpl::DeleteObjectStore(int64_t object_store_id) {
return;
}
+ if (!transaction_->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "DeleteObjectStore was called after committing or aborting the "
+ "transaction");
+ return;
+ }
+
IndexedDBConnection* connection = transaction_->connection();
if (!connection->IsConnected())
return;
@@ -114,6 +128,12 @@ void TransactionImpl::Put(
return;
}
+ if (!transaction_->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "Put was called after committing or aborting the transaction");
+ return;
+ }
+
IndexedDBConnection* connection = transaction_->connection();
if (!connection->IsConnected()) {
IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError,
@@ -173,6 +193,12 @@ void TransactionImpl::PutAll(int64_t object_store_id,
return;
}
+ if (!transaction_->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "PutAll was called after committing or aborting the transaction");
+ return;
+ }
+
std::vector<std::vector<IndexedDBExternalObject>> external_objects_per_put(
puts.size());
for (size_t i = 0; i < puts.size(); i++) {
@@ -271,6 +297,12 @@ void TransactionImpl::Commit(int64_t num_errors_handled) {
if (!transaction_)
return;
+ if (!transaction_->IsAcceptingRequests()) {
+ mojo::ReportBadMessage(
+ "Commit was called after committing or aborting the transaction");
+ return;
+ }
+
IndexedDBConnection* connection = transaction_->connection();
if (!connection->IsConnected())
return;

View File

@@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Victor Costan <pwnall@chromium.org>
Date: Fri, 10 Sep 2021 22:37:26 +0000
Subject: M93: [IndexedDB] Don't ReportBadMessage for Commit calls.
We do seem to be getting commit calls quite a lot even after a
transaction has already started to be committed or aborted, so for now
just avoid killing the renderer until we figure out where these calls
are coming from.
(cherry picked from commit f9bf7be854ed80a792953e94dd56e1269a5bbe98)
Bug: 1247766
Change-Id: If7a4d4b12574c894addddbfcaf336295bd90e0a3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3154398
Reviewed-by: Daniel Murphy <dmurph@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#920304}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3154726
Commit-Queue: Victor Costan <pwnall@chromium.org>
Reviewed-by: enne <enne@chromium.org>
Cr-Commit-Position: refs/branch-heads/4577@{#1235}
Cr-Branched-From: 761ddde228655e313424edec06497d0c56b0f3c4-refs/heads/master@{#902210}
diff --git a/content/browser/indexed_db/transaction_impl.cc b/content/browser/indexed_db/transaction_impl.cc
index a6e040a32718af0d995cf87aadaeef2a9e3fadbc..7add046bb8d0a47cfbf9bf99048f3cec2fece260 100644
--- a/content/browser/indexed_db/transaction_impl.cc
+++ b/content/browser/indexed_db/transaction_impl.cc
@@ -298,8 +298,8 @@ void TransactionImpl::Commit(int64_t num_errors_handled) {
return;
if (!transaction_->IsAcceptingRequests()) {
- mojo::ReportBadMessage(
- "Commit was called after committing or aborting the transaction");
+ // This really shouldn't be happening, but seems to be happening anyway. So
+ // rather than killing the renderer, simply ignore the request.
return;
}

View File

@@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: VerteDinde <khammond@slack-corp.com>
Date: Tue, 19 Oct 2021 16:56:25 -0700
Subject: fix: mas gate private enterprise APIs
Beginning in Electron 15.2.0, Chromium moved several formerly public
APIs into the AreDeviceAndUserJoinedToDomain method. Using these APIs
in a MAS build will result in rejection from the Apple Store. This
patch gates those APIs to non-MAS builds to comply with Apple
Store requirements, and returns the default state for MAS builds.
diff --git a/base/enterprise_util_mac.mm b/base/enterprise_util_mac.mm
index 3ebcca94d7a9916b371eb7571e1ec4ba8ec3dcad..58b7de2b2a4c3223c64d275da888ae812fee26f9 100644
--- a/base/enterprise_util_mac.mm
+++ b/base/enterprise_util_mac.mm
@@ -154,6 +154,10 @@ MacDeviceManagementStateNew IsDeviceRegisteredWithManagementNew() {
DeviceUserDomainJoinState AreDeviceAndUserJoinedToDomain() {
DeviceUserDomainJoinState state{false, false};
+#if defined(MAS_BUILD)
+ return state;
+}
+#else
@autoreleasepool {
ODSession* session = [ODSession defaultSession];
@@ -256,5 +260,6 @@ DeviceUserDomainJoinState AreDeviceAndUserJoinedToDomain() {
return state;
}
+#endif
} // namespace base

View File

@@ -0,0 +1,527 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Clark DuVall <cduvall@chromium.org>
Date: Fri, 20 Aug 2021 00:52:03 +0000
Subject: Speculative fix for crash in URLLoader::OnBeforeSendHeadersComplete
I wasn't able to reproduce the crash, but this should prevent crashing
when accessing an invalid pointer for the HttpRequestHeaders. Instead of
passing a raw pointer, OnBeforeStartTransaction will now take optional
headers in the callback to modify the extra headers. If the job has been
destroyed, the callback will not be run since it was bound with a
WeakPtr to the job.
(cherry picked from commit c06b3928469bfd0e0a9fa6045b95a7be70ef393f)
Bug: 1221047
Change-Id: I93d5838b778e7283f7043fd2c841844941f52a85
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3042975
Commit-Queue: Clark DuVall <cduvall@chromium.org>
Reviewed-by: Matt Mueller <mattm@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#905539}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3108058
Auto-Submit: Clark DuVall <cduvall@chromium.org>
Cr-Commit-Position: refs/branch-heads/4515@{#2070}
Cr-Branched-From: 488fc70865ddaa05324ac00a54a6eb783b4bc41c-refs/heads/master@{#885287}
diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc
index 02e2fba808247bbe6379c236fec158e7d50e4ed8..be05286516cef07fe39c453fa811ff15a23e0e40 100644
--- a/net/base/network_delegate.cc
+++ b/net/base/network_delegate.cc
@@ -35,14 +35,13 @@ int NetworkDelegate::NotifyBeforeURLRequest(URLRequest* request,
int NetworkDelegate::NotifyBeforeStartTransaction(
URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers) {
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) {
TRACE_EVENT0(NetTracingCategory(),
"NetworkDelegate::NotifyBeforeStartTransation");
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(headers);
DCHECK(!callback.is_null());
- return OnBeforeStartTransaction(request, std::move(callback), headers);
+ return OnBeforeStartTransaction(request, headers, std::move(callback));
}
int NetworkDelegate::NotifyHeadersReceived(
diff --git a/net/base/network_delegate.h b/net/base/network_delegate.h
index c00f0ccd3b5a8bf8973b359cfc7880355292be03..8992bb63a5cfd8d577b36a29ee35ba4c8e9867c1 100644
--- a/net/base/network_delegate.h
+++ b/net/base/network_delegate.h
@@ -56,9 +56,11 @@ class NET_EXPORT NetworkDelegate {
int NotifyBeforeURLRequest(URLRequest* request,
CompletionOnceCallback callback,
GURL* new_url);
+ using OnBeforeStartTransactionCallback =
+ base::OnceCallback<void(int, const base::Optional<HttpRequestHeaders>&)>;
int NotifyBeforeStartTransaction(URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers);
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback);
int NotifyHeadersReceived(
URLRequest* request,
CompletionOnceCallback callback,
@@ -133,7 +135,8 @@ class NET_EXPORT NetworkDelegate {
GURL* new_url) = 0;
// Called right before the network transaction starts. Allows the delegate to
- // read/write |headers| before they get sent out.
+ // read |headers| and modify them by passing a new copy to |callback| before
+ // they get sent out.
//
// Returns OK to continue with the request, ERR_IO_PENDING if the result is
// not ready yet, and any other status code to cancel the request. If
@@ -142,11 +145,11 @@ class NET_EXPORT NetworkDelegate {
// or OnCompleted. Once cancelled, |request| and |headers| become invalid and
// |callback| may not be called.
//
- // The default implementation returns OK (continue with request) without
- // modifying |headers|.
- virtual int OnBeforeStartTransaction(URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers) = 0;
+ // The default implementation returns OK (continue with request).
+ virtual int OnBeforeStartTransaction(
+ URLRequest* request,
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) = 0;
// Called for HTTP requests when the headers have been received.
// |original_response_headers| contains the headers as received over the
diff --git a/net/base/network_delegate_impl.cc b/net/base/network_delegate_impl.cc
index 822bedc22a827a6ae06e7212111bf075298e9e5c..67e43fa2f764506ba7dc6e114570da54045a91f6 100644
--- a/net/base/network_delegate_impl.cc
+++ b/net/base/network_delegate_impl.cc
@@ -16,8 +16,8 @@ int NetworkDelegateImpl::OnBeforeURLRequest(URLRequest* request,
int NetworkDelegateImpl::OnBeforeStartTransaction(
URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers) {
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) {
return OK;
}
diff --git a/net/base/network_delegate_impl.h b/net/base/network_delegate_impl.h
index 323dade2a5affcd9123de0ef7d4b04e32445a149..78f658ba84da26ab7a22ad23f8944f1157fe0450 100644
--- a/net/base/network_delegate_impl.h
+++ b/net/base/network_delegate_impl.h
@@ -39,9 +39,10 @@ class NET_EXPORT NetworkDelegateImpl : public NetworkDelegate {
CompletionOnceCallback callback,
GURL* new_url) override;
- int OnBeforeStartTransaction(URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers) override;
+ int OnBeforeStartTransaction(
+ URLRequest* request,
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) override;
int OnHeadersReceived(
URLRequest* request,
diff --git a/net/proxy_resolution/network_delegate_error_observer_unittest.cc b/net/proxy_resolution/network_delegate_error_observer_unittest.cc
index c9448fd2a4c665bd91d2a6714a1def2404d4f446..665bb592b892457dc313c2f92148dfecc4930916 100644
--- a/net/proxy_resolution/network_delegate_error_observer_unittest.cc
+++ b/net/proxy_resolution/network_delegate_error_observer_unittest.cc
@@ -35,9 +35,10 @@ class TestNetworkDelegate : public NetworkDelegateImpl {
GURL* new_url) override {
return OK;
}
- int OnBeforeStartTransaction(URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers) override {
+ int OnBeforeStartTransaction(
+ URLRequest* request,
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) override {
return OK;
}
int OnHeadersReceived(
diff --git a/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc b/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
index 8d9fa8344f3febfcd9ba1e3933546d24cc1f1ae3..c10aee9e925c0eea44cc89a2dbfa5ee4c0495917 100644
--- a/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
+++ b/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
@@ -146,9 +146,10 @@ class BasicNetworkDelegate : public NetworkDelegateImpl {
return OK;
}
- int OnBeforeStartTransaction(URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers) override {
+ int OnBeforeStartTransaction(
+ URLRequest* request,
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) override {
return OK;
}
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index d6f1215fa15971199b9e7020b99c830120beab4b..1eec76ef7ebc44137a3f954a0a80d6f9dcfd676b 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -79,9 +79,10 @@ class BasicNetworkDelegate : public NetworkDelegateImpl {
return OK;
}
- int OnBeforeStartTransaction(URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers) override {
+ int OnBeforeStartTransaction(
+ URLRequest* request,
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) override {
return OK;
}
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index 9d993cce5e0e01936d1e4c9837f6bc129ca41e67..5a9873dc9b8b9e390c72d5d01eeb35136b3d0824 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -379,15 +379,10 @@ void URLRequestHttpJob::StartTransaction() {
if (network_delegate) {
OnCallToDelegate(
NetLogEventType::NETWORK_DELEGATE_BEFORE_START_TRANSACTION);
- // The NetworkDelegate must watch for OnRequestDestroyed and not modify
- // |extra_headers| after it's called.
- // TODO(mattm): change the API to remove the out-params and take the
- // results as params of the callback.
int rv = network_delegate->NotifyBeforeStartTransaction(
- request_,
+ request_, request_info_.extra_headers,
base::BindOnce(&URLRequestHttpJob::NotifyBeforeStartTransactionCallback,
- weak_factory_.GetWeakPtr()),
- &request_info_.extra_headers);
+ weak_factory_.GetWeakPtr()));
// If an extension blocks the request, we rely on the callback to
// MaybeStartTransactionInternal().
if (rv == ERR_IO_PENDING)
@@ -398,10 +393,14 @@ void URLRequestHttpJob::StartTransaction() {
StartTransactionInternal();
}
-void URLRequestHttpJob::NotifyBeforeStartTransactionCallback(int result) {
+void URLRequestHttpJob::NotifyBeforeStartTransactionCallback(
+ int result,
+ const base::Optional<HttpRequestHeaders>& headers) {
// The request should not have been cancelled or have already completed.
DCHECK(!is_done());
+ if (headers)
+ request_info_.extra_headers = headers.value();
MaybeStartTransactionInternal(result);
}
diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h
index c026834af2c910315f4b37b578a59f8596b299f1..988db0d80576c542b92c460d4f00838fb06e8632 100644
--- a/net/url_request/url_request_http_job.h
+++ b/net/url_request/url_request_http_job.h
@@ -121,7 +121,9 @@ class NET_EXPORT_PRIVATE URLRequestHttpJob : public URLRequestJob {
void OnHeadersReceivedCallback(int result);
void OnStartCompleted(int result);
void OnReadCompleted(int result);
- void NotifyBeforeStartTransactionCallback(int result);
+ void NotifyBeforeStartTransactionCallback(
+ int result,
+ const base::Optional<HttpRequestHeaders>& headers);
// This just forwards the call to URLRequestJob::NotifyConnected().
// We need it because that method is protected and cannot be bound in a
// callback in this class.
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index d0a70f24f44906e22c917ebae4e69ab10245540a..85941d92df12178ef5e71070e12f195b8bd04443 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -440,8 +440,8 @@ int TestNetworkDelegate::OnBeforeURLRequest(URLRequest* request,
int TestNetworkDelegate::OnBeforeStartTransaction(
URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers) {
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) {
if (before_start_transaction_fails_)
return ERR_FAILED;
diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h
index 7cfed610a55fc4bf69e48875e06e41019281829b..98a218115359a38a10e6e2dd623e26195745de0e 100644
--- a/net/url_request/url_request_test_util.h
+++ b/net/url_request/url_request_test_util.h
@@ -338,9 +338,10 @@ class TestNetworkDelegate : public NetworkDelegateImpl {
int OnBeforeURLRequest(URLRequest* request,
CompletionOnceCallback callback,
GURL* new_url) override;
- int OnBeforeStartTransaction(URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers) override;
+ int OnBeforeStartTransaction(
+ URLRequest* request,
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) override;
int OnHeadersReceived(
URLRequest* request,
CompletionOnceCallback callback,
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index a45042e543c6d76425a09851943d5d2a8c27a504..f63730b854be33d8d03dd223209919fd2b637230 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -443,9 +443,10 @@ class BlockingNetworkDelegate : public TestNetworkDelegate {
CompletionOnceCallback callback,
GURL* new_url) override;
- int OnBeforeStartTransaction(URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers) override;
+ int OnBeforeStartTransaction(
+ URLRequest* request,
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) override;
int OnHeadersReceived(
URLRequest* request,
@@ -544,13 +545,19 @@ int BlockingNetworkDelegate::OnBeforeURLRequest(URLRequest* request,
int BlockingNetworkDelegate::OnBeforeStartTransaction(
URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers) {
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) {
// TestNetworkDelegate always completes synchronously.
CHECK_NE(ERR_IO_PENDING, TestNetworkDelegate::OnBeforeStartTransaction(
- request, base::NullCallback(), headers));
+ request, headers, base::NullCallback()));
- return MaybeBlockStage(ON_BEFORE_SEND_HEADERS, std::move(callback));
+ return MaybeBlockStage(
+ ON_BEFORE_SEND_HEADERS,
+ base::BindOnce(
+ [](OnBeforeStartTransactionCallback callback, int result) {
+ std::move(callback).Run(result, absl::nullopt);
+ },
+ std::move(callback)));
}
int BlockingNetworkDelegate::OnHeadersReceived(
@@ -4175,13 +4182,19 @@ class AsyncLoggingNetworkDelegate : public TestNetworkDelegate {
return RunCallbackAsynchronously(request, std::move(callback));
}
- int OnBeforeStartTransaction(URLRequest* request,
- CompletionOnceCallback callback,
- HttpRequestHeaders* headers) override {
+ int OnBeforeStartTransaction(
+ URLRequest* request,
+ const HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) override {
// TestNetworkDelegate always completes synchronously.
CHECK_NE(ERR_IO_PENDING, TestNetworkDelegate::OnBeforeStartTransaction(
- request, base::NullCallback(), headers));
- return RunCallbackAsynchronously(request, std::move(callback));
+ request, headers, base::NullCallback()));
+ return RunCallbackAsynchronously(
+ request, base::BindOnce(
+ [](OnBeforeStartTransactionCallback callback, int result) {
+ std::move(callback).Run(result, absl::nullopt);
+ },
+ std::move(callback)));
}
int OnHeadersReceived(
diff --git a/services/network/network_service_network_delegate.cc b/services/network/network_service_network_delegate.cc
index 25e64eb7c66c3087ba187cc06685294f29c08ccd..85ce0aa207985f7aba758f149d9a330ee0b29d23 100644
--- a/services/network/network_service_network_delegate.cc
+++ b/services/network/network_service_network_delegate.cc
@@ -104,16 +104,16 @@ int NetworkServiceNetworkDelegate::OnBeforeURLRequest(
int NetworkServiceNetworkDelegate::OnBeforeStartTransaction(
net::URLRequest* request,
- net::CompletionOnceCallback callback,
- net::HttpRequestHeaders* headers) {
+ const net::HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) {
URLLoader* url_loader = URLLoader::ForRequest(*request);
if (url_loader)
- return url_loader->OnBeforeStartTransaction(std::move(callback), headers);
+ return url_loader->OnBeforeStartTransaction(headers, std::move(callback));
#if !defined(OS_IOS)
WebSocket* web_socket = WebSocket::ForRequest(*request);
if (web_socket)
- return web_socket->OnBeforeStartTransaction(std::move(callback), headers);
+ return web_socket->OnBeforeStartTransaction(headers, std::move(callback));
#endif // !defined(OS_IOS)
return net::OK;
diff --git a/services/network/network_service_network_delegate.h b/services/network/network_service_network_delegate.h
index 0926327d2a009550d91824ef87f06aa7c4482c64..811589027df710e46314198c0aa60d188ad1128c 100644
--- a/services/network/network_service_network_delegate.h
+++ b/services/network/network_service_network_delegate.h
@@ -38,9 +38,10 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkServiceNetworkDelegate
int OnBeforeURLRequest(net::URLRequest* request,
net::CompletionOnceCallback callback,
GURL* new_url) override;
- int OnBeforeStartTransaction(net::URLRequest* request,
- net::CompletionOnceCallback callback,
- net::HttpRequestHeaders* headers) override;
+ int OnBeforeStartTransaction(
+ net::URLRequest* request,
+ const net::HttpRequestHeaders& headers,
+ OnBeforeStartTransactionCallback callback) override;
int OnHeadersReceived(
net::URLRequest* request,
net::CompletionOnceCallback callback,
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 4c87980dbad41372f3f23a9493877801ab4ed3d8..6a58f03258deab5ade6c2f1f8b837c6f2710145f 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -1622,13 +1622,14 @@ void URLLoader::OnReadCompleted(net::URLRequest* url_request, int bytes_read) {
// |this| may have been deleted.
}
-int URLLoader::OnBeforeStartTransaction(net::CompletionOnceCallback callback,
- net::HttpRequestHeaders* headers) {
+int URLLoader::OnBeforeStartTransaction(
+ const net::HttpRequestHeaders& headers,
+ net::NetworkDelegate::OnBeforeStartTransactionCallback callback) {
if (header_client_) {
header_client_->OnBeforeSendHeaders(
- *headers, base::BindOnce(&URLLoader::OnBeforeSendHeadersComplete,
- weak_ptr_factory_.GetWeakPtr(),
- std::move(callback), headers));
+ headers,
+ base::BindOnce(&URLLoader::OnBeforeSendHeadersComplete,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
return net::ERR_IO_PENDING;
}
return net::OK;
@@ -2005,13 +2006,10 @@ void URLLoader::ResumeStart() {
}
void URLLoader::OnBeforeSendHeadersComplete(
- net::CompletionOnceCallback callback,
- net::HttpRequestHeaders* out_headers,
+ net::NetworkDelegate::OnBeforeStartTransactionCallback callback,
int result,
const base::Optional<net::HttpRequestHeaders>& headers) {
- if (headers)
- *out_headers = headers.value();
- std::move(callback).Run(result);
+ std::move(callback).Run(result, headers);
}
void URLLoader::OnHeadersReceivedComplete(
diff --git a/services/network/url_loader.h b/services/network/url_loader.h
index e2fcaeea674b3012d428911637748bb819aaf3e8..2f3b1df33eee12b14a51883e33e596ef5bb2cd64 100644
--- a/services/network/url_loader.h
+++ b/services/network/url_loader.h
@@ -24,6 +24,7 @@
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/simple_watcher.h"
#include "net/base/load_states.h"
+#include "net/base/network_delegate.h"
#include "net/http/http_raw_request_headers.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request.h"
@@ -167,8 +168,9 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) URLLoader
// These methods are called by the network delegate to forward these events to
// the |header_client_|.
- int OnBeforeStartTransaction(net::CompletionOnceCallback callback,
- net::HttpRequestHeaders* headers);
+ int OnBeforeStartTransaction(
+ const net::HttpRequestHeaders& headers,
+ net::NetworkDelegate::OnBeforeStartTransactionCallback callback);
int OnHeadersReceived(
net::CompletionOnceCallback callback,
const net::HttpResponseHeaders* original_response_headers,
@@ -327,8 +329,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) URLLoader
void RecordBodyReadFromNetBeforePausedIfNeeded();
void ResumeStart();
void OnBeforeSendHeadersComplete(
- net::CompletionOnceCallback callback,
- net::HttpRequestHeaders* out_headers,
+ net::NetworkDelegate::OnBeforeStartTransactionCallback callback,
int result,
const base::Optional<net::HttpRequestHeaders>& headers);
void OnHeadersReceivedComplete(
diff --git a/services/network/websocket.cc b/services/network/websocket.cc
index 66406b297bbb5371acbc7d19327be3331ce7acdd..8d2afaf498207ff5b5edb7b3f99e40df62e9b6e7 100644
--- a/services/network/websocket.cc
+++ b/services/network/websocket.cc
@@ -535,13 +535,14 @@ bool WebSocket::AllowCookies(const GURL& url) const {
url, site_for_cookies_) == net::OK;
}
-int WebSocket::OnBeforeStartTransaction(net::CompletionOnceCallback callback,
- net::HttpRequestHeaders* headers) {
+int WebSocket::OnBeforeStartTransaction(
+ const net::HttpRequestHeaders& headers,
+ net::NetworkDelegate::OnBeforeStartTransactionCallback callback) {
if (header_client_) {
header_client_->OnBeforeSendHeaders(
- *headers, base::BindOnce(&WebSocket::OnBeforeSendHeadersComplete,
- weak_ptr_factory_.GetWeakPtr(),
- std::move(callback), headers));
+ headers,
+ base::BindOnce(&WebSocket::OnBeforeSendHeadersComplete,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
return net::ERR_IO_PENDING;
}
return net::OK;
@@ -838,17 +839,14 @@ void WebSocket::OnAuthRequiredComplete(
}
void WebSocket::OnBeforeSendHeadersComplete(
- net::CompletionOnceCallback callback,
- net::HttpRequestHeaders* out_headers,
+ net::NetworkDelegate::OnBeforeStartTransactionCallback callback,
int result,
const base::Optional<net::HttpRequestHeaders>& headers) {
if (!channel_) {
// Something happened before the OnBeforeSendHeaders response arrives.
return;
}
- if (headers)
- *out_headers = headers.value();
- std::move(callback).Run(result);
+ std::move(callback).Run(result, headers);
}
void WebSocket::OnHeadersReceivedComplete(
diff --git a/services/network/websocket.h b/services/network/websocket.h
index e14c5616eb59f11c31a3f05984f038e6fc72c4b8..e4d8af33cdb8835316f5b0dc4d40000afe4b2e2e 100644
--- a/services/network/websocket.h
+++ b/services/network/websocket.h
@@ -22,6 +22,7 @@
#include "base/types/strong_alias.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "net/base/network_delegate.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/websockets/websocket_event_interface.h"
#include "services/network/network_service.h"
@@ -89,8 +90,9 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) WebSocket : public mojom::WebSocket {
// These methods are called by the network delegate to forward these events to
// the |header_client_|.
- int OnBeforeStartTransaction(net::CompletionOnceCallback callback,
- net::HttpRequestHeaders* headers);
+ int OnBeforeStartTransaction(
+ const net::HttpRequestHeaders& headers,
+ net::NetworkDelegate::OnBeforeStartTransactionCallback callback);
int OnHeadersReceived(
net::CompletionOnceCallback callback,
const net::HttpResponseHeaders* original_response_headers,
@@ -149,8 +151,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) WebSocket : public mojom::WebSocket {
base::OnceCallback<void(const net::AuthCredentials*)> callback,
const base::Optional<net::AuthCredentials>& credential);
void OnBeforeSendHeadersComplete(
- net::CompletionOnceCallback callback,
- net::HttpRequestHeaders* out_headers,
+ net::NetworkDelegate::OnBeforeStartTransactionCallback callback,
int result,
const base::Optional<net::HttpRequestHeaders>& headers);
void OnHeadersReceivedComplete(

View File

@@ -0,0 +1,222 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Adam Rice <ricea@chromium.org>
Date: Thu, 30 Sep 2021 13:35:07 +0000
Subject: Move NetworkStateObserver from document to window
Previously NetworkStateObserver was a nested class of Document. Make it
a nested class of LocalDOMWindow instead, since they have the same
lifetime and it fires "online" and "offline" events at the window, not
the document.
BUG=1206928
(cherry picked from commit af84d38b5cf5ee24f432ae8273bc2dad1e075f0e)
Change-Id: I2a1080915cf56cfa47eae65594fe6edcc8c2130a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3167550
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Commit-Queue: Adam Rice <ricea@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#922429}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3196231
Cr-Commit-Position: refs/branch-heads/4638@{#476}
Cr-Branched-From: 159257cab5585bc8421abf347984bb32fdfe9eb9-refs/heads/main@{#920003}
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 93b923688e9dc6a43f515c12d1678d38fc40f34c..852a146666b38cd752113ca29a62a35012f98106 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -319,7 +319,6 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h"
-#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/event_loop.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
@@ -636,43 +635,6 @@ uint64_t Document::global_tree_version_ = 0;
static bool g_threaded_parsing_enabled_for_testing = true;
-class Document::NetworkStateObserver final
- : public GarbageCollected<Document::NetworkStateObserver>,
- public NetworkStateNotifier::NetworkStateObserver,
- public ExecutionContextLifecycleObserver {
- public:
- explicit NetworkStateObserver(ExecutionContext* context)
- : ExecutionContextLifecycleObserver(context) {
- online_observer_handle_ = GetNetworkStateNotifier().AddOnLineObserver(
- this, GetExecutionContext()->GetTaskRunner(TaskType::kNetworking));
- }
-
- void OnLineStateChange(bool on_line) override {
- AtomicString event_name =
- on_line ? event_type_names::kOnline : event_type_names::kOffline;
- auto* window = To<LocalDOMWindow>(GetExecutionContext());
- window->DispatchEvent(*Event::Create(event_name));
- probe::NetworkStateChanged(window->GetFrame(), on_line);
- }
-
- void ContextDestroyed() override {
- UnregisterAsObserver(GetExecutionContext());
- }
-
- void UnregisterAsObserver(ExecutionContext* context) {
- DCHECK(context);
- online_observer_handle_ = nullptr;
- }
-
- void Trace(Visitor* visitor) const override {
- ExecutionContextLifecycleObserver::Trace(visitor);
- }
-
- private:
- std::unique_ptr<NetworkStateNotifier::NetworkStateObserverHandle>
- online_observer_handle_;
-};
-
ExplicitlySetAttrElementsMap* Document::GetExplicitlySetAttrElementsMap(
Element* element) {
DCHECK(element);
@@ -2996,12 +2958,6 @@ void Document::Initialize() {
if (View())
View()->DidAttachDocument();
-
- // Observer(s) should not be initialized until the document is initialized /
- // attached to a frame. Otherwise
- // ExecutionContextLifecycleObserver::contextDestroyed wouldn't be fired.
- network_state_observer_ =
- MakeGarbageCollected<NetworkStateObserver>(GetExecutionContext());
}
void Document::Shutdown() {
@@ -8181,7 +8137,6 @@ void Document::Trace(Visitor* visitor) const {
visitor->Trace(intersection_observer_controller_);
visitor->Trace(snap_coordinator_);
visitor->Trace(property_registry_);
- visitor->Trace(network_state_observer_);
visitor->Trace(policy_);
visitor->Trace(slot_assignment_engine_);
visitor->Trace(viewport_data_);
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index f1d7d46f4e166f9054979fb7e28c41c1831bcceb..f71f12b34a39f8a4d50b0b821ef318cf02b1173d 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -1689,7 +1689,6 @@ class CORE_EXPORT Document : public ContainerNode,
BeforeMatchExpandedHiddenMatchableUkm);
FRIEND_TEST_ALL_PREFIXES(TextFinderSimTest,
BeforeMatchExpandedHiddenMatchableUkmNoHandler);
- class NetworkStateObserver;
friend class AXContext;
void AddAXContext(AXContext*);
@@ -2071,8 +2070,6 @@ class CORE_EXPORT Document : public ContainerNode,
TaskHandle sensitive_input_edited_task_;
- Member<NetworkStateObserver> network_state_observer_;
-
std::unique_ptr<DocumentOutliveTimeReporter> document_outlive_time_reporter_;
// |ukm_recorder_| and |source_id_| will allow objects that are part of
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 1cd316f90a037d8736e89bbfb28fb26523ccd97b..19ad80c9342f5aaeae10bb19fd5f71aedba7e169 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -127,6 +127,7 @@
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
+#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
#include "third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/timer.h"
@@ -162,6 +163,38 @@ bool ShouldRecordPostMessageIncomingFrameUkmEvent(
} // namespace
+class LocalDOMWindow::NetworkStateObserver final
+ : public GarbageCollected<LocalDOMWindow::NetworkStateObserver>,
+ public NetworkStateNotifier::NetworkStateObserver,
+ public ExecutionContextLifecycleObserver {
+ public:
+ explicit NetworkStateObserver(ExecutionContext* context)
+ : ExecutionContextLifecycleObserver(context) {}
+
+ void Initialize() {
+ online_observer_handle_ = GetNetworkStateNotifier().AddOnLineObserver(
+ this, GetExecutionContext()->GetTaskRunner(TaskType::kNetworking));
+ }
+
+ void OnLineStateChange(bool on_line) override {
+ AtomicString event_name =
+ on_line ? event_type_names::kOnline : event_type_names::kOffline;
+ auto* window = To<LocalDOMWindow>(GetExecutionContext());
+ window->DispatchEvent(*Event::Create(event_name));
+ probe::NetworkStateChanged(window->GetFrame(), on_line);
+ }
+
+ void ContextDestroyed() override { online_observer_handle_ = nullptr; }
+
+ void Trace(Visitor* visitor) const override {
+ ExecutionContextLifecycleObserver::Trace(visitor);
+ }
+
+ private:
+ std::unique_ptr<NetworkStateNotifier::NetworkStateObserverHandle>
+ online_observer_handle_;
+};
+
LocalDOMWindow::LocalDOMWindow(LocalFrame& frame, WindowAgent* agent)
: DOMWindow(frame),
ExecutionContext(V8PerIsolateData::MainThreadIsolate(), agent),
@@ -179,7 +212,9 @@ LocalDOMWindow::LocalDOMWindow(LocalFrame& frame, WindowAgent* agent)
isolated_world_csp_map_(
MakeGarbageCollected<
HeapHashMap<int, Member<ContentSecurityPolicy>>>()),
- token_(LocalFrameToken(frame.GetFrameToken())) {}
+ token_(LocalFrameToken(frame.GetFrameToken())),
+ network_state_observer_(
+ MakeGarbageCollected<NetworkStateObserver>(this)) {}
void LocalDOMWindow::BindContentSecurityPolicy() {
DCHECK(!GetContentSecurityPolicy()->IsBound());
@@ -189,6 +224,7 @@ void LocalDOMWindow::BindContentSecurityPolicy() {
void LocalDOMWindow::Initialize() {
GetAgent()->AttachContext(this);
+ network_state_observer_->Initialize();
}
void LocalDOMWindow::ResetWindowAgent(WindowAgent* agent) {
@@ -2120,6 +2156,7 @@ void LocalDOMWindow::Trace(Visitor* visitor) const {
visitor->Trace(spell_checker_);
visitor->Trace(text_suggestion_controller_);
visitor->Trace(isolated_world_csp_map_);
+ visitor->Trace(network_state_observer_);
DOMWindow::Trace(visitor);
ExecutionContext::Trace(visitor);
Supplementable<LocalDOMWindow>::Trace(visitor);
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h
index 290467577c86bd69c19c108e3bcd87b80d24e4a9..aa1d1f89ba061df6e8d856aef6c0b6803c126f87 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.h
+++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -448,6 +448,8 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
LocalDOMWindow* source) override;
private:
+ class NetworkStateObserver;
+
// Intentionally private to prevent redundant checks when the type is
// already LocalDOMWindow.
bool IsLocalDOMWindow() const override { return true; }
@@ -545,6 +547,9 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
// this UKM is logged.
// TODO(crbug.com/1112491): Remove when no longer needed.
Deque<ukm::SourceId> post_message_ukm_recorded_source_ids_;
+
+ // Fire "online" and "offline" events.
+ Member<NetworkStateObserver> network_state_observer_;
};
template <>

View File

@@ -0,0 +1,55 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yuly Novikov <ynovikov@chromium.org>
Date: Thu, 9 Sep 2021 20:00:43 +0000
Subject: Skip WebGL conformance/programs/program-test.html on all platforms
To unblock ANGLE CL http://crrev.com/c/3140496, which modifies behaviour
to make it an error to draw after the current program fails to re-link.
(cherry picked from commit 8ef1e4544ed5214608039d969940347d8f98e543)
Bug: 1241123
Bug: angleproject:6358
Change-Id: I40a1f4843f902533745cc9527379def9d777a578
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3140226
Auto-Submit: Yuly Novikov <ynovikov@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/heads/main@{#918281}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3150594
Auto-Submit: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Yuly Novikov <ynovikov@chromium.org>
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
Cr-Commit-Position: refs/branch-heads/4515@{#2117}
Cr-Branched-From: 488fc70865ddaa05324ac00a54a6eb783b4bc41c-refs/heads/master@{#885287}
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
index 6b91c94495f2aea1b1cc6fa1c5962cea0b94b2a6..4e97412e4873b0ed5b7de6a417dd5e5f1e86f8d3 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -187,6 +187,10 @@ crbug.com/1085222 [ linux intel-0x5912 ] deqp/functional/gles3/shadermatrix/add_
crbug.com/1085222 [ catalina intel-0xa2e ] deqp/functional/gles3/shaderoperator/binary_operator_* [ RetryOnFailure ]
crbug.com/1085222 [ catalina intel-0xa2e ] deqp/functional/gles3/shaderoperator/unary_operator_* [ RetryOnFailure ]
+# Temporary suppression while we wait for a spec update.
+# TODO(jmadill): Remove when possible.
+crbug.com/angleproject/6358 conformance/programs/program-test.html [ Failure ]
+
####################
# Win failures #
####################
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
index 9e2aee0cebecbe83bc6df45fd6e006d95513b2f9..b8ff50068fc419630cab86fb4eb925b0f5e3a05b 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -238,6 +238,10 @@ crbug.com/1163292 [ win nvidia angle-d3d9 ] conformance/textures/misc/texture-co
crbug.com/1105129 [ linux ] conformance/context/context-creation.html [ RetryOnFailure ]
crbug.com/1105129 [ win ] conformance/context/context-creation.html [ RetryOnFailure ]
+# Temporary suppression while we wait for a spec update.
+# TODO(jmadill): Remove when possible.
+crbug.com/angleproject/6358 conformance/programs/program-test.html [ Failure ]
+
# Win / AMD / Passthrough command decoder / D3D11
crbug.com/772037 [ win amd angle-d3d11 passthrough ] conformance/textures/misc/texture-sub-image-cube-maps.html [ RetryOnFailure ]

View File

@@ -0,0 +1,63 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ionel Popescu <iopopesc@microsoft.com>
Date: Wed, 15 Sep 2021 18:16:16 +0000
Subject: Speculative fix for eye dropper getColor crash.
There seems to be a situation where the captured frame coordinates
are different than the ones accessible by moving the mouse.
I am not able to locally reproduce this issue, so I am adding DCHECKs
to validate that the coordinates are correct and I am also handling
the invalid coordinates to prevent invalid memory access.
(cherry picked from commit a656373ae7212e0d88474bdec4691a4152452748)
Bug: 1246631
Change-Id: I915d46a71aa73b5dcf08127d347fdd47c1ddf54c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3152423
Reviewed-by: Mason Freed <masonf@chromium.org>
Commit-Queue: Ionel Popescu <iopopesc@microsoft.com>
Cr-Original-Commit-Position: refs/heads/main@{#920811}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3163070
Auto-Submit: Ionel Popescu <iopopesc@microsoft.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4638@{#75}
Cr-Branched-From: 159257cab5585bc8421abf347984bb32fdfe9eb9-refs/heads/main@{#920003}
diff --git a/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc b/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc
index 1adde90978a49f482f586755aa2a549e47de2ede..d247bfc187f4b461ff335ea7e307b21571522dd8 100644
--- a/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc
+++ b/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc
@@ -63,6 +63,7 @@ class EyeDropperView::ScreenCapturer
std::unique_ptr<webrtc::DesktopFrame> frame) override;
SkBitmap GetBitmap() const;
+ SkColor GetColor(int x, int y) const;
private:
std::unique_ptr<webrtc::DesktopCapturer> capturer_;
@@ -93,6 +94,13 @@ SkBitmap EyeDropperView::ScreenCapturer::GetBitmap() const {
return frame_;
}
+SkColor EyeDropperView::ScreenCapturer::GetColor(int x, int y) const {
+ DCHECK(x < frame_.width());
+ DCHECK(y < frame_.height());
+ return x < frame_.width() && y < frame_.height() ? frame_.getColor(x, y)
+ : SK_ColorBLACK;
+}
+
EyeDropperView::EyeDropperView(content::RenderFrameHost* frame,
content::EyeDropperListener* listener)
: render_frame_host_(frame),
@@ -169,7 +177,8 @@ void EyeDropperView::OnPaint(gfx::Canvas* view_canvas) {
// Store the pixel color under the cursor as it is the last color seen
// by the user before selection.
- selected_color_ = frame.getColor(center_position.x(), center_position.y());
+ selected_color_ =
+ screen_capturer_->GetColor(center_position.x(), center_position.y());
// Paint grid.
cc::PaintFlags flags;

View File

@@ -0,0 +1,122 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hongchan Choi <hongchan@chromium.org>
Date: Mon, 11 Oct 2021 23:53:51 +0000
Subject: Use zero when the starting value of exponential ramp is zero
The calculation of an exponential curve is done by the specification:
https://webaudio.github.io/web-audio-api/#dom-audioparam-exponentialramptovalueattime
However, it missed a case where V0 (value1) is zero where it causes
a NaN.
(cherry picked from commit 4e2dcd84dc33f29b032b52e053726ab49e4d0b4d)
Bug: 1253746,1240610
Test: third_party/blink/web_tests/webaudio/AudioParam/exponential-ramp-crash-1253746.html
Change-Id: Ib4a95f9298b4300705eda6a2eea64169de7cb002
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3205982
Reviewed-by: Ryan Sleevi <rsleevi@chromium.org>
Reviewed-by: Chrome Cunningham <chcunningham@chromium.org>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#928673}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3218139
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/branch-heads/4638@{#766}
Cr-Branched-From: 159257cab5585bc8421abf347984bb32fdfe9eb9-refs/heads/main@{#920003}
diff --git a/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc b/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc
index c6177422fc29300242390a3ea6fded1484d46ee2..c0cdc0f6635615dde6424852f0a3dec9413af62b 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc
@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#if defined(ARCH_CPU_X86_FAMILY)
#include <emmintrin.h>
@@ -132,7 +133,12 @@ float AudioParamTimeline::ExponentialRampAtTime(double t,
double time1,
float value2,
double time2) {
- return value1 * pow(value2 / value1, (t - time1) / (time2 - time1));
+ DCHECK(!std::isnan(value1) && std::isfinite(value1));
+ DCHECK(!std::isnan(value2) && std::isfinite(value2));
+
+ return (value1 == 0.0f || std::signbit(value1) != std::signbit(value2))
+ ? value1
+ : value1 * pow(value2 / value1, (t - time1) / (time2 - time1));
}
// Compute the value of a set target event at time t with the given event
@@ -992,6 +998,8 @@ float AudioParamTimeline::ValuesForFrameRangeImpl(size_t start_frame,
std::tie(value2, time2, next_event_type) =
HandleCancelValues(event, next_event, value2, time2);
+ DCHECK(!std::isnan(value1));
+ DCHECK(!std::isnan(value2));
DCHECK_GE(time2, time1);
// |fillToEndFrame| is the exclusive upper bound of the last frame to be
@@ -1051,7 +1059,6 @@ float AudioParamTimeline::ValuesForFrameRangeImpl(size_t start_frame,
value = event->Value();
write_index =
FillWithDefault(values, value, fill_to_frame, write_index);
-
break;
}
@@ -1393,6 +1400,7 @@ AudioParamTimeline::HandleCancelValues(const ParamEvent* current_event,
value2 = ExponentialRampAtTime(next_event->Time(), value1, time1,
saved_event->Value(),
saved_event->Time());
+ DCHECK(!std::isnan(value1));
break;
case ParamEvent::kSetValueCurve:
case ParamEvent::kSetValueCurveEnd:
diff --git a/third_party/blink/web_tests/webaudio/AudioParam/exponential-ramp-crash-1253746.html b/third_party/blink/web_tests/webaudio/AudioParam/exponential-ramp-crash-1253746.html
new file mode 100644
index 0000000000000000000000000000000000000000..85397c5cc6757ae1464a0cd6733283b6b60abeee
--- /dev/null
+++ b/third_party/blink/web_tests/webaudio/AudioParam/exponential-ramp-crash-1253746.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>
+ Test if a corner case crashes the exponential ramp.
+ </title>
+ <script src="../../resources/testharness.js"></script>
+ <script src="../../resources/testharnessreport.js"></script>
+</head>
+<body>
+ <script>
+ const t = async_test('exponential-ramp-crash');
+
+ const onload = () => {
+ const context = new OfflineAudioContext(2, 441000, 44100);
+ const source = new ConstantSourceNode(context);
+ const delay_node = context.createDelay(30);
+ delay_node.connect(context.destination);
+ // The time overlap between 4.1s and 4s caused a crash in M95:
+ // https://crbug.com/1253746
+ delay_node.delayTime.exponentialRampToValueAtTime(2, 4.1);
+ delay_node.delayTime.cancelAndHoldAtTime(4);
+ context.oncomplete = t.step_func_done(() => {
+ // The |delay_node.delayTime| value should be zero because it does not
+ // have the previous anchor value. Based on the specification, if the
+ // beginning of an expoential ramp is zero, the resulting value falls
+ // into zero. In this case, there was no value point before the
+ // exponential ramp, and having no value point is treated as a
+ // default value, which is zero for |delayTime|.
+ assert_equals(delay_node.delayTime.value, 0);
+ assert_equals(context.state, 'closed');
+ });
+ context.startRendering();
+ };
+
+ window.addEventListener('load', t.step_func(onload));
+ </script>
+</body>
+</html>

View File

@@ -21,5 +21,9 @@
"src/electron/patches/usrsctp": "src/third_party/usrsctp/usrsctplib",
"src/electron/patches/sqlite": "src/third_party/sqlite/src"
"src/electron/patches/sqlite": "src/third_party/sqlite/src",
"src/electron/patches/webrtc": "src/third_party/webrtc",
"src/electron/patches/pdfium": "src/third_party/pdfium"
}

View File

@@ -34,3 +34,4 @@ fix_parallel_test-crypto-ecdh-convert-key_to_use_compatible_group.patch
src_inline_asynccleanuphookhandle_in_headers.patch
node-api_faster_threadsafe_function.patch
src_add_missing_context_scopes.patch
fix_remove_expired_dst_root_ca_x3.patch

View File

@@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Fri, 1 Oct 2021 08:03:08 +0900
Subject: fix: remove expired DST Root CA X3
The alternative ISRG Root X1 trusted certificate is
already available in this bundle.
https://letsencrypt.org/docs/certificate-compatibility/
https://www.openssl.org/blog/blog/2021/09/13/LetsEncryptRootCertExpire/
diff --git a/src/node_root_certs.h b/src/node_root_certs.h
index 47beb730f4b853f1bf248a7fd1b1cd7d726bdf7e..94ac882ec7e4e2eb61d1f0094f79fb6f603d978c 100644
--- a/src/node_root_certs.h
+++ b/src/node_root_certs.h
@@ -525,26 +525,6 @@
"yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K\n"
"-----END CERTIFICATE-----",
-/* DST Root CA X3 */
-"-----BEGIN CERTIFICATE-----\n"
-"MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYD\n"
-"VQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENB\n"
-"IFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRh\n"
-"bCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJ\n"
-"KoZIhvcNAQEBBQADggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdA\n"
-"wRgUi+DoM3ZJKuM/IUmTrE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwG\n"
-"MoOifooUMM0RoOEqOLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4X\n"
-"Lh7dIN9bxiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw\n"
-"7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkq\n"
-"tilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw\n"
-"HQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqGSIb3DQEBBQUAA4IBAQCjGiyb\n"
-"FwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikugdB/OEIKcdBodfpga3csTS7MgROSR\n"
-"6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaL\n"
-"bumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir\n"
-"/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06Xyx\n"
-"V3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ\n"
-"-----END CERTIFICATE-----",
-
/* SwissSign Gold CA - G2 */
"-----BEGIN CERTIFICATE-----\n"
"MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNI\n"

1
patches/pdfium/.patches Normal file
View File

@@ -0,0 +1 @@
m94_use_more_safe_arithmetic_in_cfx_dibbase.patch

View File

@@ -0,0 +1,143 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Thu, 14 Oct 2021 18:29:32 +0000
Subject: M94: Use more safe arithmetic in CFX_DIBBase
Most of the calculations are "safe" because we know that the DIB
has validated sizes before allocating a buffer, and that calculations
in terms of bytes won't overflow and will be within the buffer. But
calculations in terms of bits might create overflow in temporaries,
so use safe arithmetic there instead.
Re-arranging the order of operations thus converting to bytes first
might be one option, but we want to handle the 1 bpp case.
Test would require large images that might not be possible on
all platforms.
Bug: chromium:1253399
Change-Id: I3c6c5b8b1f1bf3f429c7d377a8a84c5ab53cafd9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/85510
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
(cherry picked from commit a8b293732a0160d1bc1d5b0ad5744922f0f820d5)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/85950
diff --git a/core/fxge/dib/cfx_bitmapcomposer.cpp b/core/fxge/dib/cfx_bitmapcomposer.cpp
index 86066ba72dccc78d65dbaaba76ee4d47d18080a2..af7a2480989668d0108b91fe4e60f2d6a12d31dd 100644
--- a/core/fxge/dib/cfx_bitmapcomposer.cpp
+++ b/core/fxge/dib/cfx_bitmapcomposer.cpp
@@ -6,6 +6,7 @@
#include "core/fxge/dib/cfx_bitmapcomposer.h"
+#include "core/fxcrt/fx_safe_types.h"
#include "core/fxge/cfx_cliprgn.h"
#include "core/fxge/dib/cfx_dibitmap.h"
@@ -109,8 +110,17 @@ void CFX_BitmapComposer::ComposeScanline(int line,
m_pClipMask->GetPitch() +
(m_DestLeft - m_pClipRgn->GetBox().left);
}
- uint8_t* dest_scan = m_pBitmap->GetWritableScanline(line + m_DestTop) +
- m_DestLeft * m_pBitmap->GetBPP() / 8;
+ uint8_t* dest_scan = m_pBitmap->GetWritableScanline(line + m_DestTop);
+ if (dest_scan) {
+ FX_SAFE_UINT32 offset = m_DestLeft;
+ offset *= m_pBitmap->GetBPP();
+ offset /= 8;
+ if (!offset.IsValid())
+ return;
+
+ // Help some compilers perform pointer arithmetic against safe numerics.
+ dest_scan += static_cast<uint32_t>(offset.ValueOrDie());
+ }
uint8_t* dest_alpha_scan =
m_pBitmap->m_pAlphaMask
? m_pBitmap->m_pAlphaMask->GetWritableScanline(line + m_DestTop) +
diff --git a/core/fxge/dib/cfx_dibbase.cpp b/core/fxge/dib/cfx_dibbase.cpp
index cff1d79f4a8e992c2b3cd110af471bb8c4bcafc3..8ea50919e224973142ceacee24a5bd03560d4f88 100644
--- a/core/fxge/dib/cfx_dibbase.cpp
+++ b/core/fxge/dib/cfx_dibbase.cpp
@@ -627,15 +627,25 @@ RetainPtr<CFX_DIBitmap> CFX_DIBBase::Clone(const FX_RECT* pClip) const {
}
}
} else {
- int copy_len = (pNewBitmap->GetWidth() * pNewBitmap->GetBPP() + 7) / 8;
- if (m_Pitch < static_cast<uint32_t>(copy_len))
- copy_len = m_Pitch;
+ FX_SAFE_UINT32 copy_len = pNewBitmap->GetWidth();
+ copy_len *= pNewBitmap->GetBPP();
+ copy_len += 7;
+ copy_len /= 8;
+ if (!copy_len.IsValid())
+ return nullptr;
+
+ copy_len = std::min<uint32_t>(m_Pitch, copy_len.ValueOrDie());
+
+ FX_SAFE_UINT32 offset = rect.left;
+ offset *= GetBppFromFormat(m_Format);
+ offset /= 8;
+ if (!offset.IsValid())
+ return nullptr;
for (int row = rect.top; row < rect.bottom; ++row) {
- const uint8_t* src_scan =
- GetScanline(row) + rect.left * GetBppFromFormat(m_Format) / 8;
+ const uint8_t* src_scan = GetScanline(row) + offset.ValueOrDie();
uint8_t* dest_scan = pNewBitmap->GetWritableScanline(row - rect.top);
- memcpy(dest_scan, src_scan, copy_len);
+ memcpy(dest_scan, src_scan, copy_len.ValueOrDie());
}
}
return pNewBitmap;
diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp
index 1052b357de90e49800c405f7c67e0e6ac34f22b9..c84b622662dab067acd4972acf6a68ad4815e258 100644
--- a/core/fxge/dib/cfx_dibitmap.cpp
+++ b/core/fxge/dib/cfx_dibitmap.cpp
@@ -216,8 +216,14 @@ bool CFX_DIBitmap::TransferWithUnequalFormats(
if (GetBppFromFormat(m_Format) == 8)
dest_format = FXDIB_Format::k8bppMask;
+ FX_SAFE_UINT32 offset = dest_left;
+ offset *= GetBPP();
+ offset /= 8;
+ if (!offset.IsValid())
+ return false;
+
uint8_t* dest_buf =
- m_pBuffer.Get() + dest_top * m_Pitch + dest_left * GetBPP() / 8;
+ m_pBuffer.Get() + dest_top * m_Pitch + offset.ValueOrDie();
std::vector<uint32_t, FxAllocAllocator<uint32_t>> d_plt;
return ConvertBuffer(dest_format, dest_buf, m_Pitch, width, height,
pSrcBitmap, src_left, src_top, &d_plt);
@@ -497,7 +503,13 @@ uint32_t CFX_DIBitmap::GetPixel(int x, int y) const {
if (!m_pBuffer)
return 0;
- uint8_t* pos = m_pBuffer.Get() + y * m_Pitch + x * GetBPP() / 8;
+ FX_SAFE_UINT32 offset = x;
+ offset *= GetBPP();
+ offset /= 8;
+ if (!offset.IsValid())
+ return 0;
+
+ uint8_t* pos = m_pBuffer.Get() + y * m_Pitch + offset.ValueOrDie();
switch (GetFormat()) {
case FXDIB_Format::k1bppMask: {
if ((*pos) & (1 << (7 - x % 8))) {
@@ -536,7 +548,13 @@ void CFX_DIBitmap::SetPixel(int x, int y, uint32_t color) {
if (x < 0 || x >= m_Width || y < 0 || y >= m_Height)
return;
- uint8_t* pos = m_pBuffer.Get() + y * m_Pitch + x * GetBPP() / 8;
+ FX_SAFE_UINT32 offset = x;
+ offset *= GetBPP();
+ offset /= 8;
+ if (!offset.IsValid())
+ return;
+
+ uint8_t* pos = m_pBuffer.Get() + y * m_Pitch + offset.ValueOrDie();
switch (GetFormat()) {
case FXDIB_Format::k1bppMask:
if (color >> 24) {

View File

@@ -26,3 +26,12 @@ cherry-pick-b9ad6a864c79.patch
cherry-pick-50de6a8ddad9.patch
cherry-pick-e76178b896f2.patch
merged_compiler_fix_a_bug_in.patch
cherry-pick-1234770.patch
cherry-pick-1234764.patch
cherry-pick-fbfd2557c2ab.patch
cherry-pick-034c2003be31.patch
cherry-pick-5c4acf2ae64a.patch
cherry-pick-6de4e210688e.patch
cherry-pick-014e1f857c33.patch
cherry-pick-feef10137b16.patch
merged_cppgc_fix_marking_of_ephemerons_with_keys_in_construction.patch

View File

@@ -0,0 +1,59 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marja=20H=C3=B6ltt=C3=A4?= <marja@chromium.org>
Date: Mon, 25 Oct 2021 12:17:15 +0200
Subject: Merged: [super ic] Fix receiver vs lookup start object confusion
related to module exports
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Revision: e4dba97006ca20337deafb85ac00524a94a62fe
BUG=chromium:1260577
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
R=ishell@chromium.org
Change-Id: Ia85235fecdb37a5da6a28f7a0092a754a8620552
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3240826
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/branch-heads/9.4@{#48}
Cr-Branched-From: 3b51863bc25492549a8bf96ff67ce481b1a3337b-refs/heads/9.4.146@{#1}
Cr-Branched-From: 2890419fc8fb9bdb507fdd801d76fa7dd9f022b5-refs/heads/master@{#76233}
diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc
index 8335bc5e883d319a0e67122e44ec231ae8af2507..1b6b6223366ecef12a9b9209bf2809e38271e262 100644
--- a/src/ic/accessor-assembler.cc
+++ b/src/ic/accessor-assembler.cc
@@ -663,8 +663,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase(
Comment("module export");
TNode<UintPtrT> index =
DecodeWord<LoadHandler::ExportsIndexBits>(handler_word);
- TNode<Module> module = LoadObjectField<Module>(
- CAST(p->receiver()), JSModuleNamespace::kModuleOffset);
+ TNode<Module> module =
+ LoadObjectField<Module>(CAST(holder), JSModuleNamespace::kModuleOffset);
TNode<ObjectHashTable> exports =
LoadObjectField<ObjectHashTable>(module, Module::kExportsOffset);
TNode<Cell> cell = CAST(LoadFixedArrayElement(exports, index));
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index d13d1bdab5f9ab4ab71500a77a2b6088667f95e7..36c82cbe95100c403b9eb2e7b7f6f210a5a0ae62 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -857,7 +857,13 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) {
// We found the accessor, so the entry must exist.
DCHECK(entry.is_found());
int index = ObjectHashTable::EntryToValueIndex(entry);
- return LoadHandler::LoadModuleExport(isolate(), index);
+ Handle<Smi> smi_handler =
+ LoadHandler::LoadModuleExport(isolate(), index);
+ if (holder_is_lookup_start_object) {
+ return smi_handler;
+ }
+ return LoadHandler::LoadFromPrototype(isolate(), map, holder,
+ smi_handler);
}
Handle<Object> accessors = lookup->GetAccessors();

View File

@@ -0,0 +1,56 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Georg Neis <neis@chromium.org>
Date: Thu, 9 Sep 2021 14:41:58 +0200
Subject: Merged: [compiler] Fix a bug in global property access reduction
Bug: chromium:1247763
(cherry picked from commit 6391d7a58d0c58cd5d096d22453b954b3ecc6fec)
Change-Id: Ifa775224ed30a2d680c6e3653063483c733de831
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3151960
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Michael Hablich <hablich@chromium.org>
Cr-Commit-Position: refs/branch-heads/9.3@{#37}
Cr-Branched-From: 7744dce208a555494e4a33e24fadc71ea20b3895-refs/heads/9.3.345@{#1}
Cr-Branched-From: 4b6b4cabf3b6a20cdfda72b369df49f3311c4344-refs/heads/master@{#75728}
diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc
index 68d9fa05f0d68270af6e567e152497400d649b0a..1b926c4bcbe98f344952da0f77be52bd0bc1d430 100644
--- a/src/compiler/js-native-context-specialization.cc
+++ b/src/compiler/js-native-context-specialization.cc
@@ -829,6 +829,12 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
return NoChange();
} else if (property_cell_type == PropertyCellType::kUndefined) {
return NoChange();
+ } else if (property_cell_type == PropertyCellType::kConstantType) {
+ // We rely on stability further below.
+ if (property_cell_value.IsHeapObject() &&
+ !property_cell_value.AsHeapObject().map().is_stable()) {
+ return NoChange();
+ }
}
} else if (access_mode == AccessMode::kHas) {
DCHECK_EQ(receiver, lookup_start_object);
@@ -949,17 +955,7 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
if (property_cell_value.IsHeapObject()) {
MapRef property_cell_value_map =
property_cell_value.AsHeapObject().map();
- if (property_cell_value_map.is_stable()) {
- dependencies()->DependOnStableMap(property_cell_value_map);
- } else {
- // The value's map is already unstable. If this store were to go
- // through the C++ runtime, it would transition the PropertyCell to
- // kMutable. We don't want to change the cell type from generated
- // code (to simplify concurrent heap access), however, so we keep
- // it as kConstantType and do the store anyways (if the new value's
- // map matches). This is safe because it merely prolongs the limbo
- // state that we are in already.
- }
+ dependencies()->DependOnStableMap(property_cell_value_map);
// Check that the {value} is a HeapObject.
value = effect = graph()->NewNode(simplified()->CheckHeapObject(),

View File

@@ -0,0 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Georg Neis <neis@chromium.org>
Date: Tue, 10 Aug 2021 09:29:33 +0200
Subject: Merged: [compiler] Harden
JSCallReducer::ReduceArrayIteratorPrototypeNext
Revision: 65b20a0e65e1078f5dd230a5203e231bec790ab4
BUG=chromium:1234764
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
R=vahl@chromium.org
Change-Id: I45faf253695011092de144c8e29bafac5337adec
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3084363
Reviewed-by: Lutz Vahl <vahl@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/branch-heads/9.2@{#53}
Cr-Branched-From: 51238348f95a1f5e0acc321efac7942d18a687a2-refs/heads/9.2.230@{#1}
Cr-Branched-From: 587a04f02ab0487d194b55a7137dc2045e071597-refs/heads/master@{#74656}
diff --git a/src/compiler/js-call-reducer.cc b/src/compiler/js-call-reducer.cc
index 2c7b6788953092ffb3cf6fa75501dcbb02dce581..56f0ca99e252e715c9792222f95397950a451149 100644
--- a/src/compiler/js-call-reducer.cc
+++ b/src/compiler/js-call-reducer.cc
@@ -5854,11 +5854,12 @@ Reduction JSCallReducer::ReduceArrayIteratorPrototypeNext(Node* node) {
Node* etrue = effect;
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
{
- // We know that the {index} is range of the {length} now.
+ // This extra check exists to refine the type of {index} but also to break
+ // an exploitation technique that abuses typer mismatches.
index = etrue = graph()->NewNode(
- common()->TypeGuard(
- Type::Range(0.0, length_access.type.Max() - 1.0, graph()->zone())),
- index, etrue, if_true);
+ simplified()->CheckBounds(p.feedback(),
+ CheckBoundsFlag::kAbortOnOutOfBounds),
+ index, length, etrue, if_true);
done_true = jsgraph()->FalseConstant();
if (iteration_kind == IterationKind::kKeys) {

View File

@@ -0,0 +1,75 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Georg Neis <neis@chromium.org>
Date: Mon, 9 Aug 2021 09:57:12 +0200
Subject: Merged: [compiler] Fix a bug in MachineOperatorReducer's
BitfieldCheck
Revision: 574ca6b71c6160d38b5fcf4b8e133bc7f6ba2387
BUG=chromium:1234770
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
R=nicohartmann@chromium.org
Change-Id: I15af5a94e89b54c2a540442c3544ed459b832e0a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3080564
Reviewed-by: Lutz Vahl <vahl@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/branch-heads/9.3@{#21}
Cr-Branched-From: 7744dce208a555494e4a33e24fadc71ea20b3895-refs/heads/9.3.345@{#1}
Cr-Branched-From: 4b6b4cabf3b6a20cdfda72b369df49f3311c4344-refs/heads/master@{#75728}
diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc
index 918caaf8fd446750d9d4c38350b3af2f25c9a91f..facfadc3ca99f9d2a554f17b577a3833a9974470 100644
--- a/src/compiler/machine-operator-reducer.cc
+++ b/src/compiler/machine-operator-reducer.cc
@@ -1706,11 +1706,21 @@ Reduction MachineOperatorReducer::ReduceWordNAnd(Node* node) {
namespace {
// Represents an operation of the form `(source & mask) == masked_value`.
+// where each bit set in masked_value also has to be set in mask.
struct BitfieldCheck {
- Node* source;
- uint32_t mask;
- uint32_t masked_value;
- bool truncate_from_64_bit;
+ Node* const source;
+ uint32_t const mask;
+ uint32_t const masked_value;
+ bool const truncate_from_64_bit;
+
+ BitfieldCheck(Node* source, uint32_t mask, uint32_t masked_value,
+ bool truncate_from_64_bit)
+ : source(source),
+ mask(mask),
+ masked_value(masked_value),
+ truncate_from_64_bit(truncate_from_64_bit) {
+ CHECK_EQ(masked_value & ~mask, 0);
+ }
static base::Optional<BitfieldCheck> Detect(Node* node) {
// There are two patterns to check for here:
@@ -1725,14 +1735,16 @@ struct BitfieldCheck {
if (eq.left().IsWord32And()) {
Uint32BinopMatcher mand(eq.left().node());
if (mand.right().HasResolvedValue() && eq.right().HasResolvedValue()) {
- BitfieldCheck result{mand.left().node(), mand.right().ResolvedValue(),
- eq.right().ResolvedValue(), false};
+ uint32_t mask = mand.right().ResolvedValue();
+ uint32_t masked_value = eq.right().ResolvedValue();
+ if ((masked_value & ~mask) != 0) return {};
if (mand.left().IsTruncateInt64ToInt32()) {
- result.truncate_from_64_bit = true;
- result.source =
- NodeProperties::GetValueInput(mand.left().node(), 0);
+ return BitfieldCheck(
+ NodeProperties::GetValueInput(mand.left().node(), 0), mask,
+ masked_value, true);
+ } else {
+ return BitfieldCheck(mand.left().node(), mask, masked_value, false);
}
- return result;
}
}
} else {

View File

@@ -0,0 +1,319 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Adam Klein <adamk@chromium.org>
Date: Wed, 29 Sep 2021 14:56:46 -0700
Subject: Merged: [heap] Improve ephemeron processing
Revision: 1054ee7f349d6be22e9518cf9b794b206d0e5818
Bug: chromium:1252918
Change-Id: I0764cb78d4a0d4b5859c0edf383c2827321db398
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3195062
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/branch-heads/9.4@{#37}
Cr-Branched-From: 3b51863bc25492549a8bf96ff67ce481b1a3337b-refs/heads/9.4.146@{#1}
Cr-Branched-From: 2890419fc8fb9bdb507fdd801d76fa7dd9f022b5-refs/heads/master@{#76233}
diff --git a/src/heap/concurrent-marking.cc b/src/heap/concurrent-marking.cc
index 9377dad3e4b9fa313c83ffc0128c39d698d741e5..5aa1eef8abe0dfd250655b92a63c925f5f42462c 100644
--- a/src/heap/concurrent-marking.cc
+++ b/src/heap/concurrent-marking.cc
@@ -426,7 +426,7 @@ void ConcurrentMarking::Run(JobDelegate* delegate,
isolate->PrintWithTimestamp("Starting concurrent marking task %d\n",
task_id);
}
- bool ephemeron_marked = false;
+ bool another_ephemeron_iteration = false;
{
TimedScope scope(&time_ms);
@@ -436,7 +436,7 @@ void ConcurrentMarking::Run(JobDelegate* delegate,
while (weak_objects_->current_ephemerons.Pop(task_id, &ephemeron)) {
if (visitor.ProcessEphemeron(ephemeron.key, ephemeron.value)) {
- ephemeron_marked = true;
+ another_ephemeron_iteration = true;
}
}
}
@@ -477,6 +477,7 @@ void ConcurrentMarking::Run(JobDelegate* delegate,
current_marked_bytes += visited_size;
}
}
+ if (objects_processed > 0) another_ephemeron_iteration = true;
marked_bytes += current_marked_bytes;
base::AsAtomicWord::Relaxed_Store<size_t>(&task_state->marked_bytes,
marked_bytes);
@@ -492,7 +493,7 @@ void ConcurrentMarking::Run(JobDelegate* delegate,
while (weak_objects_->discovered_ephemerons.Pop(task_id, &ephemeron)) {
if (visitor.ProcessEphemeron(ephemeron.key, ephemeron.value)) {
- ephemeron_marked = true;
+ another_ephemeron_iteration = true;
}
}
}
@@ -512,8 +513,8 @@ void ConcurrentMarking::Run(JobDelegate* delegate,
base::AsAtomicWord::Relaxed_Store<size_t>(&task_state->marked_bytes, 0);
total_marked_bytes_ += marked_bytes;
- if (ephemeron_marked) {
- set_ephemeron_marked(true);
+ if (another_ephemeron_iteration) {
+ set_another_ephemeron_iteration(true);
}
}
if (FLAG_trace_concurrent_marking) {
diff --git a/src/heap/concurrent-marking.h b/src/heap/concurrent-marking.h
index c685f5cca6de44ca910c5b19c7dce4aa7412e845..54f6057f58b12354629126380452c29c5427c695 100644
--- a/src/heap/concurrent-marking.h
+++ b/src/heap/concurrent-marking.h
@@ -91,10 +91,12 @@ class V8_EXPORT_PRIVATE ConcurrentMarking {
size_t TotalMarkedBytes();
- void set_ephemeron_marked(bool ephemeron_marked) {
- ephemeron_marked_.store(ephemeron_marked);
+ void set_another_ephemeron_iteration(bool another_ephemeron_iteration) {
+ another_ephemeron_iteration_.store(another_ephemeron_iteration);
+ }
+ bool another_ephemeron_iteration() {
+ return another_ephemeron_iteration_.load();
}
- bool ephemeron_marked() { return ephemeron_marked_.load(); }
private:
struct TaskState {
@@ -115,7 +117,7 @@ class V8_EXPORT_PRIVATE ConcurrentMarking {
WeakObjects* const weak_objects_;
TaskState task_state_[kMaxTasks + 1];
std::atomic<size_t> total_marked_bytes_{0};
- std::atomic<bool> ephemeron_marked_{false};
+ std::atomic<bool> another_ephemeron_iteration_{false};
};
} // namespace internal
diff --git a/src/heap/incremental-marking.cc b/src/heap/incremental-marking.cc
index 7b6b01855d608f6dca506bb91b181525b0394e26..6104f2146c4c91d7e3d92698189db5dc3103ecb3 100644
--- a/src/heap/incremental-marking.cc
+++ b/src/heap/incremental-marking.cc
@@ -927,7 +927,8 @@ StepResult IncrementalMarking::Step(double max_step_size_in_ms,
// This ignores that case where the embedder finds new V8-side objects. The
// assumption is that large graphs are well connected and can mostly be
// processed on their own. For small graphs, helping is not necessary.
- v8_bytes_processed = collector_->ProcessMarkingWorklist(bytes_to_process);
+ std::tie(v8_bytes_processed, std::ignore) =
+ collector_->ProcessMarkingWorklist(bytes_to_process);
StepResult v8_result = local_marking_worklists()->IsEmpty()
? StepResult::kNoImmediateWork
: StepResult::kMoreWorkRemaining;
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index 780d3dc6ca7a936080f817342c066db604b89303..f4e8356823131b4ac39ef37e580dd46cceac30ef 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -1604,24 +1604,24 @@ void MarkCompactCollector::MarkDescriptorArrayFromWriteBarrier(
descriptors, number_of_own_descriptors);
}
-void MarkCompactCollector::ProcessEphemeronsUntilFixpoint() {
- bool work_to_do = true;
+bool MarkCompactCollector::ProcessEphemeronsUntilFixpoint() {
int iterations = 0;
int max_iterations = FLAG_ephemeron_fixpoint_iterations;
- while (work_to_do) {
+ bool another_ephemeron_iteration_main_thread;
+
+ do {
PerformWrapperTracing();
if (iterations >= max_iterations) {
// Give up fixpoint iteration and switch to linear algorithm.
- ProcessEphemeronsLinear();
- break;
+ return false;
}
// Move ephemerons from next_ephemerons into current_ephemerons to
// drain them in this iteration.
weak_objects_.current_ephemerons.Swap(weak_objects_.next_ephemerons);
- heap()->concurrent_marking()->set_ephemeron_marked(false);
+ heap()->concurrent_marking()->set_another_ephemeron_iteration(false);
{
TRACE_GC(heap()->tracer(),
@@ -1632,47 +1632,54 @@ void MarkCompactCollector::ProcessEphemeronsUntilFixpoint() {
TaskPriority::kUserBlocking);
}
- work_to_do = ProcessEphemerons();
+ another_ephemeron_iteration_main_thread = ProcessEphemerons();
FinishConcurrentMarking();
}
CHECK(weak_objects_.current_ephemerons.IsEmpty());
CHECK(weak_objects_.discovered_ephemerons.IsEmpty());
- work_to_do = work_to_do || !local_marking_worklists()->IsEmpty() ||
- heap()->concurrent_marking()->ephemeron_marked() ||
- !local_marking_worklists()->IsEmbedderEmpty() ||
- !heap()->local_embedder_heap_tracer()->IsRemoteTracingDone();
++iterations;
- }
+ } while (another_ephemeron_iteration_main_thread ||
+ heap()->concurrent_marking()->another_ephemeron_iteration() ||
+ !local_marking_worklists()->IsEmpty() ||
+ !local_marking_worklists()->IsEmbedderEmpty() ||
+ !heap()->local_embedder_heap_tracer()->IsRemoteTracingDone());
CHECK(local_marking_worklists()->IsEmpty());
CHECK(weak_objects_.current_ephemerons.IsEmpty());
CHECK(weak_objects_.discovered_ephemerons.IsEmpty());
+ return true;
}
bool MarkCompactCollector::ProcessEphemerons() {
Ephemeron ephemeron;
- bool ephemeron_marked = false;
+ bool another_ephemeron_iteration = false;
// Drain current_ephemerons and push ephemerons where key and value are still
// unreachable into next_ephemerons.
while (weak_objects_.current_ephemerons.Pop(kMainThreadTask, &ephemeron)) {
if (ProcessEphemeron(ephemeron.key, ephemeron.value)) {
- ephemeron_marked = true;
+ another_ephemeron_iteration = true;
}
}
// Drain marking worklist and push discovered ephemerons into
// discovered_ephemerons.
- DrainMarkingWorklist();
+ size_t objects_processed;
+ std::tie(std::ignore, objects_processed) = ProcessMarkingWorklist(0);
+
+ // As soon as a single object was processed and potentially marked another
+ // object we need another iteration. Otherwise we might miss to apply
+ // ephemeron semantics on it.
+ if (objects_processed > 0) another_ephemeron_iteration = true;
// Drain discovered_ephemerons (filled in the drain MarkingWorklist-phase
// before) and push ephemerons where key and value are still unreachable into
// next_ephemerons.
while (weak_objects_.discovered_ephemerons.Pop(kMainThreadTask, &ephemeron)) {
if (ProcessEphemeron(ephemeron.key, ephemeron.value)) {
- ephemeron_marked = true;
+ another_ephemeron_iteration = true;
}
}
@@ -1680,7 +1687,7 @@ bool MarkCompactCollector::ProcessEphemerons() {
weak_objects_.ephemeron_hash_tables.FlushToGlobal(kMainThreadTask);
weak_objects_.next_ephemerons.FlushToGlobal(kMainThreadTask);
- return ephemeron_marked;
+ return another_ephemeron_iteration;
}
void MarkCompactCollector::ProcessEphemeronsLinear() {
@@ -1766,6 +1773,12 @@ void MarkCompactCollector::ProcessEphemeronsLinear() {
ephemeron_marking_.newly_discovered.shrink_to_fit();
CHECK(local_marking_worklists()->IsEmpty());
+ CHECK(weak_objects_.current_ephemerons.IsEmpty());
+ CHECK(weak_objects_.discovered_ephemerons.IsEmpty());
+
+ // Flush local ephemerons for main task to global pool.
+ weak_objects_.ephemeron_hash_tables.FlushToGlobal(kMainThreadTask);
+ weak_objects_.next_ephemerons.FlushToGlobal(kMainThreadTask);
}
void MarkCompactCollector::PerformWrapperTracing() {
@@ -1787,9 +1800,11 @@ void MarkCompactCollector::PerformWrapperTracing() {
void MarkCompactCollector::DrainMarkingWorklist() { ProcessMarkingWorklist(0); }
template <MarkCompactCollector::MarkingWorklistProcessingMode mode>
-size_t MarkCompactCollector::ProcessMarkingWorklist(size_t bytes_to_process) {
+std::pair<size_t, size_t> MarkCompactCollector::ProcessMarkingWorklist(
+ size_t bytes_to_process) {
HeapObject object;
size_t bytes_processed = 0;
+ size_t objects_processed = 0;
bool is_per_context_mode = local_marking_worklists()->IsPerContextMode();
Isolate* isolate = heap()->isolate();
while (local_marking_worklists()->Pop(&object) ||
@@ -1829,18 +1844,19 @@ size_t MarkCompactCollector::ProcessMarkingWorklist(size_t bytes_to_process) {
map, object, visited_size);
}
bytes_processed += visited_size;
+ objects_processed++;
if (bytes_to_process && bytes_processed >= bytes_to_process) {
break;
}
}
- return bytes_processed;
+ return std::make_pair(bytes_processed, objects_processed);
}
// Generate definitions for use in other files.
-template size_t MarkCompactCollector::ProcessMarkingWorklist<
+template std::pair<size_t, size_t> MarkCompactCollector::ProcessMarkingWorklist<
MarkCompactCollector::MarkingWorklistProcessingMode::kDefault>(
size_t bytes_to_process);
-template size_t MarkCompactCollector::ProcessMarkingWorklist<
+template std::pair<size_t, size_t> MarkCompactCollector::ProcessMarkingWorklist<
MarkCompactCollector::MarkingWorklistProcessingMode::
kTrackNewlyDiscoveredObjects>(size_t bytes_to_process);
@@ -1865,7 +1881,23 @@ void MarkCompactCollector::ProcessEphemeronMarking() {
// buffer, flush it into global pool.
weak_objects_.next_ephemerons.FlushToGlobal(kMainThreadTask);
- ProcessEphemeronsUntilFixpoint();
+ if (!ProcessEphemeronsUntilFixpoint()) {
+ // Fixpoint iteration needed too many iterations and was cancelled. Use the
+ // guaranteed linear algorithm.
+ ProcessEphemeronsLinear();
+ }
+
+#ifdef VERIFY_HEAP
+ if (FLAG_verify_heap) {
+ Ephemeron ephemeron;
+
+ weak_objects_.current_ephemerons.Swap(weak_objects_.next_ephemerons);
+
+ while (weak_objects_.current_ephemerons.Pop(kMainThreadTask, &ephemeron)) {
+ CHECK(!ProcessEphemeron(ephemeron.key, ephemeron.value));
+ }
+ }
+#endif
CHECK(local_marking_worklists()->IsEmpty());
CHECK(heap()->local_embedder_heap_tracer()->IsRemoteTracingDone());
diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h
index 08d9a5bcb6b444f3ce0f7c66f5be8df9bdd5324e..fbdb74c30c19cae1d0a568178d15666ec9318cc9 100644
--- a/src/heap/mark-compact.h
+++ b/src/heap/mark-compact.h
@@ -590,7 +590,7 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
// is drained until it is empty.
template <MarkingWorklistProcessingMode mode =
MarkingWorklistProcessingMode::kDefault>
- size_t ProcessMarkingWorklist(size_t bytes_to_process);
+ std::pair<size_t, size_t> ProcessMarkingWorklist(size_t bytes_to_process);
private:
void ComputeEvacuationHeuristics(size_t area_size,
@@ -636,8 +636,9 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
bool ProcessEphemeron(HeapObject key, HeapObject value);
// Marks ephemerons and drains marking worklist iteratively
- // until a fixpoint is reached.
- void ProcessEphemeronsUntilFixpoint();
+ // until a fixpoint is reached. Returns false if too many iterations have been
+ // tried and the linear approach should be used.
+ bool ProcessEphemeronsUntilFixpoint();
// Drains ephemeron and marking worklists. Single iteration of the
// fixpoint iteration.

View File

@@ -0,0 +1,77 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marja=20H=C3=B6ltt=C3=A4?= <marja@chromium.org>
Date: Fri, 3 Sep 2021 11:46:26 +0200
Subject: Fix class variable redeclaration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
ParserBase::ParseClassLiteral and BaseConsumedPreparseData::RestoreDataForScope
both declare the class variable, but the logic is so complex
that they sometimes ended up both declaring it.
This is further complicated by some of the variable values (esp.
inner_scope_calls_eval_) potentially changing in between, so we can't
just redo the same logic any more.
Forcefully make it work by making RestoreDataForScope declare the variable
iff ParseClassLiteral didn't.
Bug: chromium:1245870
Change-Id: I777fd9d78145240448fc25709d2b118977d91056
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3140596
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76654}
diff --git a/src/parsing/preparse-data.cc b/src/parsing/preparse-data.cc
index aa49b55227cdc8e4016a80a76111a8c1e06fd070..40e2a250921b95ef3eb80ce45593929113814a93 100644
--- a/src/parsing/preparse-data.cc
+++ b/src/parsing/preparse-data.cc
@@ -666,12 +666,13 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope(
scope->AsDeclarationScope()->RecordNeedsPrivateNameContextChainRecalc();
}
if (ShouldSaveClassVariableIndexField::decode(scope_data_flags)) {
- Variable* var;
- // An anonymous class whose class variable needs to be saved do not
+ Variable* var = scope->AsClassScope()->class_variable();
+ // An anonymous class whose class variable needs to be saved might not
// have the class variable created during reparse since we skip parsing
// the inner scopes that contain potential access to static private
// methods. So create it now.
- if (scope->AsClassScope()->is_anonymous_class()) {
+ if (var == nullptr) {
+ DCHECK(scope->AsClassScope()->is_anonymous_class());
var = scope->AsClassScope()->DeclareClassVariable(
ast_value_factory, nullptr, kNoSourcePosition);
AstNodeFactory factory(ast_value_factory, zone);
@@ -679,9 +680,6 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope(
factory.NewVariableDeclaration(kNoSourcePosition);
scope->declarations()->Add(declaration);
declaration->set_var(var);
- } else {
- var = scope->AsClassScope()->class_variable();
- DCHECK_NOT_NULL(var);
}
var->set_is_used();
var->ForceContextAllocation();
diff --git a/test/mjsunit/regress/regress-crbug-1245870.js b/test/mjsunit/regress/regress-crbug-1245870.js
new file mode 100644
index 0000000000000000000000000000000000000000..2ef3f753d500880717f10f26ed8cca4a47079196
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-1245870.js
@@ -0,0 +1,14 @@
+// Copyright 2021 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+class Outer {
+ test() {
+ return class {
+ static #a() { }
+ b = eval();
+ };
+ }
+}
+const obj = new Outer();
+obj.test();

View File

@@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mythri A <mythria@chromium.org>
Date: Fri, 21 May 2021 11:12:41 +0100
Subject: Return early when initializing feedback cell for AsmWasm functions
AsmWasmFunctions don't allocate / use feedback vectors.
Bug: chromium:1206289
Change-Id: I970d5eaba6603809a844c2fc5753efba411cd719
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2909854
Commit-Queue: Mythri Alle <mythria@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74708}
diff --git a/src/objects/js-function.cc b/src/objects/js-function.cc
index 2e657d28266e8b8cb3f6db0ba268d34d6818c784..2247c608762034508561f7bda9a320f9e916992c 100644
--- a/src/objects/js-function.cc
+++ b/src/objects/js-function.cc
@@ -314,6 +314,14 @@ void JSFunction::EnsureFeedbackVector(Handle<JSFunction> function,
void JSFunction::InitializeFeedbackCell(Handle<JSFunction> function,
IsCompiledScope* is_compiled_scope) {
Isolate* const isolate = function->GetIsolate();
+#if V8_ENABLE_WEBASSEMBLY
+ // The following checks ensure that the feedback vectors are compatible with
+ // the feedback metadata. For Asm / Wasm functions we never allocate / use
+ // feedback vectors, so a mismatch between the metadata and feedback vector is
+ // harmless. The checks could fail for functions that has has_asm_wasm_broken
+ // set at runtime (for ex: failed instantiation).
+ if (function->shared().HasAsmWasmData()) return;
+#endif // V8_ENABLE_WEBASSEMBLY
if (function->has_feedback_vector()) {
CHECK_EQ(function->feedback_vector().length(),

View File

@@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Toon Verwaest <verwaest@chromium.org>
Date: Wed, 27 Oct 2021 11:02:06 +0200
Subject: Merged: [runtime] Check if we have a pending exception before
returning it
Revision: be55c16e50e714475034b00ed2682f0813794d15
BUG=chromium:1263462
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
R=cbruni@chromium.org
Change-Id: Ib7de676fe614403674fcd2745c574f7e91ded23f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3247033
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/branch-heads/9.4@{#52}
Cr-Branched-From: 3b51863bc25492549a8bf96ff67ce481b1a3337b-refs/heads/9.4.146@{#1}
Cr-Branched-From: 2890419fc8fb9bdb507fdd801d76fa7dd9f022b5-refs/heads/master@{#76233}
diff --git a/src/execution/isolate-inl.h b/src/execution/isolate-inl.h
index aa477913b6dd13a0bd38e74b50766aa66139128d..83da2ecd9dd6f0efedffe9d5edfc83ec7ac86e53 100644
--- a/src/execution/isolate-inl.h
+++ b/src/execution/isolate-inl.h
@@ -33,7 +33,7 @@ NativeContext Isolate::raw_native_context() {
}
Object Isolate::pending_exception() {
- DCHECK(has_pending_exception());
+ CHECK(has_pending_exception());
DCHECK(!thread_local_top()->pending_exception_.IsException(this));
return thread_local_top()->pending_exception_;
}

View File

@@ -0,0 +1,143 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Lippautz <mlippautz@chromium.org>
Date: Wed, 20 Oct 2021 10:10:56 +0200
Subject: Merged: cppgc: Fix marking of ephemerons with keys in construction
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Revision: 32a09a6bce6cc75806dee5ec748bb1d081048fd0
BUG=chromium:1259587
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
R=dinfuehr@chromium.org
Change-Id: Ief330b4b71705c16bc61a3aca6d3aa1db172cdf3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3234200
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/branch-heads/9.4@{#46}
Cr-Branched-From: 3b51863bc25492549a8bf96ff67ce481b1a3337b-refs/heads/9.4.146@{#1}
Cr-Branched-From: 2890419fc8fb9bdb507fdd801d76fa7dd9f022b5-refs/heads/master@{#76233}
diff --git a/src/heap/cppgc/marker.cc b/src/heap/cppgc/marker.cc
index f6c0e74f625fde2c31031cc1795fbd83c3bbea07..82f3442e54a72e2f43069e1993f7a3c3c6c165d8 100644
--- a/src/heap/cppgc/marker.cc
+++ b/src/heap/cppgc/marker.cc
@@ -237,6 +237,7 @@ void MarkerBase::EnterAtomicPause(MarkingConfig::StackState stack_state) {
}
config_.stack_state = stack_state;
config_.marking_type = MarkingConfig::MarkingType::kAtomic;
+ mutator_marking_state_.set_in_atomic_pause();
// Lock guards against changes to {Weak}CrossThreadPersistent handles, that
// may conflict with marking. E.g., a WeakCrossThreadPersistent may be
diff --git a/src/heap/cppgc/marking-state.h b/src/heap/cppgc/marking-state.h
index 65185c36e2babe145a27076cf1c76a12a7c880a1..39615474e4776281e48f8e6a504ba39165966d90 100644
--- a/src/heap/cppgc/marking-state.h
+++ b/src/heap/cppgc/marking-state.h
@@ -8,6 +8,7 @@
#include <algorithm>
#include "include/cppgc/trace-trait.h"
+#include "src/base/logging.h"
#include "src/heap/cppgc/compaction-worklists.h"
#include "src/heap/cppgc/globals.h"
#include "src/heap/cppgc/heap-object-header.h"
@@ -109,6 +110,8 @@ class MarkingStateBase {
movable_slots_worklist_.reset();
}
+ void set_in_atomic_pause() { in_atomic_pause_ = true; }
+
protected:
inline void MarkAndPush(HeapObjectHeader&, TraceDescriptor);
@@ -142,6 +145,7 @@ class MarkingStateBase {
movable_slots_worklist_;
size_t marked_bytes_ = 0;
+ bool in_atomic_pause_ = false;
};
MarkingStateBase::MarkingStateBase(HeapBase& heap,
@@ -267,10 +271,19 @@ void MarkingStateBase::ProcessWeakContainer(const void* object,
void MarkingStateBase::ProcessEphemeron(const void* key,
TraceDescriptor value_desc) {
- // Filter out already marked keys. The write barrier for WeakMember
- // ensures that any newly set value after this point is kept alive and does
- // not require the callback.
- if (HeapObjectHeader::FromPayload(key).IsMarked<AccessMode::kAtomic>()) {
+ // Keys are considered live even in incremental/concurrent marking settings
+ // because the write barrier for WeakMember ensures that any newly set value
+ // after this point is kept alive and does not require the callback.
+ const bool key_in_construction =
+ HeapObjectHeader::FromPayload(key).IsInConstruction<AccessMode::kAtomic>();
+ const bool key_considered_as_live =
+ key_in_construction
+ ? in_atomic_pause_
+ : HeapObjectHeader::FromPayload(key).IsMarked<AccessMode::kAtomic>();
+ DCHECK_IMPLIES(
+ key_in_construction && in_atomic_pause_,
+ HeapObjectHeader::FromPayload(key).IsMarked<AccessMode::kAtomic>());
+ if (key_considered_as_live) {
MarkAndPush(value_desc.base_object_payload, value_desc);
return;
}
diff --git a/test/unittests/heap/cppgc/ephemeron-pair-unittest.cc b/test/unittests/heap/cppgc/ephemeron-pair-unittest.cc
index 1172eedb866c7a1a4723fd96ce9070219deec32e..3d2b2e7bc3e47921632f406aba1f6472cb747b6d 100644
--- a/test/unittests/heap/cppgc/ephemeron-pair-unittest.cc
+++ b/test/unittests/heap/cppgc/ephemeron-pair-unittest.cc
@@ -108,5 +108,50 @@ TEST_F(EhpemeronPairTest, ValueNotMarkedBeforeKey) {
EXPECT_TRUE(HeapObjectHeader::FromPayload(value).IsMarked());
}
+namespace {
+
+class KeyWithCallback final : public GarbageCollected<KeyWithCallback> {
+ public:
+ template <typename Callback>
+ explicit KeyWithCallback(Callback callback) {
+ callback(this);
+ }
+ void Trace(Visitor*) const {}
+};
+
+class EphemeronHolderForKeyWithCallback final
+ : public GarbageCollected<EphemeronHolderForKeyWithCallback> {
+ public:
+ EphemeronHolderForKeyWithCallback(KeyWithCallback* key, GCed* value)
+ : ephemeron_pair_(key, value) {}
+ void Trace(cppgc::Visitor* visitor) const { visitor->Trace(ephemeron_pair_); }
+
+ private:
+ const EphemeronPair<KeyWithCallback, GCed> ephemeron_pair_;
+};
+
+} // namespace
+
+TEST_F(EphemeronPairTest, EphemeronPairWithKeyInConstruction) {
+ GCed* value = MakeGarbageCollected<GCed>(GetAllocationHandle());
+ Persistent<EphemeronHolderForKeyWithCallback> holder;
+ InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get());
+ FinishSteps();
+ MakeGarbageCollected<KeyWithCallback>(
+ GetAllocationHandle(), [this, &holder, value](KeyWithCallback* thiz) {
+ // The test doesn't use conservative stack scanning to retain key to
+ // avoid retaining value as a side effect.
+ EXPECT_TRUE(HeapObjectHeader::FromObject(thiz).TryMarkAtomic());
+ holder = MakeGarbageCollected<EphemeronHolderForKeyWithCallback>(
+ GetAllocationHandle(), thiz, value);
+ // Finishing marking at this point will leave an ephemeron pair
+ // reachable where the key is still in construction. The GC needs to
+ // mark the value for such pairs as live in the atomic pause as they key
+ // is considered live.
+ FinishMarking();
+ });
+ EXPECT_TRUE(HeapObjectHeader::FromObject(value).IsMarked());
+}
+
} // namespace internal
} // namespace cppgc

1
patches/webrtc/.patches Normal file
View File

@@ -0,0 +1 @@
merge_to_94_add_direction_indicator_to_transformableframes.patch

View File

@@ -0,0 +1,222 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tony Herre <toprice@chromium.org>
Date: Mon, 4 Oct 2021 10:02:51 +0000
Subject: Add Direction indicator to TransformableFrames
Currently the implementation of FrameTransformers uses distinct,
incompatible types for recevied vs about-to-be-sent frames. This adds a
flag in the interface so we can at least check that we are being given
the correct type. crbug.com/1250638 tracks removing the need for this.
Chrome will be updated after this to check the direction flag and provide
a javascript error if the wrong type of frame is written into the
encoded insertable streams writable stream, rather than crashing.
(cherry picked from commit 8fb41a39e1a2d151d1c00c409630dcee80adeb76)
Bug: chromium:1247260
Change-Id: I9cbb66962ea0718ed47c5e5dba19a8ff9635b0b1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232301
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Tony Herre <toprice@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#35100}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/233943
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/branch-heads/4606@{#4}
Cr-Branched-From: 8b18304e66524060eca390f143033ba51322b3a2-refs/heads/master@{#34737}
diff --git a/api/frame_transformer_interface.h b/api/frame_transformer_interface.h
index 2cfe6edb884b53b0b3fa87afad264aa411d112bd..d04acc098cb564c161f87c87d68511429895757c 100644
--- a/api/frame_transformer_interface.h
+++ b/api/frame_transformer_interface.h
@@ -35,6 +35,16 @@ class TransformableFrameInterface {
virtual uint32_t GetTimestamp() const = 0;
virtual uint32_t GetSsrc() const = 0;
+
+ enum class Direction {
+ kUnknown,
+ kReceiver,
+ kSender,
+ };
+ // TODO(crbug.com/1250638): Remove this distinction between receiver and
+ // sender frames to allow received frames to be directly re-transmitted on
+ // other PeerConnectionss.
+ virtual Direction GetDirection() const { return Direction::kUnknown; }
};
class TransformableVideoFrameInterface : public TransformableFrameInterface {
diff --git a/audio/channel_receive_frame_transformer_delegate.cc b/audio/channel_receive_frame_transformer_delegate.cc
index 261afbb10075c443b8627846a8434d7ef5b19a15..ec744bc61e28a8b72a6c6bb78893962cdd5f22e2 100644
--- a/audio/channel_receive_frame_transformer_delegate.cc
+++ b/audio/channel_receive_frame_transformer_delegate.cc
@@ -18,15 +18,16 @@
namespace webrtc {
namespace {
-class TransformableAudioFrame : public TransformableAudioFrameInterface {
+class TransformableIncomingAudioFrame
+ : public TransformableAudioFrameInterface {
public:
- TransformableAudioFrame(rtc::ArrayView<const uint8_t> payload,
- const RTPHeader& header,
- uint32_t ssrc)
+ TransformableIncomingAudioFrame(rtc::ArrayView<const uint8_t> payload,
+ const RTPHeader& header,
+ uint32_t ssrc)
: payload_(payload.data(), payload.size()),
header_(header),
ssrc_(ssrc) {}
- ~TransformableAudioFrame() override = default;
+ ~TransformableIncomingAudioFrame() override = default;
rtc::ArrayView<const uint8_t> GetData() const override { return payload_; }
void SetData(rtc::ArrayView<const uint8_t> data) override {
@@ -36,6 +37,7 @@ class TransformableAudioFrame : public TransformableAudioFrameInterface {
uint32_t GetTimestamp() const override { return header_.timestamp; }
uint32_t GetSsrc() const override { return ssrc_; }
const RTPHeader& GetHeader() const override { return header_; }
+ Direction GetDirection() const override { return Direction::kReceiver; }
private:
rtc::Buffer payload_;
@@ -71,7 +73,7 @@ void ChannelReceiveFrameTransformerDelegate::Transform(
uint32_t ssrc) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
frame_transformer_->Transform(
- std::make_unique<TransformableAudioFrame>(packet, header, ssrc));
+ std::make_unique<TransformableIncomingAudioFrame>(packet, header, ssrc));
}
void ChannelReceiveFrameTransformerDelegate::OnTransformedFrame(
@@ -88,7 +90,10 @@ void ChannelReceiveFrameTransformerDelegate::ReceiveFrame(
RTC_DCHECK_RUN_ON(&sequence_checker_);
if (!receive_frame_callback_)
return;
- auto* transformed_frame = static_cast<TransformableAudioFrame*>(frame.get());
+ RTC_CHECK_EQ(frame->GetDirection(),
+ TransformableFrameInterface::Direction::kReceiver);
+ auto* transformed_frame =
+ static_cast<TransformableIncomingAudioFrame*>(frame.get());
receive_frame_callback_(transformed_frame->GetData(),
transformed_frame->GetHeader());
}
diff --git a/audio/channel_send_frame_transformer_delegate.cc b/audio/channel_send_frame_transformer_delegate.cc
index 72a459d89783f9b7bc498aabc15cd7c7b45f3783..5597e7553e956c9dc20e311f5e16d163d9a7119e 100644
--- a/audio/channel_send_frame_transformer_delegate.cc
+++ b/audio/channel_send_frame_transformer_delegate.cc
@@ -15,16 +15,16 @@
namespace webrtc {
namespace {
-class TransformableAudioFrame : public TransformableFrameInterface {
+class TransformableOutgoingAudioFrame : public TransformableFrameInterface {
public:
- TransformableAudioFrame(AudioFrameType frame_type,
- uint8_t payload_type,
- uint32_t rtp_timestamp,
- uint32_t rtp_start_timestamp,
- const uint8_t* payload_data,
- size_t payload_size,
- int64_t absolute_capture_timestamp_ms,
- uint32_t ssrc)
+ TransformableOutgoingAudioFrame(AudioFrameType frame_type,
+ uint8_t payload_type,
+ uint32_t rtp_timestamp,
+ uint32_t rtp_start_timestamp,
+ const uint8_t* payload_data,
+ size_t payload_size,
+ int64_t absolute_capture_timestamp_ms,
+ uint32_t ssrc)
: frame_type_(frame_type),
payload_type_(payload_type),
rtp_timestamp_(rtp_timestamp),
@@ -32,7 +32,7 @@ class TransformableAudioFrame : public TransformableFrameInterface {
payload_(payload_data, payload_size),
absolute_capture_timestamp_ms_(absolute_capture_timestamp_ms),
ssrc_(ssrc) {}
- ~TransformableAudioFrame() override = default;
+ ~TransformableOutgoingAudioFrame() override = default;
rtc::ArrayView<const uint8_t> GetData() const override { return payload_; }
void SetData(rtc::ArrayView<const uint8_t> data) override {
payload_.SetData(data.data(), data.size());
@@ -48,6 +48,7 @@ class TransformableAudioFrame : public TransformableFrameInterface {
int64_t GetAbsoluteCaptureTimestampMs() const {
return absolute_capture_timestamp_ms_;
}
+ Direction GetDirection() const override { return Direction::kSender; }
private:
AudioFrameType frame_type_;
@@ -90,9 +91,10 @@ void ChannelSendFrameTransformerDelegate::Transform(
size_t payload_size,
int64_t absolute_capture_timestamp_ms,
uint32_t ssrc) {
- frame_transformer_->Transform(std::make_unique<TransformableAudioFrame>(
- frame_type, payload_type, rtp_timestamp, rtp_start_timestamp,
- payload_data, payload_size, absolute_capture_timestamp_ms, ssrc));
+ frame_transformer_->Transform(
+ std::make_unique<TransformableOutgoingAudioFrame>(
+ frame_type, payload_type, rtp_timestamp, rtp_start_timestamp,
+ payload_data, payload_size, absolute_capture_timestamp_ms, ssrc));
}
void ChannelSendFrameTransformerDelegate::OnTransformedFrame(
@@ -111,9 +113,12 @@ void ChannelSendFrameTransformerDelegate::SendFrame(
std::unique_ptr<TransformableFrameInterface> frame) const {
MutexLock lock(&send_lock_);
RTC_DCHECK_RUN_ON(encoder_queue_);
+ RTC_CHECK_EQ(frame->GetDirection(),
+ TransformableFrameInterface::Direction::kSender);
if (!send_frame_callback_)
return;
- auto* transformed_frame = static_cast<TransformableAudioFrame*>(frame.get());
+ auto* transformed_frame =
+ static_cast<TransformableOutgoingAudioFrame*>(frame.get());
send_frame_callback_(transformed_frame->GetFrameType(),
transformed_frame->GetPayloadType(),
transformed_frame->GetTimestamp() -
diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc
index 074b64086a6cb2ff5014319b53305dd8385d8de6..8fe275e71984983fa248c1b9fb6e66c90a91ed3f 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc
@@ -75,6 +75,8 @@ class TransformableVideoSenderFrame : public TransformableVideoFrameInterface {
return expected_retransmission_time_ms_;
}
+ Direction GetDirection() const override { return Direction::kSender; }
+
private:
rtc::scoped_refptr<EncodedImageBufferInterface> encoded_data_;
const RTPVideoHeader header_;
@@ -143,6 +145,8 @@ void RTPSenderVideoFrameTransformerDelegate::OnTransformedFrame(
void RTPSenderVideoFrameTransformerDelegate::SendVideo(
std::unique_ptr<TransformableFrameInterface> transformed_frame) const {
RTC_CHECK(encoder_queue_->IsCurrent());
+ RTC_CHECK_EQ(transformed_frame->GetDirection(),
+ TransformableFrameInterface::Direction::kSender);
MutexLock lock(&sender_lock_);
if (!sender_)
return;
diff --git a/video/rtp_video_stream_receiver_frame_transformer_delegate.cc b/video/rtp_video_stream_receiver_frame_transformer_delegate.cc
index 31eb344d5b6ca9664297004aea469398ac578479..69a64ffaa9e852949663703a64429cd0cafdd838 100644
--- a/video/rtp_video_stream_receiver_frame_transformer_delegate.cc
+++ b/video/rtp_video_stream_receiver_frame_transformer_delegate.cc
@@ -59,6 +59,8 @@ class TransformableVideoReceiverFrame
return std::move(frame_);
}
+ Direction GetDirection() const override { return Direction::kReceiver; }
+
private:
std::unique_ptr<video_coding::RtpFrameObject> frame_;
const VideoFrameMetadata metadata_;
@@ -111,6 +113,8 @@ void RtpVideoStreamReceiverFrameTransformerDelegate::OnTransformedFrame(
void RtpVideoStreamReceiverFrameTransformerDelegate::ManageFrame(
std::unique_ptr<TransformableFrameInterface> frame) {
RTC_DCHECK_RUN_ON(&network_sequence_checker_);
+ RTC_CHECK_EQ(frame->GetDirection(),
+ TransformableFrameInterface::Direction::kReceiver);
if (!receiver_)
return;
auto transformed_frame = absl::WrapUnique(

View File

@@ -74,6 +74,7 @@
#include "mojo/public/cpp/system/platform_handle.h"
#include "ppapi/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "shell/browser/api/electron_api_browser_window.h"
#include "shell/browser/api/electron_api_debugger.h"
@@ -101,6 +102,7 @@
#include "shell/browser/web_view_guest_delegate.h"
#include "shell/browser/web_view_manager.h"
#include "shell/common/api/electron_api_native_image.h"
#include "shell/common/api/electron_bindings.h"
#include "shell/common/color_util.h"
#include "shell/common/electron_constants.h"
#include "shell/common/gin_converters/base_converter.h"
@@ -906,6 +908,12 @@ void WebContents::InitWithWebContents(content::WebContents* web_contents,
}
WebContents::~WebContents() {
// clear out objects that have been granted permissions so that when
// WebContents::RenderFrameDeleted is called as a result of WebContents
// destruction it doesn't try to clear out a granted_devices_
// on a destructed object.
granted_devices_.clear();
MarkDestroyed();
// The destroy() is called.
if (inspectable_web_contents_) {
@@ -1230,31 +1238,29 @@ void WebContents::OnEnterFullscreenModeForTab(
content::RenderFrameHost* requesting_frame,
const blink::mojom::FullscreenOptions& options,
bool allowed) {
if (!allowed)
return;
if (!owner_window_)
if (!allowed || !owner_window_)
return;
auto* source = content::WebContents::FromRenderFrameHost(requesting_frame);
if (IsFullscreenForTabOrPending(source)) {
DCHECK_EQ(fullscreen_frame_, source->GetFocusedFrame());
return;
}
SetHtmlApiFullscreen(true);
owner_window_->NotifyWindowEnterHtmlFullScreen();
if (native_fullscreen_) {
// Explicitly trigger a view resize, as the size is not actually changing if
// the browser is fullscreened, too.
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
}
Emit("enter-html-full-screen");
}
void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
if (!owner_window_)
return;
SetHtmlApiFullscreen(false);
owner_window_->NotifyWindowLeaveHtmlFullScreen();
if (native_fullscreen_) {
// Explicitly trigger a view resize, as the size is not actually changing if
@@ -1262,7 +1268,6 @@ void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
// `chrome/browser/ui/exclusive_access/fullscreen_controller.cc`.
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
}
Emit("leave-html-full-screen");
}
void WebContents::RendererUnresponsive(
@@ -1641,6 +1646,11 @@ void WebContents::UpdateDraggableRegions(
void WebContents::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) {
// clear out objects that have been granted permissions
if (!granted_devices_.empty()) {
granted_devices_.erase(render_frame_host->GetFrameTreeNodeId());
}
// A WebFrameMain can outlive its RenderFrameHost so we need to mark it as
// disposed to prevent access to it.
WebFrameMain::RenderFrameDeleted(render_frame_host);
@@ -3142,6 +3152,26 @@ void WebContents::NotifyUserActivation() {
blink::mojom::UserActivationNotificationType::kInteraction);
}
v8::Local<v8::Promise> WebContents::GetProcessMemoryInfo(v8::Isolate* isolate) {
gin_helper::Promise<gin_helper::Dictionary> promise(isolate);
v8::Local<v8::Promise> handle = promise.GetHandle();
auto* frame_host = web_contents()->GetMainFrame();
if (!frame_host) {
promise.RejectWithErrorMessage("Failed to create memory dump");
return handle;
}
auto pid = frame_host->GetProcess()->GetProcess().Pid();
v8::Global<v8::Context> context(isolate, isolate->GetCurrentContext());
memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDumpForPid(
pid, std::vector<std::string>(),
base::BindOnce(&ElectronBindings::DidReceiveMemoryDump,
std::move(context), std::move(promise), pid));
return handle;
}
v8::Local<v8::Promise> WebContents::TakeHeapSnapshot(
v8::Isolate* isolate,
const base::FilePath& file_path) {
@@ -3190,6 +3220,42 @@ v8::Local<v8::Promise> WebContents::TakeHeapSnapshot(
return handle;
}
void WebContents::GrantDevicePermission(
const url::Origin& origin,
const base::Value* device,
content::PermissionType permissionType,
content::RenderFrameHost* render_frame_host) {
granted_devices_[render_frame_host->GetFrameTreeNodeId()][permissionType]
[origin]
.push_back(
std::make_unique<base::Value>(device->Clone()));
}
std::vector<base::Value> WebContents::GetGrantedDevices(
const url::Origin& origin,
content::PermissionType permissionType,
content::RenderFrameHost* render_frame_host) {
const auto& devices_for_frame_host_it =
granted_devices_.find(render_frame_host->GetFrameTreeNodeId());
if (devices_for_frame_host_it == granted_devices_.end())
return {};
const auto& current_devices_it =
devices_for_frame_host_it->second.find(permissionType);
if (current_devices_it == devices_for_frame_host_it->second.end())
return {};
const auto& origin_devices_it = current_devices_it->second.find(origin);
if (origin_devices_it == current_devices_it->second.end())
return {};
std::vector<base::Value> results;
for (const auto& object : origin_devices_it->second)
results.push_back(object->Clone());
return results;
}
void WebContents::UpdatePreferredSize(content::WebContents* web_contents,
const gfx::Size& pref_size) {
Emit("preferred-size-changed", pref_size);
@@ -3585,7 +3651,7 @@ void WebContents::SetHtmlApiFullscreen(bool enter_fullscreen) {
}
void WebContents::UpdateHtmlApiFullscreen(bool fullscreen) {
if (fullscreen == html_fullscreen_)
if (fullscreen == is_html_fullscreen())
return;
html_fullscreen_ = fullscreen;
@@ -3596,11 +3662,19 @@ void WebContents::UpdateHtmlApiFullscreen(bool fullscreen) {
->GetWidget()
->SynchronizeVisualProperties();
// The embedder WebContents is spearated from the frame tree of webview, so
// The embedder WebContents is separated from the frame tree of webview, so
// we must manually sync their fullscreen states.
if (embedder_)
embedder_->SetHtmlApiFullscreen(fullscreen);
if (fullscreen) {
Emit("enter-html-full-screen");
owner_window_->NotifyWindowEnterHtmlFullScreen();
} else {
Emit("leave-html-full-screen");
owner_window_->NotifyWindowLeaveHtmlFullScreen();
}
// Make sure all child webviews quit html fullscreen.
if (!fullscreen && !IsGuest()) {
auto* manager = WebViewManager::GetWebViewManager(web_contents());
@@ -3740,6 +3814,7 @@ v8::Local<v8::ObjectTemplate> WebContents::FillObjectTemplate(
&WebContents::GetWebRTCIPHandlingPolicy)
.SetMethod("_grantOriginAccess", &WebContents::GrantOriginAccess)
.SetMethod("takeHeapSnapshot", &WebContents::TakeHeapSnapshot)
.SetMethod("_getProcessMemoryInfo", &WebContents::GetProcessMemoryInfo)
.SetProperty("id", &WebContents::ID)
.SetProperty("session", &WebContents::Session)
.SetProperty("hostWebContents", &WebContents::HostWebContents)
@@ -3850,6 +3925,16 @@ gin::Handle<WebContents> WebContentsFromID(v8::Isolate* isolate, int32_t id) {
: gin::Handle<WebContents>();
}
gin::Handle<WebContents> WebContentsFromDevToolsTargetID(
v8::Isolate* isolate,
std::string target_id) {
auto agent_host = content::DevToolsAgentHost::GetForId(target_id);
WebContents* contents =
agent_host ? WebContents::From(agent_host->GetWebContents()) : nullptr;
return contents ? gin::CreateHandle(isolate, contents)
: gin::Handle<WebContents>();
}
std::vector<gin::Handle<WebContents>> GetAllWebContentsAsV8(
v8::Isolate* isolate) {
std::vector<gin::Handle<WebContents>> list;
@@ -3868,6 +3953,7 @@ void Initialize(v8::Local<v8::Object> exports,
gin_helper::Dictionary dict(isolate, exports);
dict.Set("WebContents", WebContents::GetConstructor(context));
dict.SetMethod("fromId", &WebContentsFromID);
dict.SetMethod("fromDevToolsTargetId", &WebContentsFromDevToolsTargetID);
dict.SetMethod("getAllWebContents", &GetAllWebContentsAsV8);
}

View File

@@ -20,6 +20,7 @@
#include "content/common/frame.mojom.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/keyboard_event_processing_result.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
@@ -91,6 +92,11 @@ class OffScreenWebContentsView;
namespace api {
using DevicePermissionMap = std::map<
int,
std::map<content::PermissionType,
std::map<url::Origin, std::vector<std::unique_ptr<base::Value>>>>>;
// Wrapper around the content::WebContents.
class WebContents : public gin::Wrappable<WebContents>,
public gin_helper::EventEmitterMixin<WebContents>,
@@ -324,6 +330,7 @@ class WebContents : public gin::Wrappable<WebContents>,
v8::Local<v8::Promise> TakeHeapSnapshot(v8::Isolate* isolate,
const base::FilePath& file_path);
v8::Local<v8::Promise> GetProcessMemoryInfo(v8::Isolate* isolate);
// Properties.
int32_t ID() const { return id_; }
@@ -429,6 +436,21 @@ class WebContents : public gin::Wrappable<WebContents>,
void DoGetZoomLevel(
electron::mojom::ElectronBrowser::DoGetZoomLevelCallback callback);
// Grants |origin| access to |device|.
// To be used in place of ObjectPermissionContextBase::GrantObjectPermission.
void GrantDevicePermission(const url::Origin& origin,
const base::Value* device,
content::PermissionType permissionType,
content::RenderFrameHost* render_frame_host);
// Returns the list of devices that |origin| has been granted permission to
// access. To be used in place of
// ObjectPermissionContextBase::GetGrantedObjects.
std::vector<base::Value> GetGrantedDevices(
const url::Origin& origin,
content::PermissionType permissionType,
content::RenderFrameHost* render_frame_host);
private:
// Does not manage lifetime of |web_contents|.
WebContents(v8::Isolate* isolate, content::WebContents* web_contents);
@@ -784,6 +806,9 @@ class WebContents : public gin::Wrappable<WebContents>,
service_manager::BinderRegistryWithArgs<content::RenderFrameHost*> registry_;
// In-memory cache that holds objects that have been granted permissions.
DevicePermissionMap granted_devices_;
base::WeakPtrFactory<WebContents> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(WebContents);

View File

@@ -15,9 +15,17 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "gin/data_object_builder.h"
#include "shell/browser/api/electron_api_web_contents.h"
#include "shell/browser/electron_browser_client.h"
#include "shell/browser/electron_browser_main_parts.h"
#include "shell/browser/serial/serial_chooser_context.h"
#include "shell/browser/web_contents_permission_helper.h"
#include "shell/browser/web_contents_preferences.h"
#include "shell/common/gin_converters/content_converter.h"
#include "shell/common/gin_converters/frame_converter.h"
#include "shell/common/gin_converters/value_converter.h"
#include "shell/common/gin_helper/event_emitter_caller.h"
namespace electron {
@@ -258,6 +266,65 @@ bool ElectronPermissionManager::CheckPermissionWithDetails(
mutable_details);
}
bool ElectronPermissionManager::CheckDevicePermission(
content::PermissionType permission,
const url::Origin& origin,
const base::Value* device,
content::RenderFrameHost* render_frame_host) const {
auto* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
api::WebContents* api_web_contents = api::WebContents::From(web_contents);
if (api_web_contents) {
std::vector<base::Value> granted_devices =
api_web_contents->GetGrantedDevices(origin, permission,
render_frame_host);
for (const auto& granted_device : granted_devices) {
if (permission ==
static_cast<content::PermissionType>(
WebContentsPermissionHelper::PermissionType::SERIAL)) {
#if defined(OS_WIN)
if (device->FindStringKey(kDeviceInstanceIdKey) ==
granted_device.FindStringKey(kDeviceInstanceIdKey))
return true;
#else
if (device->FindIntKey(kVendorIdKey) !=
granted_device.FindIntKey(kVendorIdKey) ||
device->FindIntKey(kProductIdKey) !=
granted_device.FindIntKey(kProductIdKey) ||
*device->FindStringKey(kSerialNumberKey) !=
*granted_device.FindStringKey(kSerialNumberKey)) {
continue;
}
#if defined(OS_MAC)
if (*device->FindStringKey(kUsbDriverKey) !=
*granted_device.FindStringKey(kUsbDriverKey)) {
continue;
}
#endif // defined(OS_MAC)
return true;
#endif // defined(OS_WIN)
}
}
}
return false;
}
void ElectronPermissionManager::GrantDevicePermission(
content::PermissionType permission,
const url::Origin& origin,
const base::Value* device,
content::RenderFrameHost* render_frame_host) const {
auto* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
api::WebContents* api_web_contents = api::WebContents::From(web_contents);
if (api_web_contents)
api_web_contents->GrantDevicePermission(origin, device, permission,
render_frame_host);
}
blink::mojom::PermissionStatus
ElectronPermissionManager::GetPermissionStatusForFrame(
content::PermissionType permission,

View File

@@ -13,6 +13,7 @@
#include "base/containers/id_map.h"
#include "base/values.h"
#include "content/public/browser/permission_controller_delegate.h"
#include "gin/dictionary.h"
namespace content {
class WebContents;
@@ -77,6 +78,16 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
const GURL& requesting_origin,
const base::DictionaryValue* details) const;
bool CheckDevicePermission(content::PermissionType permission,
const url::Origin& origin,
const base::Value* object,
content::RenderFrameHost* render_frame_host) const;
void GrantDevicePermission(content::PermissionType permission,
const url::Origin& origin,
const base::Value* object,
content::RenderFrameHost* render_frame_host) const;
protected:
void OnPermissionResponse(int request_id,
int permission_id,

View File

@@ -1582,8 +1582,17 @@ void NativeWindowViews::OnMouseEvent(ui::MouseEvent* event) {
}
ui::WindowShowState NativeWindowViews::GetRestoredState() {
if (IsMaximized())
if (IsMaximized()) {
#if defined(OS_WIN)
// Only restore Maximized state when window is NOT transparent style
if (!transparent()) {
return ui::SHOW_STATE_MAXIMIZED;
}
#else
return ui::SHOW_STATE_MAXIMIZED;
#endif
}
if (IsFullscreen())
return ui::SHOW_STATE_FULLSCREEN;

View File

@@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 12,0,17,0
PRODUCTVERSION 12,0,17,0
FILEVERSION 12,2,3,0
PRODUCTVERSION 12,2,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -68,12 +68,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron"
VALUE "FileVersion", "12.0.17"
VALUE "FileVersion", "12.2.3"
VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron"
VALUE "ProductVersion", "12.0.17"
VALUE "ProductVersion", "12.2.3"
VALUE "SquirrelAwareVersion", "1"
END
END

View File

@@ -71,8 +71,7 @@ bool ElectronSerialDelegate::HasPortPermission(
auto* chooser_context =
SerialChooserContextFactory::GetForBrowserContext(browser_context);
return chooser_context->HasPortPermission(
frame->GetLastCommittedOrigin(),
web_contents->GetMainFrame()->GetLastCommittedOrigin(), port);
web_contents->GetMainFrame()->GetLastCommittedOrigin(), port, frame);
}
device::mojom::SerialPortManager* ElectronSerialDelegate::GetPortManager(

View File

@@ -10,22 +10,25 @@
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "content/public/browser/device_service.h"
#include "content/public/browser/web_contents.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "shell/browser/web_contents_permission_helper.h"
namespace electron {
constexpr char kPortNameKey[] = "name";
constexpr char kTokenKey[] = "token";
#if defined(OS_WIN)
constexpr char kDeviceInstanceIdKey[] = "device_instance_id";
const char kDeviceInstanceIdKey[] = "device_instance_id";
#else
constexpr char kVendorIdKey[] = "vendor_id";
constexpr char kProductIdKey[] = "product_id";
constexpr char kSerialNumberKey[] = "serial_number";
const char kVendorIdKey[] = "vendor_id";
const char kProductIdKey[] = "product_id";
const char kSerialNumberKey[] = "serial_number";
#if defined(OS_MAC)
constexpr char kUsbDriverKey[] = "usb_driver";
const char kUsbDriverKey[] = "usb_driver";
#endif // defined(OS_MAC)
#endif // defined(OS_WIN)
#endif // defined(OS_WIN
std::string EncodeToken(const base::UnguessableToken& token) {
const uint64_t data[2] = {token.GetHighForSerialization(),
@@ -81,30 +84,51 @@ base::Value PortInfoToValue(const device::mojom::SerialPortInfo& port) {
}
SerialChooserContext::SerialChooserContext() = default;
SerialChooserContext::~SerialChooserContext() = default;
void SerialChooserContext::GrantPortPermission(
const url::Origin& requesting_origin,
const url::Origin& embedding_origin,
const device::mojom::SerialPortInfo& port) {
const url::Origin& origin,
const device::mojom::SerialPortInfo& port,
content::RenderFrameHost* render_frame_host) {
base::Value value = PortInfoToValue(port);
port_info_.insert({port.token, value.Clone()});
ephemeral_ports_[{requesting_origin, embedding_origin}].insert(port.token);
if (CanStorePersistentEntry(port)) {
auto* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
auto* permission_helper =
WebContentsPermissionHelper::FromWebContents(web_contents);
permission_helper->GrantSerialPortPermission(origin, std::move(value),
render_frame_host);
return;
}
ephemeral_ports_[origin].insert(port.token);
}
bool SerialChooserContext::HasPortPermission(
const url::Origin& requesting_origin,
const url::Origin& embedding_origin,
const device::mojom::SerialPortInfo& port) {
auto it = ephemeral_ports_.find({requesting_origin, embedding_origin});
const url::Origin& origin,
const device::mojom::SerialPortInfo& port,
content::RenderFrameHost* render_frame_host) {
auto it = ephemeral_ports_.find(origin);
if (it != ephemeral_ports_.end()) {
const std::set<base::UnguessableToken> ports = it->second;
if (base::Contains(ports, port.token))
return true;
}
return false;
if (!CanStorePersistentEntry(port)) {
return false;
}
auto* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
auto* permission_helper =
WebContentsPermissionHelper::FromWebContents(web_contents);
base::Value value = PortInfoToValue(port);
return permission_helper->CheckSerialPortPermission(origin, std::move(value),
render_frame_host);
}
// static
@@ -168,14 +192,6 @@ void SerialChooserContext::OnPortRemoved(
for (auto& observer : port_observer_list_)
observer.OnPortRemoved(*port);
std::vector<std::pair<url::Origin, url::Origin>> revoked_url_pairs;
for (auto& map_entry : ephemeral_ports_) {
std::set<base::UnguessableToken>& ports = map_entry.second;
if (ports.erase(port->token) > 0) {
revoked_url_pairs.push_back(map_entry.first);
}
}
port_info_.erase(port->token);
}

View File

@@ -30,6 +30,20 @@ class Value;
namespace electron {
extern const char kHidVendorIdKey[];
extern const char kHidProductIdKey[];
#if defined(OS_WIN)
extern const char kDeviceInstanceIdKey[];
#else
extern const char kVendorIdKey[];
extern const char kProductIdKey[];
extern const char kSerialNumberKey[];
#if defined(OS_MAC)
extern const char kUsbDriverKey[];
#endif // defined(OS_MAC)
#endif // defined(OS_WIN)
class SerialChooserContext : public KeyedService,
public device::mojom::SerialPortManagerClient {
public:
@@ -39,12 +53,12 @@ class SerialChooserContext : public KeyedService,
~SerialChooserContext() override;
// Serial-specific interface for granting and checking permissions.
void GrantPortPermission(const url::Origin& requesting_origin,
const url::Origin& embedding_origin,
const device::mojom::SerialPortInfo& port);
bool HasPortPermission(const url::Origin& requesting_origin,
const url::Origin& embedding_origin,
const device::mojom::SerialPortInfo& port);
void GrantPortPermission(const url::Origin& origin,
const device::mojom::SerialPortInfo& port,
content::RenderFrameHost* render_frame_host);
bool HasPortPermission(const url::Origin& origin,
const device::mojom::SerialPortInfo& port,
content::RenderFrameHost* render_frame_host);
static bool CanStorePersistentEntry(
const device::mojom::SerialPortInfo& port);
@@ -69,11 +83,8 @@ class SerialChooserContext : public KeyedService,
blink::mojom::SerialService::GetPortsCallback callback,
std::vector<device::mojom::SerialPortInfoPtr> ports);
// Tracks the set of ports to which an origin (potentially embedded in another
// origin) has access to. Key is (requesting_origin, embedding_origin).
std::map<std::pair<url::Origin, url::Origin>,
std::set<base::UnguessableToken>>
ephemeral_ports_;
// Tracks the set of ports to which an origin has access to.
std::map<url::Origin, std::set<base::UnguessableToken>> ephemeral_ports_;
// Holds information about ports in |ephemeral_ports_|.
std::map<base::UnguessableToken, base::Value> port_info_;

View File

@@ -67,9 +67,9 @@ SerialChooserController::SerialChooserController(
: WebContentsObserver(web_contents),
filters_(std::move(filters)),
callback_(std::move(callback)),
serial_delegate_(serial_delegate) {
requesting_origin_ = render_frame_host->GetLastCommittedOrigin();
embedding_origin_ = web_contents->GetMainFrame()->GetLastCommittedOrigin();
serial_delegate_(serial_delegate),
render_frame_host_id_(render_frame_host->GetGlobalFrameRoutingId()) {
origin_ = web_contents->GetMainFrame()->GetLastCommittedOrigin();
chooser_context_ = SerialChooserContextFactory::GetForBrowserContext(
web_contents->GetBrowserContext())
@@ -125,8 +125,8 @@ void SerialChooserController::OnDeviceChosen(const std::string& port_id) {
return ptr->token.ToString() == port_id;
});
if (it != ports_.end()) {
chooser_context_->GrantPortPermission(requesting_origin_,
embedding_origin_, *it->get());
auto* rfh = content::RenderFrameHost::FromID(render_frame_host_id_);
chooser_context_->GrantPortPermission(origin_, *it->get(), rfh);
RunCallback(it->Clone());
} else {
RunCallback(/*port=*/nullptr);

View File

@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/serial_chooser.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
@@ -54,8 +55,7 @@ class SerialChooserController final : public SerialChooserContext::PortObserver,
std::vector<blink::mojom::SerialPortFilterPtr> filters_;
content::SerialChooser::Callback callback_;
url::Origin requesting_origin_;
url::Origin embedding_origin_;
url::Origin origin_;
base::WeakPtr<SerialChooserContext> chooser_context_;
@@ -63,6 +63,8 @@ class SerialChooserController final : public SerialChooserContext::PortObserver,
base::WeakPtr<ElectronSerialDelegate> serial_delegate_;
content::GlobalFrameRoutingId render_frame_host_id_;
base::WeakPtrFactory<SerialChooserController> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(SerialChooserController);

View File

@@ -94,6 +94,28 @@ bool WebContentsPermissionHelper::CheckPermission(
details);
}
bool WebContentsPermissionHelper::CheckDevicePermission(
content::PermissionType permission,
const url::Origin& origin,
const base::Value* device,
content::RenderFrameHost* render_frame_host) const {
auto* permission_manager = static_cast<ElectronPermissionManager*>(
web_contents_->GetBrowserContext()->GetPermissionControllerDelegate());
return permission_manager->CheckDevicePermission(permission, origin, device,
render_frame_host);
}
void WebContentsPermissionHelper::GrantDevicePermission(
content::PermissionType permission,
const url::Origin& origin,
const base::Value* device,
content::RenderFrameHost* render_frame_host) const {
auto* permission_manager = static_cast<ElectronPermissionManager*>(
web_contents_->GetBrowserContext()->GetPermissionControllerDelegate());
permission_manager->GrantDevicePermission(permission, origin, device,
render_frame_host);
}
void WebContentsPermissionHelper::RequestFullscreenPermission(
base::OnceCallback<void(bool)> callback) {
RequestPermission(
@@ -168,6 +190,24 @@ bool WebContentsPermissionHelper::CheckSerialAccessPermission(
static_cast<content::PermissionType>(PermissionType::SERIAL), &details);
}
bool WebContentsPermissionHelper::CheckSerialPortPermission(
const url::Origin& origin,
base::Value device,
content::RenderFrameHost* render_frame_host) const {
return CheckDevicePermission(
static_cast<content::PermissionType>(PermissionType::SERIAL), origin,
&device, render_frame_host);
}
void WebContentsPermissionHelper::GrantSerialPortPermission(
const url::Origin& origin,
base::Value device,
content::RenderFrameHost* render_frame_host) const {
return GrantDevicePermission(
static_cast<content::PermissionType>(PermissionType::SERIAL), origin,
&device, render_frame_host);
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(WebContentsPermissionHelper)
} // namespace electron

View File

@@ -40,6 +40,14 @@ class WebContentsPermissionHelper
bool CheckMediaAccessPermission(const GURL& security_origin,
blink::mojom::MediaStreamType type) const;
bool CheckSerialAccessPermission(const url::Origin& embedding_origin) const;
bool CheckSerialPortPermission(
const url::Origin& origin,
base::Value device,
content::RenderFrameHost* render_frame_host) const;
void GrantSerialPortPermission(
const url::Origin& origin,
base::Value device,
content::RenderFrameHost* render_frame_host) const;
private:
explicit WebContentsPermissionHelper(content::WebContents* web_contents);
@@ -53,6 +61,16 @@ class WebContentsPermissionHelper
bool CheckPermission(content::PermissionType permission,
const base::DictionaryValue* details) const;
bool CheckDevicePermission(content::PermissionType permission,
const url::Origin& origin,
const base::Value* device,
content::RenderFrameHost* render_frame_host) const;
void GrantDevicePermission(content::PermissionType permission,
const url::Origin& origin,
const base::Value* device,
content::RenderFrameHost* render_frame_host) const;
content::WebContents* web_contents_;
WEB_CONTENTS_USER_DATA_KEY_DECL();

View File

@@ -12,6 +12,7 @@
#include <string>
#include <vector>
#include "base/win/scoped_com_initializer.h"
#include "shell/common/gin_converters/image_converter.h"
#include "shell/common/gin_helper/promise.h"
#include "shell/common/skia_util.h"
@@ -26,6 +27,8 @@ v8::Local<v8::Promise> NativeImage::CreateThumbnailFromPath(
v8::Isolate* isolate,
const base::FilePath& path,
const gfx::Size& size) {
base::win::ScopedCOMInitializer scoped_com_initializer;
gin_helper::Promise<gfx::Image> promise(isolate);
v8::Local<v8::Promise> handle = promise.GetHandle();
HRESULT hr;

View File

@@ -50,7 +50,9 @@ void ElectronBindings::BindProcess(v8::Isolate* isolate,
process->SetMethod("getCreationTime", &GetCreationTime);
process->SetMethod("getHeapStatistics", &GetHeapStatistics);
process->SetMethod("getBlinkMemoryInfo", &GetBlinkMemoryInfo);
process->SetMethod("getProcessMemoryInfo", &GetProcessMemoryInfo);
if (gin_helper::Locker::IsBrowserProcess()) {
process->SetMethod("getProcessMemoryInfo", &GetProcessMemoryInfo);
}
process->SetMethod("getSystemMemoryInfo", &GetSystemMemoryInfo);
process->SetMethod("getSystemVersion",
&base::SysInfo::OperatingSystemVersion);
@@ -207,10 +209,11 @@ v8::Local<v8::Value> ElectronBindings::GetSystemMemoryInfo(
// static
v8::Local<v8::Promise> ElectronBindings::GetProcessMemoryInfo(
v8::Isolate* isolate) {
CHECK(gin_helper::Locker::IsBrowserProcess());
gin_helper::Promise<gin_helper::Dictionary> promise(isolate);
v8::Local<v8::Promise> handle = promise.GetHandle();
if (gin_helper::Locker::IsBrowserProcess() && !Browser::Get()->is_ready()) {
if (!Browser::Get()->is_ready()) {
promise.RejectWithErrorMessage(
"Memory Info is available only after app ready");
return handle;
@@ -221,7 +224,8 @@ v8::Local<v8::Promise> ElectronBindings::GetProcessMemoryInfo(
->RequestGlobalDumpForPid(
base::GetCurrentProcId(), std::vector<std::string>(),
base::BindOnce(&ElectronBindings::DidReceiveMemoryDump,
std::move(context), std::move(promise)));
std::move(context), std::move(promise),
base::GetCurrentProcId()));
return handle;
}
@@ -242,6 +246,7 @@ v8::Local<v8::Value> ElectronBindings::GetBlinkMemoryInfo(
void ElectronBindings::DidReceiveMemoryDump(
v8::Global<v8::Context> context,
gin_helper::Promise<gin_helper::Dictionary> promise,
base::ProcessId target_pid,
bool success,
std::unique_ptr<memory_instrumentation::GlobalMemoryDump> global_dump) {
v8::Isolate* isolate = promise.isolate();
@@ -259,7 +264,7 @@ void ElectronBindings::DidReceiveMemoryDump(
bool resolved = false;
for (const memory_instrumentation::GlobalMemoryDump::ProcessDump& dump :
global_dump->process_dumps()) {
if (base::GetCurrentProcId() == dump.pid()) {
if (target_pid == dump.pid()) {
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
const auto& osdump = dump.os_dump();
#if defined(OS_LINUX) || defined(OS_WIN)

View File

@@ -49,6 +49,13 @@ class ElectronBindings {
static void Crash();
static void DidReceiveMemoryDump(
v8::Global<v8::Context> context,
gin_helper::Promise<gin_helper::Dictionary> promise,
base::ProcessId target_pid,
bool success,
std::unique_ptr<memory_instrumentation::GlobalMemoryDump> dump);
private:
static void Hang();
static v8::Local<v8::Value> GetHeapStatistics(v8::Isolate* isolate);
@@ -67,12 +74,6 @@ class ElectronBindings {
static void OnCallNextTick(uv_async_t* handle);
static void DidReceiveMemoryDump(
v8::Global<v8::Context> context,
gin_helper::Promise<gin_helper::Dictionary> promise,
bool success,
std::unique_ptr<memory_instrumentation::GlobalMemoryDump> dump);
UvHandle<uv_async_t> call_next_tick_async_;
std::list<node::Environment*> pending_next_ticks_;
std::unique_ptr<base::ProcessMetrics> metrics_;

View File

@@ -4676,4 +4676,32 @@ describe('BrowserWindow module', () => {
});
});
});
describe('"transparent" option', () => {
afterEach(closeAllWindows);
// Only applicable on Windows where transparent windows can't be maximized.
ifit(process.platform === 'win32')('can show maximized frameless window', async () => {
const display = screen.getPrimaryDisplay();
const w = new BrowserWindow({
...display.bounds,
frame: false,
transparent: true,
show: true
});
w.loadURL('about:blank');
await emittedOnce(w, 'ready-to-show');
expect(w.isMaximized()).to.be.true();
// Fails when the transparent HWND is in an invalid maximized state.
expect(w.getBounds()).to.deep.equal(display.workArea);
const newBounds = { width: 256, height: 256, x: 0, y: 0 };
w.setBounds(newBounds);
expect(w.getBounds()).to.deep.equal(newBounds);
});
});
});

View File

@@ -48,6 +48,24 @@ describe('webContents module', () => {
});
});
describe('fromDevToolsTargetId()', () => {
it('returns WebContents for attached DevTools target', async () => {
const w = new BrowserWindow({ show: false });
await w.loadURL('about:blank');
try {
await w.webContents.debugger.attach('1.3');
const { targetInfo } = await w.webContents.debugger.sendCommand('Target.getTargetInfo');
expect(webContents.fromDevToolsTargetId(targetInfo.targetId)).to.equal(w.webContents);
} finally {
await w.webContents.debugger.detach();
}
});
it('returns undefined for an unknown id', () => {
expect(webContents.fromDevToolsTargetId('nope')).to.be.undefined();
});
});
describe('will-prevent-unload event', function () {
afterEach(closeAllWindows);
it('does not emit if beforeunload returns undefined', async () => {

View File

@@ -54,24 +54,26 @@ testStorage(function (
syncForRemove, localForRemove,
syncForClear, localForClear
) {
const message = JSON.stringify({
runtimeId: chrome.runtime.id,
tabId: chrome.devtools.inspectedWindow.tabId,
i18nString: chrome.i18n.getMessage('foo', ['bar', 'baz']),
storageItems: {
local: {
set: localForSet,
remove: localForRemove,
clear: localForClear
},
sync: {
set: syncForSet,
remove: syncForRemove,
clear: syncForClear
setTimeout(() => {
const message = JSON.stringify({
runtimeId: chrome.runtime.id,
tabId: chrome.devtools.inspectedWindow.tabId,
i18nString: chrome.i18n.getMessage('foo', ['bar', 'baz']),
storageItems: {
local: {
set: localForSet,
remove: localForRemove,
clear: localForClear
},
sync: {
set: syncForSet,
remove: syncForRemove,
clear: syncForClear
}
}
}
});
});
const sendMessage = `require('electron').ipcRenderer.send('answer', ${message})`;
window.chrome.devtools.inspectedWindow.eval(sendMessage, function () {});
const sendMessage = `require('electron').ipcRenderer.send('answer', ${message})`;
window.chrome.devtools.inspectedWindow.eval(sendMessage, function () {});
});
});

View File

@@ -458,6 +458,34 @@ describe('<webview> tag', function () {
await delay(0);
expect(w.isFullScreen()).to.be.false();
});
it('pressing ESC should emit the leave-html-full-screen event', async () => {
const w = new BrowserWindow({
show: false,
webPreferences: {
webviewTag: true,
nodeIntegration: true,
contextIsolation: false
}
});
const didAttachWebview = emittedOnce(w.webContents, 'did-attach-webview');
w.loadFile(path.join(fixtures, 'pages', 'webview-did-attach-event.html'));
const [, webContents] = await didAttachWebview;
const enterFSWindow = emittedOnce(w, 'enter-html-full-screen');
const enterFSWebview = emittedOnce(webContents, 'enter-html-full-screen');
await webContents.executeJavaScript('document.getElementById("div").requestFullscreen()', true);
await enterFSWindow;
await enterFSWebview;
const leaveFSWindow = emittedOnce(w, 'leave-html-full-screen');
const leaveFSWebview = emittedOnce(webContents, 'leave-html-full-screen');
webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Escape' });
await leaveFSWindow;
await leaveFSWebview;
});
});
describe('nativeWindowOpen option', () => {

View File

@@ -3,6 +3,7 @@
<link rel="icon" type="image/png" href="http://test.com/favicon.png"/>
<meta http-equiv="content-security-policy" content="script-src 'self' 'unsafe-inline'" />
<body>
<div id="div">Hello World</div>
<script type="text/javascript" charset="utf-8">
console.log('a');
document.title = "test"

View File

@@ -60,6 +60,7 @@ declare namespace Electron {
getOwnerBrowserWindow(): Electron.BrowserWindow;
getWebPreferences(): Electron.WebPreferences;
getLastWebPreferences(): Electron.WebPreferences;
_getProcessMemoryInfo(): Electron.ProcessMemoryInfo;
_getPreloadPaths(): string[];
equal(other: WebContents): boolean;
browserWindowOptions: BrowserWindowConstructorOptions;