mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8492c10291 | ||
|
|
df8611de59 | ||
|
|
2141287cb8 | ||
|
|
bec5e8fc1e | ||
|
|
e83201297a | ||
|
|
a3be71d6e7 | ||
|
|
5aa2271ae7 | ||
|
|
e61cbbd13e | ||
|
|
6cc7de5c13 | ||
|
|
a83d1fe68a | ||
|
|
5759a52589 | ||
|
|
8416737917 | ||
|
|
7313f7ebeb | ||
|
|
4b969e90bf | ||
|
|
9183507c6f | ||
|
|
1f6ecd6424 | ||
|
|
06b5cf9395 | ||
|
|
f3e5920f66 | ||
|
|
e2f4ddbc42 | ||
|
|
f5357caafa | ||
|
|
b846a32bc5 | ||
|
|
09e40aca61 | ||
|
|
f5e1934fb6 | ||
|
|
5c5ccfd178 | ||
|
|
e395cd391a | ||
|
|
9a25e9e010 | ||
|
|
504ecb4931 | ||
|
|
8a9811a29d | ||
|
|
6370ff866a | ||
|
|
22373d0d18 | ||
|
|
43de53d78c | ||
|
|
4b10899dfa | ||
|
|
ea36d3a27f | ||
|
|
d0b8685d92 | ||
|
|
0f47c63860 | ||
|
|
365a10c767 | ||
|
|
2becb29a37 | ||
|
|
b711ec1634 | ||
|
|
2afeea4c43 | ||
|
|
fed1c7993c | ||
|
|
cdb1961ef5 | ||
|
|
f86a8b21f5 | ||
|
|
745a4f9695 | ||
|
|
bf32321f4b | ||
|
|
05c31e9121 | ||
|
|
b4d322a505 | ||
|
|
5ff2f654d1 | ||
|
|
87b55ceacb | ||
|
|
da5a627201 | ||
|
|
83a3a8995f | ||
|
|
ea234f9cb9 | ||
|
|
013825c986 | ||
|
|
c7d61b6ac6 | ||
|
|
cdf0387f6f | ||
|
|
d3e7f2b302 | ||
|
|
21258845f0 | ||
|
|
96bcadd290 | ||
|
|
ee1030e044 | ||
|
|
11d1bfa071 | ||
|
|
131be8cefd |
@@ -1 +1 @@
|
||||
12.0.17
|
||||
12.2.3
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
|
||||
@@ -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',
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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
|
||||
|
||||
90
patches/angle/cherry-pick-1fb846c.patch
Normal file
90
patches/angle/cherry-pick-1fb846c.patch
Normal 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)
|
||||
69
patches/angle/cherry-pick-72473550f6ff.patch
Normal file
69
patches/angle/cherry-pick-72473550f6ff.patch
Normal 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;
|
||||
300
patches/angle/cherry-pick-d8cb996.patch
Normal file
300
patches/angle/cherry-pick-d8cb996.patch
Normal 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)
|
||||
{
|
||||
112
patches/angle/fix_integer_overflow_in_blocklayoutencoder.patch
Normal file
112
patches/angle/fix_integer_overflow_in_blocklayoutencoder.patch
Normal 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.
|
||||
@@ -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;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
174
patches/chromium/check_direction_of_rtcencodedframes.patch
Normal file
174
patches/chromium/check_direction_of_rtcencodedframes.patch
Normal 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 =
|
||||
385
patches/chromium/cherry-pick-0894af410c4e.patch
Normal file
385
patches/chromium/cherry-pick-0894af410c4e.patch
Normal 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());
|
||||
}
|
||||
|
||||
215
patches/chromium/cherry-pick-1227933.patch
Normal file
215
patches/chromium/cherry-pick-1227933.patch
Normal 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>
|
||||
163
patches/chromium/cherry-pick-1231134.patch
Normal file
163
patches/chromium/cherry-pick-1231134.patch
Normal 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();
|
||||
77
patches/chromium/cherry-pick-1233564.patch
Normal file
77
patches/chromium/cherry-pick-1233564.patch
Normal 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_;
|
||||
36
patches/chromium/cherry-pick-3a5bafa35def.patch
Normal file
36
patches/chromium/cherry-pick-3a5bafa35def.patch
Normal 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.
|
||||
135
patches/chromium/cherry-pick-4ce2abc17078.patch
Normal file
135
patches/chromium/cherry-pick-4ce2abc17078.patch
Normal 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)
|
||||
65
patches/chromium/cherry-pick-6048fcd52f42.patch
Normal file
65
patches/chromium/cherry-pick-6048fcd52f42.patch
Normal 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>
|
||||
121
patches/chromium/cherry-pick-6215793f008f.patch
Normal file
121
patches/chromium/cherry-pick-6215793f008f.patch
Normal 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
|
||||
230
patches/chromium/cherry-pick-6a8a2098f9fa.patch
Normal file
230
patches/chromium/cherry-pick-6a8a2098f9fa.patch
Normal 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);
|
||||
};
|
||||
|
||||
274
patches/chromium/cherry-pick-8623d711677d.patch
Normal file
274
patches/chromium/cherry-pick-8623d711677d.patch
Normal 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>
|
||||
48
patches/chromium/cherry-pick-91dd4f79ab5b.patch
Normal file
48
patches/chromium/cherry-pick-91dd4f79ab5b.patch
Normal 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);
|
||||
|
||||
85
patches/chromium/cherry-pick-d727013bb543.patch
Normal file
85
patches/chromium/cherry-pick-d727013bb543.patch
Normal 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;
|
||||
336
patches/chromium/cherry-pick-ddc4cf156505.patch
Normal file
336
patches/chromium/cherry-pick-ddc4cf156505.patch
Normal 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_
|
||||
64
patches/chromium/cherry-pick-e2123a8e0943.patch
Normal file
64
patches/chromium/cherry-pick-e2123a8e0943.patch
Normal 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>(
|
||||
108
patches/chromium/cherry-pick-e8a5cefd1aac.patch
Normal file
108
patches/chromium/cherry-pick-e8a5cefd1aac.patch
Normal 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(
|
||||
+ ®istration_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;
|
||||
|
||||
119
patches/chromium/cherry-pick-efd8e01ac1a6.patch
Normal file
119
patches/chromium/cherry-pick-efd8e01ac1a6.patch
Normal 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);
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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">
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
33
patches/chromium/mas_gate_private_enterprise_APIs
Normal file
33
patches/chromium/mas_gate_private_enterprise_APIs
Normal 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
|
||||
527
patches/chromium/merge_m92_speculative_fix_for_crash_in.patch
Normal file
527
patches/chromium/merge_m92_speculative_fix_for_crash_in.patch
Normal 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(
|
||||
@@ -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 <>
|
||||
@@ -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 ]
|
||||
|
||||
@@ -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;
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
42
patches/node/fix_remove_expired_dst_root_ca_x3.patch
Normal file
42
patches/node/fix_remove_expired_dst_root_ca_x3.patch
Normal 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
1
patches/pdfium/.patches
Normal file
@@ -0,0 +1 @@
|
||||
m94_use_more_safe_arithmetic_in_cfx_dibbase.patch
|
||||
143
patches/pdfium/m94_use_more_safe_arithmetic_in_cfx_dibbase.patch
Normal file
143
patches/pdfium/m94_use_more_safe_arithmetic_in_cfx_dibbase.patch
Normal 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) {
|
||||
@@ -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
|
||||
|
||||
59
patches/v8/cherry-pick-014e1f857c33.patch
Normal file
59
patches/v8/cherry-pick-014e1f857c33.patch
Normal 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();
|
||||
56
patches/v8/cherry-pick-034c2003be31.patch
Normal file
56
patches/v8/cherry-pick-034c2003be31.patch
Normal 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(),
|
||||
43
patches/v8/cherry-pick-1234764.patch
Normal file
43
patches/v8/cherry-pick-1234764.patch
Normal 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) {
|
||||
75
patches/v8/cherry-pick-1234770.patch
Normal file
75
patches/v8/cherry-pick-1234770.patch
Normal 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 {
|
||||
319
patches/v8/cherry-pick-5c4acf2ae64a.patch
Normal file
319
patches/v8/cherry-pick-5c4acf2ae64a.patch
Normal 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.
|
||||
77
patches/v8/cherry-pick-6de4e210688e.patch
Normal file
77
patches/v8/cherry-pick-6de4e210688e.patch
Normal 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();
|
||||
33
patches/v8/cherry-pick-fbfd2557c2ab.patch
Normal file
33
patches/v8/cherry-pick-fbfd2557c2ab.patch
Normal 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(),
|
||||
34
patches/v8/cherry-pick-feef10137b16.patch
Normal file
34
patches/v8/cherry-pick-feef10137b16.patch
Normal 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_;
|
||||
}
|
||||
@@ -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
1
patches/webrtc/.patches
Normal file
@@ -0,0 +1 @@
|
||||
merge_to_94_add_direction_indicator_to_transformableframes.patch
|
||||
@@ -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(
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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 () {});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
1
spec/fixtures/pages/a.html
vendored
1
spec/fixtures/pages/a.html
vendored
@@ -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"
|
||||
|
||||
1
typings/internal-electron.d.ts
vendored
1
typings/internal-electron.d.ts
vendored
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user