mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd4b311d7e | ||
|
|
a22cfb6bef | ||
|
|
bc669916bd | ||
|
|
4067ec6263 | ||
|
|
a6f04822d9 | ||
|
|
9961c7aa77 | ||
|
|
aa9d2dbef7 | ||
|
|
39d55f0b6a | ||
|
|
b07b268fd0 | ||
|
|
daa220f84e | ||
|
|
f22fb9c25d | ||
|
|
c804d638fa | ||
|
|
2ee43f9ece | ||
|
|
33b54d7a8f | ||
|
|
574ee7d219 | ||
|
|
4aa6b8d001 | ||
|
|
2dd1034146 | ||
|
|
14c533c256 | ||
|
|
f8ba210b21 | ||
|
|
2f645042c2 | ||
|
|
be34c32e38 | ||
|
|
a7f4e03e1b | ||
|
|
b09dc5c4a0 | ||
|
|
ac1f5b159f | ||
|
|
9fe4fe6725 | ||
|
|
51e4b47177 | ||
|
|
f2c078ecb6 | ||
|
|
930dde396d | ||
|
|
42aa56a575 | ||
|
|
d91e53e57c | ||
|
|
1f1d139f0e | ||
|
|
18b685e397 | ||
|
|
9d3baaae58 | ||
|
|
23713aa10b | ||
|
|
883f692dad | ||
|
|
cef7a28136 | ||
|
|
d552fa0c07 | ||
|
|
2727847aca | ||
|
|
072158bf8c | ||
|
|
a733074c8c | ||
|
|
bc25056770 | ||
|
|
f0b37841ea | ||
|
|
1caf4e695d | ||
|
|
bba04ea788 | ||
|
|
3b3430fba6 | ||
|
|
c53ffadb8a | ||
|
|
e714d729b1 | ||
|
|
627bf64263 | ||
|
|
a7bbb47ec2 | ||
|
|
cf9ae70dbc | ||
|
|
044c980e96 | ||
|
|
9a71ca545f |
6
BUILD.gn
6
BUILD.gn
@@ -183,6 +183,12 @@ action("electron_js2c") {
|
||||
rebase_path(sources, root_build_dir)
|
||||
}
|
||||
|
||||
action("generate_config_gypi") {
|
||||
outputs = [ "$root_gen_dir/config.gypi" ]
|
||||
script = "script/generate-config-gypi.py"
|
||||
args = rebase_path(outputs) + [ target_cpu ]
|
||||
}
|
||||
|
||||
target_gen_default_app_js = "$target_gen_dir/js/default_app"
|
||||
|
||||
typescript_build("default_app_js") {
|
||||
|
||||
@@ -1 +1 @@
|
||||
13.5.1
|
||||
13.6.5
|
||||
@@ -1687,7 +1687,7 @@ current window into a top-level window.
|
||||
|
||||
#### `win.getParentWindow()`
|
||||
|
||||
Returns `BrowserWindow` - The parent window.
|
||||
Returns `BrowserWindow | null` - The parent window or `null` if there is no parent.
|
||||
|
||||
#### `win.getChildWindows()`
|
||||
|
||||
|
||||
@@ -506,6 +506,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
* `permissionGranted` Boolean - Allow or deny the permission.
|
||||
* `details` Object - Some properties are only available on certain permission types.
|
||||
* `externalURL` String (optional) - The url of the `openExternal` request.
|
||||
* `securityOrigin` String (optional) - The security origin of the `media` request.
|
||||
* `mediaTypes` String[] (optional) - The types of media access being requested, elements can be `video`
|
||||
or `audio`
|
||||
* `requestingUrl` String - The last URL the requesting frame loaded
|
||||
|
||||
@@ -730,6 +730,8 @@ first available device will be selected. `callback` should be called with
|
||||
`deviceId` to be selected, passing empty string to `callback` will
|
||||
cancel the request.
|
||||
|
||||
If no event listener is added for this event, all bluetooth requests will be cancelled.
|
||||
|
||||
```javascript
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
|
||||
@@ -1004,3 +1004,78 @@ Emitted when DevTools is focused / opened.
|
||||
|
||||
[runtime-enabled-features]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70
|
||||
[chrome-webview]: https://developer.chrome.com/docs/extensions/reference/webviewTag/
|
||||
|
||||
### Event: 'context-menu'
|
||||
|
||||
Returns:
|
||||
|
||||
* `params` Object
|
||||
* `x` Integer - x coordinate.
|
||||
* `y` Integer - y coordinate.
|
||||
* `linkURL` String - URL of the link that encloses the node the context menu
|
||||
was invoked on.
|
||||
* `linkText` String - Text associated with the link. May be an empty
|
||||
string if the contents of the link are an image.
|
||||
* `pageURL` String - URL of the top level page that the context menu was
|
||||
invoked on.
|
||||
* `frameURL` String - URL of the subframe that the context menu was invoked
|
||||
on.
|
||||
* `srcURL` String - Source URL for the element that the context menu
|
||||
was invoked on. Elements with source URLs are images, audio and video.
|
||||
* `mediaType` String - Type of the node the context menu was invoked on. Can
|
||||
be `none`, `image`, `audio`, `video`, `canvas`, `file` or `plugin`.
|
||||
* `hasImageContents` Boolean - Whether the context menu was invoked on an image
|
||||
which has non-empty contents.
|
||||
* `isEditable` Boolean - Whether the context is editable.
|
||||
* `selectionText` String - Text of the selection that the context menu was
|
||||
invoked on.
|
||||
* `titleText` String - Title text of the selection that the context menu was
|
||||
invoked on.
|
||||
* `altText` String - Alt text of the selection that the context menu was
|
||||
invoked on.
|
||||
* `suggestedFilename` String - Suggested filename to be used when saving file through 'Save
|
||||
Link As' option of context menu.
|
||||
* `selectionRect` [Rectangle](structures/rectangle.md) - Rect representing the coordinates in the document space of the selection.
|
||||
* `selectionStartOffset` Number - Start position of the selection text.
|
||||
* `referrerPolicy` [Referrer](structures/referrer.md) - The referrer policy of the frame on which the menu is invoked.
|
||||
* `misspelledWord` String - The misspelled word under the cursor, if any.
|
||||
* `dictionarySuggestions` String[] - An array of suggested words to show the
|
||||
user to replace the `misspelledWord`. Only available if there is a misspelled
|
||||
word and spellchecker is enabled.
|
||||
* `frameCharset` String - The character encoding of the frame on which the
|
||||
menu was invoked.
|
||||
* `inputFieldType` String - If the context menu was invoked on an input
|
||||
field, the type of that field. Possible values are `none`, `plainText`,
|
||||
`password`, `other`.
|
||||
* `spellcheckEnabled` Boolean - If the context is editable, whether or not spellchecking is enabled.
|
||||
* `menuSourceType` String - Input source that invoked the context menu.
|
||||
Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.
|
||||
* `mediaFlags` Object - The flags for the media element the context menu was
|
||||
invoked on.
|
||||
* `inError` Boolean - Whether the media element has crashed.
|
||||
* `isPaused` Boolean - Whether the media element is paused.
|
||||
* `isMuted` Boolean - Whether the media element is muted.
|
||||
* `hasAudio` Boolean - Whether the media element has audio.
|
||||
* `isLooping` Boolean - Whether the media element is looping.
|
||||
* `isControlsVisible` Boolean - Whether the media element's controls are
|
||||
visible.
|
||||
* `canToggleControls` Boolean - Whether the media element's controls are
|
||||
toggleable.
|
||||
* `canPrint` Boolean - Whether the media element can be printed.
|
||||
* `canSave` Boolean - Whether or not the media element can be downloaded.
|
||||
* `canShowPictureInPicture` Boolean - Whether the media element can show picture-in-picture.
|
||||
* `isShowingPictureInPicture` Boolean - Whether the media element is currently showing picture-in-picture.
|
||||
* `canRotate` Boolean - Whether the media element can be rotated.
|
||||
* `canLoop` Boolean - Whether the media element can be looped.
|
||||
* `editFlags` Object - These flags indicate whether the renderer believes it
|
||||
is able to perform the corresponding action.
|
||||
* `canUndo` Boolean - Whether the renderer believes it can undo.
|
||||
* `canRedo` Boolean - Whether the renderer believes it can redo.
|
||||
* `canCut` Boolean - Whether the renderer believes it can cut.
|
||||
* `canCopy` Boolean - Whether the renderer believes it can copy.
|
||||
* `canPaste` Boolean - Whether the renderer believes it can paste.
|
||||
* `canDelete` Boolean - Whether the renderer believes it can delete.
|
||||
* `canSelectAll` Boolean - Whether the renderer believes it can select all.
|
||||
* `canEditRichly` Boolean - Whether the renderer believes it can edit text richly.
|
||||
|
||||
Emitted when there is a new context menu that needs to be handled.
|
||||
|
||||
@@ -541,6 +541,9 @@ WebContents.prototype._init = function () {
|
||||
ipcMainInternal.emit(channel, event, ...args);
|
||||
} else {
|
||||
addReplyToEvent(event);
|
||||
if (this.listenerCount('ipc-message-sync') === 0 && ipcMain.listenerCount(channel) === 0) {
|
||||
console.warn(`WebContents #${this.id} called ipcRenderer.sendSync() with '${channel}' channel without listeners.`);
|
||||
}
|
||||
this.emit('ipc-message-sync', event, channel, ...args);
|
||||
ipcMain.emit(channel, event, ...args);
|
||||
}
|
||||
@@ -678,6 +681,14 @@ WebContents.prototype._init = function () {
|
||||
}
|
||||
});
|
||||
|
||||
this.on('select-bluetooth-device', (event, devices, callback) => {
|
||||
if (this.listenerCount('select-bluetooth-device') === 0) {
|
||||
// Cancel it if there are no handlers
|
||||
event.preventDefault();
|
||||
callback('');
|
||||
}
|
||||
});
|
||||
|
||||
const event = process._linkedBinding('electron_browser_event').createEmpty();
|
||||
app.emit('web-contents-created', event, this);
|
||||
|
||||
|
||||
@@ -37,6 +37,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) {
|
||||
|
||||
@@ -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',
|
||||
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -43,7 +44,7 @@ const v8Util = process._linkedBinding('electron_common_v8_util');
|
||||
const contextId = v8Util.getHiddenValue<string>(global, 'contextId');
|
||||
Object.defineProperty(process, 'contextId', { enumerable: true, value: contextId });
|
||||
|
||||
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', {
|
||||
@@ -57,6 +58,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 { preloadScripts, process: processProps } = ipcRendererUtils.invokeSync(IPC_MESSAGES.BROWSER_SANDBOX_LOAD);
|
||||
@@ -80,6 +81,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": "13.5.1",
|
||||
"version": "13.6.5",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -2,3 +2,4 @@ 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
|
||||
|
||||
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 0539923bc75f5b88228dcb387c8aba4c701edc1b..1e6b143a1e1ee9a127b71685febd36416a8840f6 100644
|
||||
--- a/src/compiler/translator/blocklayout.cpp
|
||||
+++ b/src/compiler/translator/blocklayout.cpp
|
||||
@@ -199,6 +199,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;
|
||||
@@ -226,7 +233,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.
|
||||
@@ -289,7 +302,7 @@ void Std140BlockEncoder::getBlockLayoutInfo(GLenum type,
|
||||
baseAlignment = ComponentAlignment(numComponents);
|
||||
}
|
||||
|
||||
- mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
|
||||
+ align(baseAlignment);
|
||||
|
||||
*matrixStrideOut = matrixStride;
|
||||
*arrayStrideOut = arrayStride;
|
||||
@@ -303,16 +316,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 726d76fa178f77a978ff2c82ec20fb8f1ad03f0b..ff90a2487830b365697ce41d660a689857b75319 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.
|
||||
@@ -1,4 +1,3 @@
|
||||
expose_ripemd160.patch
|
||||
expose_aes-cfb.patch
|
||||
expose_des-ede3.patch
|
||||
enable_x509_v_flag_trusted_first_flag.patch
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Juan Cruz Viotti <jv@jviotti.com>
|
||||
Date: Thu, 30 Sep 2021 13:39:23 -0400
|
||||
Subject: Enable X509_V_FLAG_TRUSTED_FIRST flag
|
||||
|
||||
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
|
||||
|
||||
diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c
|
||||
index d8d1efe883321510e4da1aab2cd78378e395c2b2..a371d611dbb2ea7a287a3cb117c3e3d0e1a925b6 100644
|
||||
--- a/crypto/x509/x509_vpm.c
|
||||
+++ b/crypto/x509/x509_vpm.c
|
||||
@@ -548,7 +548,7 @@ static const X509_VERIFY_PARAM default_table[] = {
|
||||
(char *)"default", /* X509 default parameters */
|
||||
0, /* Check time */
|
||||
0, /* internal flags */
|
||||
- 0, /* flags */
|
||||
+ X509_V_FLAG_TRUSTED_FIRST, /* flags */
|
||||
0, /* purpose */
|
||||
0, /* trust */
|
||||
100, /* depth */
|
||||
@@ -149,3 +149,23 @@ linux_sandbox_update_syscall_numbers_for_all_platforms.patch
|
||||
linux_sandbox_return_enosys_for_clone3.patch
|
||||
content-visibility_add_a_clipper_fix_for_content-visibility.patch
|
||||
kill_a_renderer_if_it_provides_an_unexpected_frameownerelementtype.patch
|
||||
m90-lts_backgroundfetch_check_whether_the_sw_id_is_valid_for.patch
|
||||
cherry-pick-096afc1c5428.patch
|
||||
cherry-pick-4e528a5a8d83.patch
|
||||
cherry-pick-3a5bafa35def.patch
|
||||
cherry-pick-b2c4e4dc21e5.patch
|
||||
check_direction_of_rtcencodedframes.patch
|
||||
cherry-pick-6a8a2098f9fa.patch
|
||||
speculative_fix_for_eye_dropper_getcolor_crash.patch
|
||||
mas_gate_private_enterprise_APIs
|
||||
cherry-pick-c69dddfe1cde.patch
|
||||
cherry-pick-8af66de55aad.patch
|
||||
move_networkstateobserver_from_document_to_window.patch
|
||||
cherry-pick-0894af410c4e.patch
|
||||
disable_quictransport_explicitly_in_the_network_service.patch
|
||||
cherry-pick-91dd4f79ab5b.patch
|
||||
introduce_crossthreadcopier_skbitmap.patch
|
||||
allow_null_skbitmap_to_be_transferred_across_threads.patch
|
||||
use_weakptrs_for_the_threadediconloader_s_background_tasks.patch
|
||||
cachestorage_store_partial_opaque_responses.patch
|
||||
cherry-pick-a5f54612590d.patch
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yutaka Hirano <yhirano@chromium.org>
|
||||
Date: Tue, 9 Nov 2021 09:03:17 +0000
|
||||
Subject: Allow null SkBitmap to be transferred across threads
|
||||
|
||||
(cherry picked from commit dad0c0e5162bcc49b8f60354d3bca92224d8381b)
|
||||
|
||||
Bug: 1241091
|
||||
Change-Id: Ie96932c14c8884d6d3eafa76dab5043e7aa31888
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3251815
|
||||
Reviewed-by: Florin Malita <fmalita@chromium.org>
|
||||
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#936861}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3268018
|
||||
Auto-Submit: Yutaka Hirano <yhirano@chromium.org>
|
||||
Reviewed-by: Kentaro Hara <haraken@chromium.org>
|
||||
Commit-Queue: Kentaro Hara <haraken@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4664@{#893}
|
||||
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/graphics/skia/skia_utils.h b/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
|
||||
index 3bd49cac3f5dfcad0fcc1140fcf876fe37558930..c037b85210bf2dedeb8478cf918633ad94885048 100644
|
||||
--- a/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
|
||||
+++ b/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
|
||||
@@ -209,11 +209,13 @@ struct CrossThreadCopier<SkBitmap> {
|
||||
|
||||
using Type = SkBitmap;
|
||||
static SkBitmap Copy(const SkBitmap& bitmap) {
|
||||
- CHECK(bitmap.isImmutable()) << "Only immutable bitmaps can be transferred.";
|
||||
+ CHECK(bitmap.isImmutable() || bitmap.isNull())
|
||||
+ << "Only immutable bitmaps can be transferred.";
|
||||
return bitmap;
|
||||
}
|
||||
static SkBitmap Copy(SkBitmap&& bitmap) {
|
||||
- CHECK(bitmap.isImmutable()) << "Only immutable bitmaps can be transferred.";
|
||||
+ CHECK(bitmap.isImmutable() || bitmap.isNull())
|
||||
+ << "Only immutable bitmaps can be transferred.";
|
||||
return std::move(bitmap);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,94 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Kelly <wanderview@chromium.org>
|
||||
Date: Fri, 5 Nov 2021 19:47:08 +0000
|
||||
Subject: CacheStorage: Store partial opaque responses.
|
||||
|
||||
(cherry picked from commit 802faa035409ac7cbb58ad1a385bb8507fe99077)
|
||||
|
||||
Fixed: 1260649
|
||||
Change-Id: If83156096e6aecec55490330d03c56c0c26120bc
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3251749
|
||||
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Commit-Queue: Ben Kelly <wanderview@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#937400}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3264366
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4664@{#774}
|
||||
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
|
||||
|
||||
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc
|
||||
index 634d72af383e4b9a52ce04202388e13077754783..c5be9cd6e579ad11701c251d48966934e71e8069 100644
|
||||
--- a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc
|
||||
+++ b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc
|
||||
@@ -446,10 +446,10 @@ blink::mojom::FetchAPIResponsePtr CreateResponse(
|
||||
padding = storage::ComputeRandomResponsePadding();
|
||||
}
|
||||
|
||||
- // Note that |has_range_requested| can be safely set to false since it only
|
||||
- // affects HTTP 206 (Partial) responses, which are blocked from cache storage.
|
||||
- // See https://fetch.spec.whatwg.org/#main-fetch for usage of
|
||||
- // |has_range_requested|.
|
||||
+ // While we block most partial responses from being stored, we can have
|
||||
+ // partial responses for bgfetch or opaque responses.
|
||||
+ bool has_range_requested = headers.contains(net::HttpRequestHeaders::kRange);
|
||||
+
|
||||
return blink::mojom::FetchAPIResponse::New(
|
||||
url_list, metadata.response().status_code(),
|
||||
metadata.response().status_text(),
|
||||
@@ -467,7 +467,7 @@ blink::mojom::FetchAPIResponsePtr CreateResponse(
|
||||
static_cast<net::HttpResponseInfo::ConnectionInfo>(
|
||||
metadata.response().connection_info()),
|
||||
alpn_negotiated_protocol, metadata.response().was_fetched_via_spdy(),
|
||||
- /*has_range_requested=*/false, /*auth_challenge_info=*/base::nullopt);
|
||||
+ has_range_requested, /*auth_challenge_info=*/base::nullopt);
|
||||
}
|
||||
|
||||
int64_t CalculateSideDataPadding(
|
||||
@@ -1907,7 +1907,13 @@ void LegacyCacheStorageCache::PutDidCreateEntry(
|
||||
}
|
||||
|
||||
proto::CacheResponse* response_metadata = metadata.mutable_response();
|
||||
- DCHECK_NE(put_context->response->status_code, net::HTTP_PARTIAL_CONTENT);
|
||||
+ if (owner_ != storage::mojom::CacheStorageOwner::kBackgroundFetch &&
|
||||
+ put_context->response->response_type !=
|
||||
+ network::mojom::FetchResponseType::kOpaque &&
|
||||
+ put_context->response->response_type !=
|
||||
+ network::mojom::FetchResponseType::kOpaqueRedirect) {
|
||||
+ DCHECK_NE(put_context->response->status_code, net::HTTP_PARTIAL_CONTENT);
|
||||
+ }
|
||||
response_metadata->set_status_code(put_context->response->status_code);
|
||||
response_metadata->set_status_text(put_context->response->status_text);
|
||||
response_metadata->set_response_type(FetchResponseTypeToProtoResponseType(
|
||||
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.cc b/third_party/blink/renderer/modules/cache_storage/cache.cc
|
||||
index 5482ce90e5a9f591016c784a0378b73b0520be03..0ec3a20cff2fdfc1ebd0f512cfdad4c991341d89 100644
|
||||
--- a/third_party/blink/renderer/modules/cache_storage/cache.cc
|
||||
+++ b/third_party/blink/renderer/modules/cache_storage/cache.cc
|
||||
@@ -101,7 +101,7 @@ void ValidateResponseForPut(const Response* response,
|
||||
exception_state.ThrowTypeError("Vary header contains *");
|
||||
return;
|
||||
}
|
||||
- if (response->GetResponse()->InternalStatus() == 206) {
|
||||
+ if (response->GetResponse()->Status() == 206) {
|
||||
exception_state.ThrowTypeError(
|
||||
"Partial response (status code 206) is unsupported");
|
||||
return;
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/script-tests/cache-put.js b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/script-tests/cache-put.js
|
||||
index b45910a3b8ba089e1724efa8b9e8a8d679c59320..f60c4b905ebcb61854b83177d59861ef92095624 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/script-tests/cache-put.js
|
||||
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/script-tests/cache-put.js
|
||||
@@ -144,7 +144,14 @@ cache_test(function(cache, test) {
|
||||
'Test framework error: The status code should be 0 for an ' +
|
||||
' opaque-filtered response. This is actually HTTP 206.');
|
||||
response = fetch_result.clone();
|
||||
- return promise_rejects_js(test, TypeError, cache.put(request, fetch_result));
|
||||
+ return cache.put(request, fetch_result);
|
||||
+ })
|
||||
+ .then(function() {
|
||||
+ return cache.match(test_url);
|
||||
+ })
|
||||
+ .then(function(result) {
|
||||
+ assert_not_equals(result, undefined,
|
||||
+ 'Cache.put should store an entry for the opaque response');
|
||||
});
|
||||
}, 'Cache.put with opaque-filtered HTTP 206 response');
|
||||
|
||||
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 3f6d24941ad7a9e5c16f11bcdcffa91b2027c0db..9837fb0be84633c88fcf451cec8c276ca6e7c17c 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
|
||||
@@ -75,11 +75,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(
|
||||
@@ -87,15 +91,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(),
|
||||
@@ -176,4 +186,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 e654738739e18adc1937922dbb59f7f9214e651e..58cf45c9023510b4615cbebcaa3b3812481a54c3 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
|
||||
@@ -506,7 +506,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 20c6325e5e7eb4e47a6324033704430ed53ea3c3..44ed2f520c88b5aa694383c749da57d6681cef9a 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
|
||||
@@ -902,7 +902,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 b5e3997002f14208e84c0bab2f3fdee17a4962ef..ef21c3d4fc4c425666af4f6fbb6213fa8f79b002 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 91786d976f7f637d659468d0700a6c858284dd66..2489b47cf864af0ff184f9250208832c31496698 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.
|
||||
@@ -285,11 +291,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>(
|
||||
@@ -344,6 +357,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 4ceea290dcc9b886fb2c65be4ff684854a0f131f..c4653492c8332201f1f6eeb2ce7dbd7fb20c7cc3 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());
|
||||
}
|
||||
|
||||
106
patches/chromium/cherry-pick-096afc1c5428.patch
Normal file
106
patches/chromium/cherry-pick-096afc1c5428.patch
Normal file
@@ -0,0 +1,106 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Rayan Kanso <rayankans@google.com>
|
||||
Date: Tue, 7 Sep 2021 20:14:30 +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/+/3143786
|
||||
Commit-Queue: Richard Knoll <knollr@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4606@{#833}
|
||||
Cr-Branched-From: 35b0d5a9dc8362adfd44e2614f0d5b7402ef63d0-refs/heads/master@{#911515}
|
||||
|
||||
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 ad9a31367250f90e5579525f42b8b1bde2eefbb1..eb0e8fc337061181d7764eb03bc420df12528c1a 100644
|
||||
--- a/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
|
||||
+++ b/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
|
||||
@@ -433,6 +433,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;
|
||||
|
||||
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.
|
||||
62
patches/chromium/cherry-pick-4e528a5a8d83.patch
Normal file
62
patches/chromium/cherry-pick-4e528a5a8d83.patch
Normal file
@@ -0,0 +1,62 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Austin Sullivan <asully@chromium.org>
|
||||
Date: Wed, 15 Sep 2021 23:57:27 +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>
|
||||
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#920376}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3160301
|
||||
Commit-Queue: Austin Sullivan <asully@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4606@{#1077}
|
||||
Cr-Branched-From: 35b0d5a9dc8362adfd44e2614f0d5b7402ef63d0-refs/heads/master@{#911515}
|
||||
|
||||
diff --git a/content/browser/file_system_access/file_system_access_manager_impl.cc b/content/browser/file_system_access/file_system_access_manager_impl.cc
|
||||
index e58be73ae495dbc3c04802caf8fd163bcafaf992..a47eceba374b2c589fe8a0d007e4e1c803baab32 100644
|
||||
--- a/content/browser/file_system_access/file_system_access_manager_impl.cc
|
||||
+++ b/content/browser/file_system_access/file_system_access_manager_impl.cc
|
||||
@@ -448,6 +448,11 @@ void FileSystemAccessManagerImpl::ResolveDefaultDirectory(
|
||||
std::move(callback))));
|
||||
}
|
||||
|
||||
+void FileSystemAccessManagerImpl::Shutdown() {
|
||||
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
+ permission_context_ = nullptr;
|
||||
+}
|
||||
+
|
||||
void FileSystemAccessManagerImpl::SetDefaultPathAndShowPicker(
|
||||
const BindingContext& context,
|
||||
blink::mojom::FilePickerOptionsPtr options,
|
||||
diff --git a/content/browser/file_system_access/file_system_access_manager_impl.h b/content/browser/file_system_access/file_system_access_manager_impl.h
|
||||
index 4c9303aa11349f8de5181ca1dcd92f20f2b74a99..e06a3d347f2af5f62ade1fc70e8ad49ca878628f 100644
|
||||
--- a/content/browser/file_system_access/file_system_access_manager_impl.h
|
||||
+++ b/content/browser/file_system_access/file_system_access_manager_impl.h
|
||||
@@ -257,6 +257,8 @@ class CONTENT_EXPORT FileSystemAccessManagerImpl
|
||||
PathType path_type,
|
||||
const base::FilePath& path);
|
||||
|
||||
+ void Shutdown();
|
||||
+
|
||||
private:
|
||||
friend class FileSystemAccessFileHandleImpl;
|
||||
|
||||
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
|
||||
index 7ffcbd0ac22164d5e268f28e0e434a08e3eb120b..f851627cf33ac4bc2aa56eb3d7b21170eb5c0d16 100644
|
||||
--- a/content/browser/storage_partition_impl.cc
|
||||
+++ b/content/browser/storage_partition_impl.cc
|
||||
@@ -1078,6 +1078,9 @@ StoragePartitionImpl::~StoragePartitionImpl() {
|
||||
GetDatabaseTracker()));
|
||||
}
|
||||
|
||||
+ if (GetFileSystemAccessManager())
|
||||
+ GetFileSystemAccessManager()->Shutdown();
|
||||
+
|
||||
if (GetFileSystemContext())
|
||||
GetFileSystemContext()->Shutdown();
|
||||
|
||||
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 562eb4c2e1341b9aeb77ce3cfaf6740fa4876a61..8d155fa573c5b67f282d43b6fc8bfc0b98cbfeb1 100644
|
||||
--- a/content/browser/browser_child_process_host_impl.cc
|
||||
+++ b/content/browser/browser_child_process_host_impl.cc
|
||||
@@ -704,6 +704,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 c2341d7e2b4149c5a83676b237f4c21ba5e9798a..be4a24917f9c5f8cf6c7c68761b3a9873d9b35aa 100644
|
||||
--- a/content/browser/renderer_host/render_process_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
@@ -2632,6 +2632,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 77cd931b5fe94dc11440c1f67c17d653db11bbb1..c16affe3949505d6144d4c4db6ece453005d6fea 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);
|
||||
};
|
||||
|
||||
126
patches/chromium/cherry-pick-8af66de55aad.patch
Normal file
126
patches/chromium/cherry-pick-8af66de55aad.patch
Normal file
@@ -0,0 +1,126 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Antonio Sartori <antoniosartori@chromium.org>
|
||||
Date: Tue, 24 Aug 2021 15:01:17 +0000
|
||||
Subject: Limit length of 'csp' attribute
|
||||
|
||||
Most servers limit the length of request headers anywhere. 4Kb seems
|
||||
like a reasonable limit, which some popular http servers have by
|
||||
default, and which we already enforce for Referer
|
||||
(https://crrev.com/c/1595872).
|
||||
|
||||
I would have liked the constant 4096 to be shared between //content
|
||||
and blink. This would have required putting it somewhere like in
|
||||
//services/network or in //third_party/blink/common, creating a new
|
||||
file for it. I thought it would be easier to avoid that for this
|
||||
change.
|
||||
|
||||
It would be safer to not load the iframe document, or to impose some
|
||||
very strict CSP like "default-src 'none'", instead than just ignoring
|
||||
the 'csp' attribute if that's too long. However, ignoring is what we
|
||||
already do if the attribute contains illegal characters or does not
|
||||
match the CSP grammary or is not subsumed by the parent iframe's csp
|
||||
attribute. For this change, I believe it's better to stay consistent
|
||||
with that, and later change the CSPEE code to block loading in all
|
||||
those cases.
|
||||
|
||||
Bug: 1233067
|
||||
Change-Id: Ie9cd3db82287a76892cca76a0bf0d4a1613a3055
|
||||
Fixed: 1233067
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3057048
|
||||
Commit-Queue: Antonio Sartori <antoniosartori@chromium.org>
|
||||
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
|
||||
Reviewed-by: Mike West <mkwst@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#914730}
|
||||
|
||||
diff --git a/content/browser/content_security_policy_browsertest.cc b/content/browser/content_security_policy_browsertest.cc
|
||||
index 1d0631955600449d142697ce68c474f1957eae75..f95fe16e3c3f8c8b6c603f7cd19dcdb915deacfa 100644
|
||||
--- a/content/browser/content_security_policy_browsertest.cc
|
||||
+++ b/content/browser/content_security_policy_browsertest.cc
|
||||
@@ -225,4 +225,21 @@ IN_PROC_BROWSER_TEST_F(ContentSecurityPolicyBrowserTest, FileURLs) {
|
||||
}
|
||||
}
|
||||
|
||||
+// Test that a 'csp' attribute longer than 4096 bytes is ignored.
|
||||
+IN_PROC_BROWSER_TEST_F(ContentSecurityPolicyBrowserTest, CSPAttributeTooLong) {
|
||||
+ std::string long_csp_attribute = "script-src 'none' ";
|
||||
+ long_csp_attribute.resize(4097, 'a');
|
||||
+ std::string page = "data:text/html,<body><iframe csp=\"" +
|
||||
+ long_csp_attribute + "\"></iframe></body>";
|
||||
+
|
||||
+ GURL url(page);
|
||||
+ WebContentsConsoleObserver console_observer(web_contents());
|
||||
+ console_observer.SetPattern("'csp' attribute too long*");
|
||||
+ EXPECT_TRUE(NavigateToURL(shell(), url));
|
||||
+ console_observer.Wait();
|
||||
+
|
||||
+ EXPECT_EQ(current_frame_host()->child_count(), 1u);
|
||||
+ EXPECT_FALSE(current_frame_host()->child_at(0)->csp_attribute());
|
||||
+}
|
||||
+
|
||||
} // namespace content
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index 39717e91a88f04d42b489b2217c67f65ee797b4c..db01f3ea0423d780763ba82e50725bb0a12e5018 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -837,9 +837,11 @@ enum class VerifyDidCommitParamsDifference {
|
||||
};
|
||||
|
||||
bool ValidateCSPAttribute(const std::string& value) {
|
||||
+ static const size_t kMaxLengthCSPAttribute = 4096;
|
||||
if (!base::IsStringASCII(value))
|
||||
return false;
|
||||
- if (value.find('\n') != std::string::npos ||
|
||||
+ if (value.length() > kMaxLengthCSPAttribute ||
|
||||
+ value.find('\n') != std::string::npos ||
|
||||
value.find('\r') != std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.cc b/third_party/blink/renderer/core/html/html_iframe_element.cc
|
||||
index 589580b9795f3908c4f5d978bd4366c98e52847a..40b8af83cdb2dc61b78628c223c0d95f7ec43d5b 100644
|
||||
--- a/third_party/blink/renderer/core/html/html_iframe_element.cc
|
||||
+++ b/third_party/blink/renderer/core/html/html_iframe_element.cc
|
||||
@@ -207,16 +207,27 @@ void HTMLIFrameElement::ParseAttribute(
|
||||
UpdateContainerPolicy();
|
||||
}
|
||||
} else if (name == html_names::kCspAttr) {
|
||||
+ static const size_t kMaxLengthCSPAttribute = 4096;
|
||||
if (value && (value.Contains('\n') || value.Contains('\r') ||
|
||||
!MatchesTheSerializedCSPGrammar(value.GetString()))) {
|
||||
+ // TODO(antoniosartori): It would be safer to block loading iframes with
|
||||
+ // invalid 'csp' attribute.
|
||||
required_csp_ = g_null_atom;
|
||||
GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
|
||||
mojom::blink::ConsoleMessageSource::kOther,
|
||||
mojom::blink::ConsoleMessageLevel::kError,
|
||||
"'csp' attribute is invalid: " + value));
|
||||
- return;
|
||||
- }
|
||||
- if (required_csp_ != value) {
|
||||
+ } else if (value && value.length() > kMaxLengthCSPAttribute) {
|
||||
+ // TODO(antoniosartori): It would be safer to block loading iframes with
|
||||
+ // invalid 'csp' attribute.
|
||||
+ required_csp_ = g_null_atom;
|
||||
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
|
||||
+ mojom::blink::ConsoleMessageSource::kOther,
|
||||
+ mojom::blink::ConsoleMessageLevel::kError,
|
||||
+ String::Format("'csp' attribute too long. The max length for the "
|
||||
+ "'csp' attribute is %zu bytes.",
|
||||
+ kMaxLengthCSPAttribute)));
|
||||
+ } else if (required_csp_ != value) {
|
||||
required_csp_ = value;
|
||||
CSPAttributeChanged();
|
||||
UseCounter::Count(GetDocument(), WebFeature::kIFrameCSPAttribute);
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header.html b/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header.html
|
||||
index a9ad787408786e594ccb554d2bd9186a9e8e7c1e..e0a31db8e28fb1a9d2884c7677597072d4badba2 100644
|
||||
--- a/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header.html
|
||||
+++ b/third_party/blink/web_tests/external/wpt/content-security-policy/embedded-enforcement/required_csp-header.html
|
||||
@@ -59,6 +59,9 @@
|
||||
{ "name": "Wrong and dangerous value of `csp` should not trigger sending Sec-Required-CSP Header - report-to present",
|
||||
"csp": "script-src 'unsafe-inline'; report-to resources/dummy-report.php",
|
||||
"expected": null },
|
||||
+ { "name": "Sec-Required-CSP is not sent if `csp` attribute is longer than 4096 bytes",
|
||||
+ "csp": "style-src " + Array.from(Array(2044).keys()).map(i => 'a').join(' '),
|
||||
+ "expected": null },
|
||||
];
|
||||
|
||||
tests.forEach(test => {
|
||||
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 475b5cb2d0a301badcd6fb90b5ad90c47e4b5cc4..b8251bf0780f2d9c0346d480839caeab36082721 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"
|
||||
@@ -1129,6 +1130,12 @@ void NodeController::OnIntroduce(const ports::NodeName& from_node,
|
||||
const uint64_t remote_capabilities) {
|
||||
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);
|
||||
|
||||
649
patches/chromium/cherry-pick-a5f54612590d.patch
Normal file
649
patches/chromium/cherry-pick-a5f54612590d.patch
Normal file
@@ -0,0 +1,649 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Victor Costan <pwnall@chromium.org>
|
||||
Date: Wed, 10 Nov 2021 21:14:03 +0000
|
||||
Subject: M96: Storage Foundation: Avoid cross-thread access of
|
||||
DOMArrayBufferView.
|
||||
|
||||
blink::NativeIOFile::{read, write}() (in the Storage Foundation API
|
||||
implementation) pass DOMArrayBufferView instances to
|
||||
blink::NativeIOFile::Do{Read,Write}() via CrossThreadPersistent.
|
||||
blink::NativeIOFile::Do{Read,Write}() accesses these instances.
|
||||
|
||||
CrossThreadPersistent can be used across threads to keep a garbage
|
||||
collected object alive. However, accessing the object on a different
|
||||
thread is not safe. cppgc::subtle::CrossThreadPersistent
|
||||
(blink::CrossThreadPersistent is an alias to that) has comments
|
||||
explaining that the garbage collected heap can go away while the
|
||||
CrossThreadPersistent instance exists.
|
||||
|
||||
This CL bypasses the problem by having Do{Read,Write}() receive a
|
||||
ArrayBufferContents that has the DOMArrayBufferView's backing buffer.
|
||||
ArrayBufferContents is not garbage-collected, so it can be safely used
|
||||
across threads.
|
||||
|
||||
This CL introduces a NativeIODataBuffer class that contains the logic
|
||||
and state for tearing a DOMArrayBufferView apart into its components
|
||||
(backing buffer, view type, view offset, view length) and putting it
|
||||
back together into a new DOMArrayBufferView, after it doesn't need to be
|
||||
accessed cross-thread anymore.
|
||||
|
||||
(cherry picked from commit 5200793c2aea5979cc79f3350a4e3d6c0795d6f2)
|
||||
|
||||
Bug: 1268274
|
||||
Change-Id: I51588f5bfe963de96ce426e0f480e8c5b4902688
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3269366
|
||||
Commit-Queue: Victor Costan <pwnall@chromium.org>
|
||||
Reviewed-by: enne <enne@chromium.org>
|
||||
Reviewed-by: Joshua Bell <jsbell@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#940070}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3272377
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/4664@{#941}
|
||||
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/native_io/native_io_file.cc b/third_party/blink/renderer/modules/native_io/native_io_file.cc
|
||||
index b25cf909f05be73f690fabee7942ee1fa83c1e04..4d5aa4efa13930aea4886bac0fd8ba892ce8b5a5 100644
|
||||
--- a/third_party/blink/renderer/modules/native_io/native_io_file.cc
|
||||
+++ b/third_party/blink/renderer/modules/native_io/native_io_file.cc
|
||||
@@ -24,7 +24,9 @@
|
||||
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
|
||||
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
|
||||
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
|
||||
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
|
||||
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
|
||||
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
|
||||
#include "third_party/blink/renderer/modules/native_io/native_io_error.h"
|
||||
#include "third_party/blink/renderer/modules/native_io/native_io_file_utils.h"
|
||||
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
|
||||
@@ -256,39 +258,41 @@ ScriptPromise NativeIOFile::read(ScriptState* script_state,
|
||||
"The file was already closed"));
|
||||
return ScriptPromise();
|
||||
}
|
||||
+
|
||||
+ // TODO(pwnall): This assignment should move right before the
|
||||
+ // worker_pool::PostTask() call.
|
||||
+ //
|
||||
+ // `io_pending_` should only be set to true when we know for sure we'll post a
|
||||
+ // task that eventually results in getting `io_pending_` set back to false.
|
||||
+ // Having `io_pending_` set to true in an early return case (rejecting with an
|
||||
+ // exception) leaves the NativeIOFile "stuck" in a state where all future I/O
|
||||
+ // method calls will reject.
|
||||
io_pending_ = true;
|
||||
|
||||
int read_size = NativeIOOperationSize(*buffer);
|
||||
|
||||
- DOMArrayBufferView* result_buffer =
|
||||
- TransferToNewArrayBufferView(script_state->GetIsolate(), buffer);
|
||||
- if (!result_buffer) {
|
||||
+ std::unique_ptr<NativeIODataBuffer> result_buffer_data =
|
||||
+ NativeIODataBuffer::Create(script_state, buffer);
|
||||
+ if (!result_buffer_data) {
|
||||
exception_state.ThrowTypeError("Could not transfer buffer");
|
||||
return ScriptPromise();
|
||||
}
|
||||
+ DCHECK(result_buffer_data->IsValid());
|
||||
DCHECK(buffer->IsDetached());
|
||||
|
||||
- char* result_buffer_data = static_cast<char*>(result_buffer->BaseAddress());
|
||||
-
|
||||
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
|
||||
// The first CrossThreadUnretained() is safe here because the
|
||||
// NativeIOFile::FileState instance is owned by this NativeIOFile, which is
|
||||
// also passed to the task via WrapCrossThreadPersistent. Therefore, the
|
||||
// FileState instance is guaranteed to remain alive during the task's
|
||||
// execution.
|
||||
- //
|
||||
- // The second CrossThreadUnretained() is safe here because result_buffer_data
|
||||
- // is backed by a DOMArrayBufferView that is also passed to the task via
|
||||
- // WrapCrossThreadPersistent. Therefore, the buffer is guaranteed to remain
|
||||
- // alive during the task's execution.
|
||||
worker_pool::PostTask(
|
||||
FROM_HERE, {base::MayBlock()},
|
||||
- CrossThreadBindOnce(
|
||||
- &DoRead, WrapCrossThreadPersistent(this),
|
||||
- WrapCrossThreadPersistent(resolver),
|
||||
- WrapCrossThreadPersistent(result_buffer),
|
||||
- CrossThreadUnretained(file_state_.get()), resolver_task_runner_,
|
||||
- CrossThreadUnretained(result_buffer_data), file_offset, read_size));
|
||||
+ CrossThreadBindOnce(&DoRead, WrapCrossThreadPersistent(this),
|
||||
+ WrapCrossThreadPersistent(resolver),
|
||||
+ CrossThreadUnretained(file_state_.get()),
|
||||
+ resolver_task_runner_, std::move(result_buffer_data),
|
||||
+ file_offset, read_size));
|
||||
return resolver->Promise();
|
||||
}
|
||||
|
||||
@@ -344,35 +348,28 @@ ScriptPromise NativeIOFile::write(ScriptState* script_state,
|
||||
|
||||
io_pending_ = true;
|
||||
|
||||
- DOMArrayBufferView* result_buffer =
|
||||
- TransferToNewArrayBufferView(script_state->GetIsolate(), buffer);
|
||||
- if (!result_buffer) {
|
||||
+ std::unique_ptr<NativeIODataBuffer> result_buffer_data =
|
||||
+ NativeIODataBuffer::Create(script_state, buffer);
|
||||
+ if (!result_buffer_data) {
|
||||
exception_state.ThrowTypeError("Could not transfer buffer");
|
||||
return ScriptPromise();
|
||||
}
|
||||
+ DCHECK(result_buffer_data->IsValid());
|
||||
DCHECK(buffer->IsDetached());
|
||||
|
||||
- char* result_buffer_data = static_cast<char*>(result_buffer->BaseAddress());
|
||||
-
|
||||
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
|
||||
// The first CrossThreadUnretained() is safe here because the
|
||||
// NativeIOFile::FileState instance is owned by this NativeIOFile, which is
|
||||
// also passed to the task via WrapCrossThreadPersistent. Therefore, the
|
||||
// FileState instance is guaranteed to remain alive during the task's
|
||||
// execution.
|
||||
- //
|
||||
- // The second CrossThreadUnretained() is safe here because result_buffer_data
|
||||
- // is backed by a DOMArrayBufferView that is also passed to the task via
|
||||
- // WrapCrossThreadPersistent. Therefore, the data is guaranteed to remain
|
||||
- // alive during the task's execution.
|
||||
worker_pool::PostTask(
|
||||
FROM_HERE, {base::MayBlock()},
|
||||
- CrossThreadBindOnce(
|
||||
- &DoWrite, WrapCrossThreadPersistent(this),
|
||||
- WrapCrossThreadPersistent(resolver),
|
||||
- WrapCrossThreadPersistent(result_buffer),
|
||||
- CrossThreadUnretained(file_state_.get()), resolver_task_runner_,
|
||||
- CrossThreadUnretained(result_buffer_data), file_offset, write_size));
|
||||
+ CrossThreadBindOnce(&DoWrite, WrapCrossThreadPersistent(this),
|
||||
+ WrapCrossThreadPersistent(resolver),
|
||||
+ CrossThreadUnretained(file_state_.get()),
|
||||
+ resolver_task_runner_, std::move(result_buffer_data),
|
||||
+ file_offset, write_size));
|
||||
return resolver->Promise();
|
||||
}
|
||||
|
||||
@@ -676,22 +673,29 @@ void NativeIOFile::DidSetLengthIpc(
|
||||
void NativeIOFile::DoRead(
|
||||
CrossThreadPersistent<NativeIOFile> native_io_file,
|
||||
CrossThreadPersistent<ScriptPromiseResolver> resolver,
|
||||
- CrossThreadPersistent<DOMArrayBufferView> result_buffer,
|
||||
NativeIOFile::FileState* file_state,
|
||||
scoped_refptr<base::SequencedTaskRunner> resolver_task_runner,
|
||||
- char* result_buffer_data,
|
||||
+ std::unique_ptr<NativeIODataBuffer> result_buffer_data,
|
||||
uint64_t file_offset,
|
||||
int read_size) {
|
||||
DCHECK(!IsMainThread()) << "File I/O should not happen on the main thread";
|
||||
|
||||
+ DCHECK(resolver_task_runner);
|
||||
+ DCHECK(result_buffer_data);
|
||||
+ DCHECK(result_buffer_data->IsValid());
|
||||
+ DCHECK_GE(read_size, 0);
|
||||
+#if DCHECK_IS_ON()
|
||||
+ DCHECK_LE(static_cast<size_t>(read_size), result_buffer_data->DataLength());
|
||||
+#endif // DCHECK_IS_ON()
|
||||
+
|
||||
int read_bytes;
|
||||
base::File::Error read_error;
|
||||
{
|
||||
WTF::MutexLocker mutex_locker(file_state->mutex);
|
||||
DCHECK(file_state->file.IsValid())
|
||||
<< "file I/O operation queued after file closed";
|
||||
- read_bytes =
|
||||
- file_state->file.Read(file_offset, result_buffer_data, read_size);
|
||||
+ read_bytes = file_state->file.Read(file_offset, result_buffer_data->Data(),
|
||||
+ read_size);
|
||||
read_error = (read_bytes < 0) ? file_state->file.GetLastFileError()
|
||||
: base::File::FILE_OK;
|
||||
}
|
||||
@@ -699,15 +703,18 @@ void NativeIOFile::DoRead(
|
||||
PostCrossThreadTask(
|
||||
*resolver_task_runner, FROM_HERE,
|
||||
CrossThreadBindOnce(&NativeIOFile::DidRead, std::move(native_io_file),
|
||||
- std::move(resolver), std::move(result_buffer),
|
||||
+ std::move(resolver), std::move(result_buffer_data),
|
||||
read_bytes, read_error));
|
||||
}
|
||||
|
||||
void NativeIOFile::DidRead(
|
||||
CrossThreadPersistent<ScriptPromiseResolver> resolver,
|
||||
- CrossThreadPersistent<DOMArrayBufferView> result_buffer,
|
||||
+ std::unique_ptr<NativeIODataBuffer> result_buffer_data,
|
||||
int read_bytes,
|
||||
base::File::Error read_error) {
|
||||
+ DCHECK(result_buffer_data);
|
||||
+ DCHECK(result_buffer_data->IsValid());
|
||||
+
|
||||
ScriptState* script_state = resolver->GetScriptState();
|
||||
if (!script_state->ContextIsValid())
|
||||
return;
|
||||
@@ -727,7 +734,7 @@ void NativeIOFile::DidRead(
|
||||
DCHECK_EQ(read_error, base::File::FILE_OK)
|
||||
<< "Error set but positive number of bytes read.";
|
||||
NativeIOReadResult* read_result = MakeGarbageCollected<NativeIOReadResult>();
|
||||
- read_result->setBuffer(NotShared<DOMArrayBufferView>(result_buffer));
|
||||
+ read_result->setBuffer(result_buffer_data->Take());
|
||||
read_result->setReadBytes(read_bytes);
|
||||
resolver->Resolve(read_result);
|
||||
}
|
||||
@@ -736,13 +743,19 @@ void NativeIOFile::DidRead(
|
||||
void NativeIOFile::DoWrite(
|
||||
CrossThreadPersistent<NativeIOFile> native_io_file,
|
||||
CrossThreadPersistent<ScriptPromiseResolver> resolver,
|
||||
- CrossThreadPersistent<DOMArrayBufferView> result_buffer,
|
||||
NativeIOFile::FileState* file_state,
|
||||
scoped_refptr<base::SequencedTaskRunner> resolver_task_runner,
|
||||
- const char* result_buffer_data,
|
||||
+ std::unique_ptr<NativeIODataBuffer> result_buffer_data,
|
||||
uint64_t file_offset,
|
||||
int write_size) {
|
||||
DCHECK(!IsMainThread()) << "File I/O should not happen on the main thread";
|
||||
+ DCHECK(resolver_task_runner);
|
||||
+ DCHECK(result_buffer_data);
|
||||
+ DCHECK(result_buffer_data->IsValid());
|
||||
+ DCHECK_GE(write_size, 0);
|
||||
+#if DCHECK_IS_ON()
|
||||
+ DCHECK_LE(static_cast<size_t>(write_size), result_buffer_data->DataLength());
|
||||
+#endif // DCHECK_IS_ON()
|
||||
|
||||
int written_bytes;
|
||||
int64_t actual_file_length_on_failure = 0;
|
||||
@@ -751,8 +764,8 @@ void NativeIOFile::DoWrite(
|
||||
WTF::MutexLocker mutex_locker(file_state->mutex);
|
||||
DCHECK(file_state->file.IsValid())
|
||||
<< "file I/O operation queued after file closed";
|
||||
- written_bytes =
|
||||
- file_state->file.Write(file_offset, result_buffer_data, write_size);
|
||||
+ written_bytes = file_state->file.Write(
|
||||
+ file_offset, result_buffer_data->Data(), write_size);
|
||||
write_error = (written_bytes < 0) ? file_state->file.GetLastFileError()
|
||||
: base::File::FILE_OK;
|
||||
if (written_bytes < write_size || write_error != base::File::FILE_OK) {
|
||||
@@ -767,18 +780,21 @@ void NativeIOFile::DoWrite(
|
||||
PostCrossThreadTask(
|
||||
*resolver_task_runner, FROM_HERE,
|
||||
CrossThreadBindOnce(&NativeIOFile::DidWrite, std::move(native_io_file),
|
||||
- std::move(resolver), std::move(result_buffer),
|
||||
+ std::move(resolver), std::move(result_buffer_data),
|
||||
written_bytes, write_error, write_size,
|
||||
actual_file_length_on_failure));
|
||||
}
|
||||
|
||||
void NativeIOFile::DidWrite(
|
||||
CrossThreadPersistent<ScriptPromiseResolver> resolver,
|
||||
- CrossThreadPersistent<DOMArrayBufferView> result_buffer,
|
||||
+ std::unique_ptr<NativeIODataBuffer> result_buffer_data,
|
||||
int written_bytes,
|
||||
base::File::Error write_error,
|
||||
int write_size,
|
||||
int64_t actual_file_length_on_failure) {
|
||||
+ DCHECK(result_buffer_data);
|
||||
+ DCHECK(result_buffer_data->IsValid());
|
||||
+
|
||||
ScriptState* script_state = resolver->GetScriptState();
|
||||
if (!script_state->ContextIsValid())
|
||||
return;
|
||||
@@ -821,7 +837,7 @@ void NativeIOFile::DidWrite(
|
||||
DCHECK_EQ(write_error, base::File::FILE_OK);
|
||||
NativeIOWriteResult* write_result =
|
||||
MakeGarbageCollected<NativeIOWriteResult>();
|
||||
- write_result->setBuffer(NotShared<DOMArrayBufferView>(result_buffer));
|
||||
+ write_result->setBuffer(result_buffer_data->Take());
|
||||
write_result->setWrittenBytes(written_bytes);
|
||||
resolver->Resolve(write_result);
|
||||
}
|
||||
diff --git a/third_party/blink/renderer/modules/native_io/native_io_file.h b/third_party/blink/renderer/modules/native_io/native_io_file.h
|
||||
index 2e41efeefbcf9805ec2b2ed70d018c717c5c75d1..8ae49ebc2d36d547d152d4e56192e30f8cacd641 100644
|
||||
--- a/third_party/blink/renderer/modules/native_io/native_io_file.h
|
||||
+++ b/third_party/blink/renderer/modules/native_io/native_io_file.h
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
|
||||
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
|
||||
#include "third_party/blink/renderer/modules/native_io/native_io_capacity_tracker.h"
|
||||
+#include "third_party/blink/renderer/modules/native_io/native_io_file_utils.h"
|
||||
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
|
||||
#include "third_party/blink/renderer/platform/heap/handle.h"
|
||||
#include "third_party/blink/renderer/platform/heap/persistent.h"
|
||||
@@ -127,15 +128,14 @@ class NativeIOFile final : public ScriptWrappable {
|
||||
// Performs the file I/O part of read(), off the main thread.
|
||||
static void DoRead(CrossThreadPersistent<NativeIOFile> native_io_file,
|
||||
CrossThreadPersistent<ScriptPromiseResolver> resolver,
|
||||
- CrossThreadPersistent<DOMArrayBufferView> result_buffer,
|
||||
NativeIOFile::FileState* file_state,
|
||||
scoped_refptr<base::SequencedTaskRunner> file_task_runner,
|
||||
- char* result_buffer_data,
|
||||
+ std::unique_ptr<NativeIODataBuffer> result_buffer_data,
|
||||
uint64_t file_offset,
|
||||
int read_size);
|
||||
// Performs the post file I/O part of read(), on the main thread.
|
||||
void DidRead(CrossThreadPersistent<ScriptPromiseResolver> resolver,
|
||||
- CrossThreadPersistent<DOMArrayBufferView> result_buffer,
|
||||
+ std::unique_ptr<NativeIODataBuffer> result_buffer_data,
|
||||
int read_bytes,
|
||||
base::File::Error read_error);
|
||||
|
||||
@@ -143,10 +143,9 @@ class NativeIOFile final : public ScriptWrappable {
|
||||
static void DoWrite(
|
||||
CrossThreadPersistent<NativeIOFile> native_io_file,
|
||||
CrossThreadPersistent<ScriptPromiseResolver> resolver,
|
||||
- CrossThreadPersistent<DOMArrayBufferView> result_buffer,
|
||||
NativeIOFile::FileState* file_state,
|
||||
scoped_refptr<base::SequencedTaskRunner> resolver_task_runner,
|
||||
- const char* result_buffer_data,
|
||||
+ std::unique_ptr<NativeIODataBuffer> result_buffer_data,
|
||||
uint64_t file_offset,
|
||||
int write_size);
|
||||
// Performs the post file I/O part of write(), on the main thread.
|
||||
@@ -154,7 +153,7 @@ class NativeIOFile final : public ScriptWrappable {
|
||||
// `actual_file_length_on_failure` is negative if the I/O operation was
|
||||
// unsuccessful and the correct length of the file could not be determined.
|
||||
void DidWrite(CrossThreadPersistent<ScriptPromiseResolver> resolver,
|
||||
- CrossThreadPersistent<DOMArrayBufferView> result_buffer,
|
||||
+ std::unique_ptr<NativeIODataBuffer> result_buffer_data,
|
||||
int written_bytes,
|
||||
base::File::Error write_error,
|
||||
int write_size,
|
||||
diff --git a/third_party/blink/renderer/modules/native_io/native_io_file_utils.cc b/third_party/blink/renderer/modules/native_io/native_io_file_utils.cc
|
||||
index c50a0a94d111d9ea4eb1eac8a7da920936e0d1a3..3e98a12059374d41b22c8d5c706c31e81581aeae 100644
|
||||
--- a/third_party/blink/renderer/modules/native_io/native_io_file_utils.cc
|
||||
+++ b/third_party/blink/renderer/modules/native_io/native_io_file_utils.cc
|
||||
@@ -3,9 +3,16 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "third_party/blink/renderer/modules/native_io/native_io_file_utils.h"
|
||||
+
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
+#include "base/sequence_checker.h"
|
||||
+#include "base/types/pass_key.h"
|
||||
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
|
||||
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
|
||||
#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h"
|
||||
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
|
||||
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
|
||||
+#include "v8/include/v8.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
@@ -72,4 +79,140 @@ DOMArrayBufferView* TransferToNewArrayBufferView(
|
||||
return target;
|
||||
}
|
||||
|
||||
+// static
|
||||
+std::unique_ptr<NativeIODataBuffer> NativeIODataBuffer::Create(
|
||||
+ ScriptState* script_state,
|
||||
+ NotShared<DOMArrayBufferView> source) {
|
||||
+ DCHECK(script_state);
|
||||
+ DCHECK(source);
|
||||
+
|
||||
+ DOMArrayBufferView::ViewType type = source->GetType();
|
||||
+ size_t offset = source->byteOffset();
|
||||
+ size_t byte_length = source->byteLength();
|
||||
+ size_t length = byte_length / source->TypeSize();
|
||||
+
|
||||
+ // Explicitly fail if the source buffer is not detachable. On its own,
|
||||
+ // Transfer() copies non-detachable input buffers.
|
||||
+ DOMArrayBuffer* buffer = source->buffer();
|
||||
+ v8::Isolate* isolate = script_state->GetIsolate();
|
||||
+ if (!buffer->IsDetachable(isolate))
|
||||
+ return nullptr;
|
||||
+
|
||||
+ ArrayBufferContents contents;
|
||||
+ if (!buffer->Transfer(isolate, contents))
|
||||
+ return nullptr;
|
||||
+ DCHECK(source->IsDetached());
|
||||
+
|
||||
+ return std::make_unique<NativeIODataBuffer>(
|
||||
+ std::move(contents), type, offset,
|
||||
+#if DCHECK_IS_ON()
|
||||
+ byte_length,
|
||||
+#endif // DCHECK_IS_ON()
|
||||
+ length, base::PassKey<NativeIODataBuffer>());
|
||||
+}
|
||||
+
|
||||
+NativeIODataBuffer::NativeIODataBuffer(ArrayBufferContents contents,
|
||||
+ DOMArrayBufferView::ViewType type,
|
||||
+ size_t offset,
|
||||
+#if DCHECK_IS_ON()
|
||||
+ size_t byte_length,
|
||||
+#endif // DCHECK_IS_ON()
|
||||
+ size_t length,
|
||||
+ base::PassKey<NativeIODataBuffer>)
|
||||
+ : contents_(std::move(contents)),
|
||||
+ type_(type),
|
||||
+ offset_(offset),
|
||||
+#if DCHECK_IS_ON()
|
||||
+ byte_length_(byte_length),
|
||||
+#endif // DCHECK_IS_ON()
|
||||
+ length_(length) {
|
||||
+ DCHECK(IsValid());
|
||||
+ DCHECK(!contents_.IsShared());
|
||||
+
|
||||
+ // DataLength() returns 0 when called on an invalid ArrayBufferContents
|
||||
+ // (backing an empty array). This works as expected.
|
||||
+ DCHECK_LE(offset, contents_.DataLength());
|
||||
+#if DCHECK_IS_ON()
|
||||
+ DCHECK_LE(length, byte_length);
|
||||
+ DCHECK_LE(byte_length, contents_.DataLength() - offset);
|
||||
+#endif // DCHECK_IS_ON()
|
||||
+}
|
||||
+
|
||||
+NativeIODataBuffer::~NativeIODataBuffer() {
|
||||
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
+}
|
||||
+
|
||||
+bool NativeIODataBuffer::IsValid() const {
|
||||
+ // The ArrayBufferContents is not shared when this instance is constructed. It
|
||||
+ // should not become shared while the instance is valid, because no other code
|
||||
+ // can gain access and make it shared.
|
||||
+ //
|
||||
+ // ArrayBufferContents::IsShared() returns false for invalid instances, which
|
||||
+ // works out well for this check.
|
||||
+ DCHECK(!contents_.IsShared());
|
||||
+
|
||||
+ // Transferring the data out of an empty ArrayBuffer yields an invalid
|
||||
+ // ArrayBufferContents.
|
||||
+ return length_ == 0 || contents_.IsValid();
|
||||
+}
|
||||
+
|
||||
+NotShared<DOMArrayBufferView> NativeIODataBuffer::Take() {
|
||||
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
+ DCHECK(IsValid());
|
||||
+
|
||||
+ DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(std::move(contents_));
|
||||
+
|
||||
+ DOMArrayBufferView* view = nullptr;
|
||||
+ switch (type_) {
|
||||
+ case DOMArrayBufferView::kTypeInt8:
|
||||
+ view = DOMInt8Array::Create(array_buffer, offset_, length_);
|
||||
+ break;
|
||||
+
|
||||
+ case DOMArrayBufferView::kTypeUint8:
|
||||
+ view = DOMUint8Array::Create(array_buffer, offset_, length_);
|
||||
+ break;
|
||||
+
|
||||
+ case DOMArrayBufferView::kTypeUint8Clamped:
|
||||
+ view = DOMUint8ClampedArray::Create(array_buffer, offset_, length_);
|
||||
+ break;
|
||||
+
|
||||
+ case DOMArrayBufferView::kTypeInt16:
|
||||
+ view = DOMInt16Array::Create(array_buffer, offset_, length_);
|
||||
+ break;
|
||||
+
|
||||
+ case DOMArrayBufferView::kTypeUint16:
|
||||
+ view = DOMUint16Array::Create(array_buffer, offset_, length_);
|
||||
+ break;
|
||||
+
|
||||
+ case DOMArrayBufferView::kTypeInt32:
|
||||
+ view = DOMInt32Array::Create(array_buffer, offset_, length_);
|
||||
+ break;
|
||||
+
|
||||
+ case DOMArrayBufferView::kTypeUint32:
|
||||
+ view = DOMUint32Array::Create(array_buffer, offset_, length_);
|
||||
+ break;
|
||||
+
|
||||
+ case DOMArrayBufferView::kTypeFloat32:
|
||||
+ view = DOMFloat32Array::Create(array_buffer, offset_, length_);
|
||||
+ break;
|
||||
+
|
||||
+ case DOMArrayBufferView::kTypeFloat64:
|
||||
+ view = DOMFloat64Array::Create(array_buffer, offset_, length_);
|
||||
+ break;
|
||||
+
|
||||
+ case DOMArrayBufferView::kTypeBigInt64:
|
||||
+ view = DOMBigInt64Array::Create(array_buffer, offset_, length_);
|
||||
+ break;
|
||||
+
|
||||
+ case DOMArrayBufferView::kTypeBigUint64:
|
||||
+ view = DOMBigUint64Array::Create(array_buffer, offset_, length_);
|
||||
+ break;
|
||||
+
|
||||
+ case DOMArrayBufferView::kTypeDataView:
|
||||
+ view = DOMDataView::Create(array_buffer, offset_, length_);
|
||||
+ break;
|
||||
+ }
|
||||
+ return NotShared<DOMArrayBufferView>(view);
|
||||
+}
|
||||
+
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/modules/native_io/native_io_file_utils.h b/third_party/blink/renderer/modules/native_io/native_io_file_utils.h
|
||||
index 355a67a8125ea11158dfe435a71c1c01b1ece361..a500d38bcdf8340e7c747cbde949db8f980ea272 100644
|
||||
--- a/third_party/blink/renderer/modules/native_io/native_io_file_utils.h
|
||||
+++ b/third_party/blink/renderer/modules/native_io/native_io_file_utils.h
|
||||
@@ -5,11 +5,19 @@
|
||||
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_IO_NATIVE_IO_FILE_UTILS_H_
|
||||
#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_IO_NATIVE_IO_FILE_UTILS_H_
|
||||
|
||||
+#include <cstddef>
|
||||
+#include <memory>
|
||||
+
|
||||
+#include "base/sequence_checker.h"
|
||||
+#include "base/types/pass_key.h"
|
||||
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
|
||||
#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
|
||||
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
+class ScriptState;
|
||||
+
|
||||
// Extracts the read/write operation size from the buffer size.
|
||||
int NativeIOOperationSize(const DOMArrayBufferView& buffer);
|
||||
|
||||
@@ -20,6 +28,121 @@ DOMArrayBufferView* TransferToNewArrayBufferView(
|
||||
v8::Isolate* isolate,
|
||||
NotShared<DOMArrayBufferView> source);
|
||||
|
||||
+// Provides cross-thread access to the buffer backing a DOMArrayBufferView.
|
||||
+//
|
||||
+// This class is necessary because DOMArrayBufferView is garbage-collected,
|
||||
+// which entails that each DOMArrayBufferView instance can only be safely
|
||||
+// accessed on the thread where it was created. Note that CrossThreadPersistent
|
||||
+// can be used to keep a DOMArrayBufferView alive across threads, but the
|
||||
+// instance cannot be safely accessed on a different thread. See the comments on
|
||||
+// cppgc::subtle::CrossThreadPersistent for details.
|
||||
+//
|
||||
+// An instance takes over a DOMArrayBufferView's backing buffer at construction.
|
||||
+// The instance exposes the backing buffer via the Data() and DataLength()
|
||||
+// methods. At some point, the backing buffer is turned back into a
|
||||
+// DOMArrayBufferView via the Take() method. Once Take() is called, the instance
|
||||
+// is invalid, and Data() / DataLength() must not be called anymore.
|
||||
+//
|
||||
+// An instance should be owned by a single sequence at a time. Changing the
|
||||
+// owning sequence should be accomplished by PostTask-ing an owning pointer to
|
||||
+// the instance.
|
||||
+//
|
||||
+// Each instance must be destroyed on the same sequence where it was created.
|
||||
+// Take() must be called on the same sequence where the instance was created.
|
||||
+class NativeIODataBuffer {
|
||||
+ public:
|
||||
+ // Detaches the buffer backing `source`.
|
||||
+ //
|
||||
+ // Returns nullptr if detaching failed.
|
||||
+ static std::unique_ptr<NativeIODataBuffer> Create(
|
||||
+ ScriptState* script_state,
|
||||
+ NotShared<DOMArrayBufferView> source);
|
||||
+
|
||||
+ // Exposed for std::make_unique. Instances should be obtained from Create().
|
||||
+ NativeIODataBuffer(ArrayBufferContents contents,
|
||||
+ DOMArrayBufferView::ViewType type,
|
||||
+ size_t offset,
|
||||
+#if DCHECK_IS_ON()
|
||||
+ size_t byte_length,
|
||||
+#endif // DCHECK_IS_ON()
|
||||
+ size_t length,
|
||||
+ base::PassKey<NativeIODataBuffer>);
|
||||
+
|
||||
+ NativeIODataBuffer(const NativeIODataBuffer&) = delete;
|
||||
+ NativeIODataBuffer& operator=(const NativeIODataBuffer&) = delete;
|
||||
+
|
||||
+ ~NativeIODataBuffer();
|
||||
+
|
||||
+ // Re-creates the DOMArrayBufferView.
|
||||
+ //
|
||||
+ // Must only be called while this instance is onwed by the same sequence where
|
||||
+ // Create() was called. Must only be called if IsValid() is true.
|
||||
+ // After the call, IsValid() will return false.
|
||||
+ NotShared<DOMArrayBufferView> Take();
|
||||
+
|
||||
+ // Exposed for DCHECKs.
|
||||
+ //
|
||||
+ // Can be called while this instance is owned by any sequence.
|
||||
+ bool IsValid() const;
|
||||
+
|
||||
+ // Returns a raw pointer to the DOMArrayBufferView's view.
|
||||
+ //
|
||||
+ // The return type was chosen so that the raw pointer can be conveniently
|
||||
+ // passed to base::File methods.
|
||||
+ //
|
||||
+ // Can be called while this instance is owned by any sequence. Must only be
|
||||
+ // called if IsValid() is true.
|
||||
+ char* Data() {
|
||||
+ DCHECK(IsValid());
|
||||
+
|
||||
+ // An invalid ArrayBufferContents (backing an empty array) returns nullptr
|
||||
+ // when Data() is called. However, in that case, the offset must be zero.
|
||||
+ DCHECK(contents_.Data() || contents_.DataLength() == 0);
|
||||
+ DCHECK(contents_.Data() || offset_ == 0);
|
||||
+
|
||||
+ // According to the DCHECKs above, this branch isn't strictly needed. The
|
||||
+ // return statement below the branch will never do pointer arithmetic on
|
||||
+ // nullptr, because `offset_` is guaranteed to be zero when
|
||||
+ // the ArrayBufferContents is not valid but this instance is.
|
||||
+ char* data = static_cast<char*>(contents_.Data());
|
||||
+ if (!data) {
|
||||
+ DCHECK_EQ(offset_, 0u);
|
||||
+ return data;
|
||||
+ }
|
||||
+
|
||||
+ return data + offset_;
|
||||
+ }
|
||||
+
|
||||
+#if DCHECK_IS_ON()
|
||||
+ // Returns the size of the DOMArrayBufferView's view, in bytes.
|
||||
+ //
|
||||
+ // Exposed for DCHECKs around base::File calls.
|
||||
+ //
|
||||
+ // Can be called while this instance is owned by any sequence. Must only be
|
||||
+ // called if IsValid() is true.
|
||||
+ size_t DataLength() const {
|
||||
+ DCHECK(IsValid());
|
||||
+ return byte_length_;
|
||||
+ }
|
||||
+#endif // DCHECK_IS_ON()
|
||||
+
|
||||
+ private:
|
||||
+ SEQUENCE_CHECKER(sequence_checker_);
|
||||
+
|
||||
+ // May not be valid, as reported by ArrayBufferContents::IsValid().
|
||||
+ //
|
||||
+ // If valid, guaranteed not to be shared, as reported by
|
||||
+ // ArrayBufferContents::IsShared().
|
||||
+ ArrayBufferContents contents_;
|
||||
+
|
||||
+ DOMArrayBufferView::ViewType type_;
|
||||
+ const size_t offset_;
|
||||
+#if DCHECK_IS_ON()
|
||||
+ const size_t byte_length_;
|
||||
+#endif // DCHECK_IS_ON()
|
||||
+ const size_t length_;
|
||||
+};
|
||||
+
|
||||
} // namespace blink
|
||||
|
||||
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_IO_NATIVE_IO_FILE_UTILS_H_
|
||||
36
patches/chromium/cherry-pick-b2c4e4dc21e5.patch
Normal file
36
patches/chromium/cherry-pick-b2c4e4dc21e5.patch
Normal file
@@ -0,0 +1,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Reilly Grant <reillyg@chromium.org>
|
||||
Date: Mon, 4 Oct 2021 23:02:19 +0000
|
||||
Subject: mojo: CHECK when array has too many elements to serialize
|
||||
|
||||
This change turns an early return into a CHECK because the surrounding
|
||||
code expects memory allocation to succeed.
|
||||
|
||||
(cherry picked from commit 588cb74f661269a5b2b69f52619c0f7a09867d6f)
|
||||
|
||||
Bug: 1236318
|
||||
Change-Id: Ib11e0564fb0fa653cb50c82e1973c76ec0c9c725
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3139712
|
||||
Commit-Queue: Reilly Grant <reillyg@chromium.org>
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Auto-Submit: Reilly Grant <reillyg@chromium.org>
|
||||
Reviewed-by: Ken Rockot <rockot@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#917908}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3203131
|
||||
Cr-Commit-Position: refs/branch-heads/4606@{#1301}
|
||||
Cr-Branched-From: 35b0d5a9dc8362adfd44e2614f0d5b7402ef63d0-refs/heads/master@{#911515}
|
||||
|
||||
diff --git a/mojo/public/cpp/bindings/lib/message_fragment.h b/mojo/public/cpp/bindings/lib/message_fragment.h
|
||||
index 226c3644689fd10bfc47b4bd86f4d2cca58adbf1..b380da4131b538e185cc2e326bbe2f38c1810953 100644
|
||||
--- a/mojo/public/cpp/bindings/lib/message_fragment.h
|
||||
+++ b/mojo/public/cpp/bindings/lib/message_fragment.h
|
||||
@@ -149,8 +149,7 @@ class MessageFragment<Array_Data<T>> {
|
||||
static_assert(
|
||||
std::numeric_limits<uint32_t>::max() > Traits::kMaxNumElements,
|
||||
"Max num elements castable to 32bit");
|
||||
- if (num_elements > Traits::kMaxNumElements)
|
||||
- return;
|
||||
+ CHECK_LE(num_elements, Traits::kMaxNumElements);
|
||||
|
||||
const uint32_t num_bytes =
|
||||
Traits::GetStorageSize(static_cast<uint32_t>(num_elements));
|
||||
122
patches/chromium/cherry-pick-c69dddfe1cde.patch
Normal file
122
patches/chromium/cherry-pick-c69dddfe1cde.patch
Normal file
@@ -0,0 +1,122 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hongchan Choi <hongchan@chromium.org>
|
||||
Date: Mon, 11 Oct 2021 23:53:51 +0000
|
||||
Subject: Use zero when the starting value of exponential ramp is zero
|
||||
|
||||
The calculation of an exponential curve is done by the specification:
|
||||
https://webaudio.github.io/web-audio-api/#dom-audioparam-exponentialramptovalueattime
|
||||
|
||||
However, it missed a case where V0 (value1) is zero where it causes
|
||||
a NaN.
|
||||
|
||||
(cherry picked from commit 4e2dcd84dc33f29b032b52e053726ab49e4d0b4d)
|
||||
|
||||
Bug: 1253746,1240610
|
||||
Test: third_party/blink/web_tests/webaudio/AudioParam/exponential-ramp-crash-1253746.html
|
||||
Change-Id: Ib4a95f9298b4300705eda6a2eea64169de7cb002
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3205982
|
||||
Reviewed-by: Ryan Sleevi <rsleevi@chromium.org>
|
||||
Reviewed-by: Chrome Cunningham <chcunningham@chromium.org>
|
||||
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#928673}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3218139
|
||||
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4638@{#766}
|
||||
Cr-Branched-From: 159257cab5585bc8421abf347984bb32fdfe9eb9-refs/heads/main@{#920003}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc b/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc
|
||||
index cf863b343bce3d9c1707be784e01114b594c24f7..f6a0dc5e5cf097f684c0443137b720865601d19c 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"
|
||||
#include "third_party/fdlibm/ieee754.h"
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
@@ -133,7 +134,12 @@ float AudioParamTimeline::ExponentialRampAtTime(double t,
|
||||
double time1,
|
||||
float value2,
|
||||
double time2) {
|
||||
- return value1 * fdlibm::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 * fdlibm::pow(value2 / value1, (t - time1) / (time2 - time1));
|
||||
}
|
||||
|
||||
// Compute the value of a set target event at time t with the given event
|
||||
@@ -998,6 +1004,8 @@ float AudioParamTimeline::ValuesForFrameRangeImpl(
|
||||
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
|
||||
@@ -1057,7 +1065,6 @@ float AudioParamTimeline::ValuesForFrameRangeImpl(
|
||||
value = event->Value();
|
||||
write_index =
|
||||
FillWithDefault(values, value, fill_to_frame, write_index);
|
||||
-
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1400,6 +1407,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>
|
||||
@@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Victor Vasiliev <vasilvv@chromium.org>
|
||||
Date: Tue, 26 Oct 2021 04:50:35 +0000
|
||||
Subject: Disable QuicTransport explicitly in the Network Service
|
||||
|
||||
(cherry picked from commit b1997bdadcda9738a19773f82605f65832acedac)
|
||||
|
||||
Bug: 1260940
|
||||
Change-Id: I6689fbce8115eda19e68414d7c03691704749b17
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3242207
|
||||
Auto-Submit: Victor Vasiliev <vasilvv@chromium.org>
|
||||
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
|
||||
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4606@{#1411}
|
||||
Cr-Branched-From: 35b0d5a9dc8362adfd44e2614f0d5b7402ef63d0-refs/heads/master@{#911515}
|
||||
|
||||
diff --git a/services/network/quic_transport.cc b/services/network/quic_transport.cc
|
||||
index df262796d9021ed478e1154e1f327ac51fe5885e..27fe2b4d2ab9f77b7d68afac57bde6b3b4d7f8e0 100644
|
||||
--- a/services/network/quic_transport.cc
|
||||
+++ b/services/network/quic_transport.cc
|
||||
@@ -27,7 +27,7 @@ net::WebTransportParameters CreateParameters(
|
||||
const std::vector<mojom::QuicTransportCertificateFingerprintPtr>&
|
||||
fingerprints) {
|
||||
net::WebTransportParameters params;
|
||||
- params.enable_quic_transport = true;
|
||||
+ params.enable_quic_transport = false;
|
||||
params.enable_web_transport_http3 = true;
|
||||
|
||||
for (const auto& fingerprint : fingerprints) {
|
||||
diff --git a/services/network/quic_transport_unittest.cc b/services/network/quic_transport_unittest.cc
|
||||
index ecb4f81e4ad947275dcdb1bcdfba1d3295947322..10ff49baaabdc1fce54376fd01ebde8f10c6f9d3 100644
|
||||
--- a/services/network/quic_transport_unittest.cc
|
||||
+++ b/services/network/quic_transport_unittest.cc
|
||||
@@ -359,7 +359,7 @@ struct PrintStringPiece {
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(QuicTransportTests,
|
||||
QuicTransportTest,
|
||||
- testing::Values("quic-transport", "https"),
|
||||
+ testing::Values("https"),
|
||||
PrintStringPiece());
|
||||
|
||||
TEST_P(QuicTransportTest, ConnectSuccessfully) {
|
||||
@@ -671,7 +671,7 @@ class QuicTransportWithCustomCertificateTest : public QuicTransportTest {
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(QuicTransportWithCustomCertificateTests,
|
||||
QuicTransportWithCustomCertificateTest,
|
||||
- testing::Values("quic-transport", "https"),
|
||||
+ testing::Values("https"),
|
||||
PrintStringPiece());
|
||||
|
||||
TEST_P(QuicTransportWithCustomCertificateTest, WithValidFingerprint) {
|
||||
@@ -10,33 +10,94 @@ receive remote control events until it begins playing audio. This runs
|
||||
counter to the design of globalShortcuts, and so we need to instead
|
||||
use `ui::MediaKeysListener`.
|
||||
|
||||
diff --git a/chrome/browser/extensions/global_shortcut_listener.cc b/chrome/browser/extensions/global_shortcut_listener.cc
|
||||
index bc009606d01469125052e68a9cdc82aaa697c764..ff18043cb07d748a49adea9874517fb29e3e7f9f 100644
|
||||
--- a/chrome/browser/extensions/global_shortcut_listener.cc
|
||||
+++ b/chrome/browser/extensions/global_shortcut_listener.cc
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "base/check.h"
|
||||
#include "base/notreached.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
+#include "content/public/browser/media_keys_listener_manager.h"
|
||||
#include "ui/base/accelerators/accelerator.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
@@ -66,6 +67,22 @@ void GlobalShortcutListener::UnregisterAccelerator(
|
||||
StopListening();
|
||||
}
|
||||
|
||||
+// static
|
||||
+void GlobalShortcutListener::SetShouldUseInternalMediaKeyHandling(bool should_use) {
|
||||
+ if (content::MediaKeysListenerManager::
|
||||
+ IsMediaKeysListenerManagerEnabled()) {
|
||||
+ content::MediaKeysListenerManager* media_keys_listener_manager =
|
||||
+ content::MediaKeysListenerManager::GetInstance();
|
||||
+ DCHECK(media_keys_listener_manager);
|
||||
+
|
||||
+ if (should_use) {
|
||||
+ media_keys_listener_manager->EnableInternalMediaKeyHandling();
|
||||
+ } else {
|
||||
+ media_keys_listener_manager->DisableInternalMediaKeyHandling();
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void GlobalShortcutListener::UnregisterAccelerators(Observer* observer) {
|
||||
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
if (IsShortcutHandlingSuspended())
|
||||
diff --git a/chrome/browser/extensions/global_shortcut_listener.h b/chrome/browser/extensions/global_shortcut_listener.h
|
||||
index 9aec54a3263d24491d24013a80b719dfc834ecd4..001a6cb2a5eb701351fa924109b43fab6f30748d 100644
|
||||
--- a/chrome/browser/extensions/global_shortcut_listener.h
|
||||
+++ b/chrome/browser/extensions/global_shortcut_listener.h
|
||||
@@ -31,6 +31,8 @@ class GlobalShortcutListener {
|
||||
|
||||
static GlobalShortcutListener* GetInstance();
|
||||
|
||||
+ static void SetShouldUseInternalMediaKeyHandling(bool should_use);
|
||||
+
|
||||
// Register an observer for when a certain |accelerator| is struck. Returns
|
||||
// true if register successfully, or false if 1) the specificied |accelerator|
|
||||
// has been registered by another caller or other native applications, or
|
||||
diff --git a/content/browser/media/media_keys_listener_manager_impl.cc b/content/browser/media/media_keys_listener_manager_impl.cc
|
||||
index 5938f75742b793868638e693a9a8c8dc686dfc46..bf8782c23095a09dec62c68d7d902df24abcb13e 100644
|
||||
index 5938f75742b793868638e693a9a8c8dc686dfc46..1263d679a5174beb960265989c370dd4a58ae7b4 100644
|
||||
--- a/content/browser/media/media_keys_listener_manager_impl.cc
|
||||
+++ b/content/browser/media/media_keys_listener_manager_impl.cc
|
||||
@@ -231,7 +231,7 @@ void MediaKeysListenerManagerImpl::StartListeningForMediaKeysIfNecessary() {
|
||||
@@ -231,18 +231,24 @@ void MediaKeysListenerManagerImpl::StartListeningForMediaKeysIfNecessary() {
|
||||
media::AudioManager::GetGlobalAppName());
|
||||
#endif
|
||||
|
||||
- if (system_media_controls_) {
|
||||
+ if (/* DISABLES CODE */ (0)) {
|
||||
system_media_controls_->AddObserver(this);
|
||||
system_media_controls_notifier_ =
|
||||
std::make_unique<SystemMediaControlsNotifier>(
|
||||
@@ -239,8 +239,13 @@ void MediaKeysListenerManagerImpl::StartListeningForMediaKeysIfNecessary() {
|
||||
} else {
|
||||
// If we can't access system media controls, then directly listen for media
|
||||
// key keypresses instead.
|
||||
+#if defined(OS_MAC)
|
||||
+ media_keys_listener_ = ui::MediaKeysListener::Create(
|
||||
+ this, ui::MediaKeysListener::Scope::kGlobalRequiresAccessibility);
|
||||
+#else
|
||||
- system_media_controls_->AddObserver(this);
|
||||
- system_media_controls_notifier_ =
|
||||
- std::make_unique<SystemMediaControlsNotifier>(
|
||||
- system_media_controls_.get());
|
||||
- } else {
|
||||
- // If we can't access system media controls, then directly listen for media
|
||||
- // key keypresses instead.
|
||||
+ // This is required for proper functioning of MediaMetadata.
|
||||
+ system_media_controls_->AddObserver(this);
|
||||
+ system_media_controls_notifier_ =
|
||||
+ std::make_unique<SystemMediaControlsNotifier>(
|
||||
+ system_media_controls_.get());
|
||||
+
|
||||
+ // Directly listen for media key keypresses when using GlobalShortcuts.
|
||||
+#if defined(OS_MACOS)
|
||||
+ auto scope = media_key_handling_enabled_ ?
|
||||
+ ui::MediaKeysListener::Scope::kGlobal :
|
||||
+ ui::MediaKeysListener::Scope::kGlobalRequiresAccessibility;
|
||||
media_keys_listener_ = ui::MediaKeysListener::Create(
|
||||
this, ui::MediaKeysListener::Scope::kGlobal);
|
||||
- this, ui::MediaKeysListener::Scope::kGlobal);
|
||||
- DCHECK(media_keys_listener_);
|
||||
- }
|
||||
+ this, scope);
|
||||
+#else
|
||||
+ media_keys_listener_ = ui::MediaKeysListener::Create(
|
||||
+ this, ui::MediaKeysListener::Scope::kGlobal);
|
||||
+#endif
|
||||
DCHECK(media_keys_listener_);
|
||||
}
|
||||
+ DCHECK(media_keys_listener_);
|
||||
|
||||
EnsureAuxiliaryServices();
|
||||
}
|
||||
diff --git a/ui/base/accelerators/media_keys_listener.h b/ui/base/accelerators/media_keys_listener.h
|
||||
index c2b03328c0e508995bdc135031500783f500ceba..1b6b14dc2999c99445cef6ffc04d49a7c1728a54 100644
|
||||
--- a/ui/base/accelerators/media_keys_listener.h
|
||||
|
||||
62
patches/chromium/introduce_crossthreadcopier_skbitmap.patch
Normal file
62
patches/chromium/introduce_crossthreadcopier_skbitmap.patch
Normal file
@@ -0,0 +1,62 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yutaka Hirano <yhirano@chromium.org>
|
||||
Date: Tue, 9 Nov 2021 05:02:50 +0000
|
||||
Subject: Introduce CrossThreadCopier<SkBitmap>
|
||||
|
||||
Allow immutable SkBitmap to be transferred across threads.
|
||||
|
||||
(cherry picked from commit fd794ad56432870e462aab9d62e4f059169c1a5f)
|
||||
|
||||
Bug: 1241091
|
||||
Change-Id: Ia771893245ef2fc1acb05cd4906d64bf2dd406fe
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3244824
|
||||
Reviewed-by: danakj <danakj@chromium.org>
|
||||
Reviewed-by: Florin Malita <fmalita@chromium.org>
|
||||
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#936435}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3267808
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Reviewed-by: Kentaro Hara <haraken@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4664@{#887}
|
||||
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/graphics/skia/skia_utils.h b/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
|
||||
index 997893fef2caee37b65e8ca6dfe9ca7b81302f98..3bd49cac3f5dfcad0fcc1140fcf876fe37558930 100644
|
||||
--- a/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
|
||||
+++ b/third_party/blink/renderer/platform/graphics/skia/skia_utils.h
|
||||
@@ -39,7 +39,9 @@
|
||||
#include "third_party/blink/renderer/platform/graphics/image.h"
|
||||
#include "third_party/blink/renderer/platform/platform_export.h"
|
||||
#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
|
||||
+#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
|
||||
+#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "third_party/skia/include/core/SkCanvas.h"
|
||||
#include "third_party/skia/include/core/SkColor.h"
|
||||
#include "third_party/skia/include/core/SkData.h"
|
||||
@@ -197,4 +199,25 @@ PLATFORM_EXPORT sk_sp<SkData> TryAllocateSkData(size_t size);
|
||||
|
||||
} // namespace blink
|
||||
|
||||
+namespace WTF {
|
||||
+
|
||||
+// We define CrossThreadCopier<SKBitMap> here because we cannot include skia
|
||||
+// headers in platform/wtf.
|
||||
+template <>
|
||||
+struct CrossThreadCopier<SkBitmap> {
|
||||
+ STATIC_ONLY(CrossThreadCopier);
|
||||
+
|
||||
+ using Type = SkBitmap;
|
||||
+ static SkBitmap Copy(const SkBitmap& bitmap) {
|
||||
+ CHECK(bitmap.isImmutable()) << "Only immutable bitmaps can be transferred.";
|
||||
+ return bitmap;
|
||||
+ }
|
||||
+ static SkBitmap Copy(SkBitmap&& bitmap) {
|
||||
+ CHECK(bitmap.isImmutable()) << "Only immutable bitmaps can be transferred.";
|
||||
+ return std::move(bitmap);
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+} // namespace WTF
|
||||
+
|
||||
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_SKIA_SKIA_UTILS_H_
|
||||
@@ -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 6f9c4e466cbec3fa76dc68ac921ec27a9d5ab88b..bbab50e4f4771596cadba107bafe4a5ca0e55c72 100644
|
||||
--- a/content/browser/background_fetch/background_fetch_service_unittest.cc
|
||||
+++ b/content/browser/background_fetch/background_fetch_service_unittest.cc
|
||||
@@ -1088,12 +1088,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
|
||||
@@ -1107,9 +1103,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);
|
||||
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
|
||||
@@ -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 ef5f685998311169352b0bb3065ad6e00f1fe720..e2b94dabe76aa5cd042a9384d5f2a464cf0fa1a4 100644
|
||||
--- a/third_party/blink/renderer/core/dom/document.cc
|
||||
+++ b/third_party/blink/renderer/core/dom/document.cc
|
||||
@@ -324,7 +324,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"
|
||||
@@ -578,43 +577,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);
|
||||
@@ -2948,12 +2910,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() {
|
||||
@@ -8163,7 +8119,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 83fb7a47c2a1abbe69b4f2136f5dbb745e283b08..c4c6ea6ff33516f9690a4d8121ce83797203b399 100644
|
||||
--- a/third_party/blink/renderer/core/dom/document.h
|
||||
+++ b/third_party/blink/renderer/core/dom/document.h
|
||||
@@ -1720,7 +1720,6 @@ class CORE_EXPORT Document : public ContainerNode,
|
||||
BeforeMatchExpandedHiddenMatchableUkm);
|
||||
FRIEND_TEST_ALL_PREFIXES(TextFinderSimTest,
|
||||
BeforeMatchExpandedHiddenMatchableUkmNoHandler);
|
||||
- class NetworkStateObserver;
|
||||
|
||||
friend class AXContext;
|
||||
void AddAXContext(AXContext*);
|
||||
@@ -2113,8 +2112,6 @@ class CORE_EXPORT Document : public ContainerNode,
|
||||
|
||||
TaskHandle sensitive_input_edited_task_;
|
||||
|
||||
- Member<NetworkStateObserver> network_state_observer_;
|
||||
-
|
||||
// |ukm_recorder_| and |source_id_| will allow objects that are part of
|
||||
// the document to record UKM.
|
||||
std::unique_ptr<ukm::UkmRecorder> ukm_recorder_;
|
||||
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 45a5e1ca7d1010da894968c7e786e2ab7072fae2..3b64833fe561f96a76987938c79e2c901ba4b7fc 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_(frame.GetLocalFrameToken()) {}
|
||||
+ token_(frame.GetLocalFrameToken()),
|
||||
+ 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) {
|
||||
@@ -2072,6 +2108,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 e9da1b27a55982266d910e8c90d9f22d975915c9..a0ea2c1f2fc40888336e24f3b6e4b0b83142eaf0 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_dom_window.h
|
||||
+++ b/third_party/blink/renderer/core/frame/local_dom_window.h
|
||||
@@ -437,6 +437,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; }
|
||||
@@ -535,6 +537,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 <>
|
||||
@@ -387,7 +387,7 @@ index 4fde003f2a12794bfcd479ef2797cc6281c5720b..bc3bc4aee26f9373de35366ddb07f7ba
|
||||
// Tells the RenderFrame to switch the CSS to print media type, render every
|
||||
// requested page using the print preview document's frame/node, and then
|
||||
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
|
||||
index b2f6053c94a272f91849b1f351ede6d64af09d4f..d54c332b7ee80106bb54de2a2123f18d3e11f559 100644
|
||||
index b2f6053c94a272f91849b1f351ede6d64af09d4f..b9bfdd3767c9215221cdffd53ef54ff5dc148521 100644
|
||||
--- a/components/printing/renderer/print_render_frame_helper.cc
|
||||
+++ b/components/printing/renderer/print_render_frame_helper.cc
|
||||
@@ -38,6 +38,7 @@
|
||||
@@ -518,18 +518,52 @@ index b2f6053c94a272f91849b1f351ede6d64af09d4f..d54c332b7ee80106bb54de2a2123f18d
|
||||
// Check if |this| is still valid.
|
||||
if (!self)
|
||||
return;
|
||||
@@ -2127,7 +2168,9 @@ void PrintRenderFrameHelper::IPCProcessed() {
|
||||
@@ -2127,36 +2168,51 @@ void PrintRenderFrameHelper::IPCProcessed() {
|
||||
}
|
||||
}
|
||||
|
||||
-bool PrintRenderFrameHelper::InitPrintSettings(bool fit_to_paper_size) {
|
||||
- mojom::PrintPagesParams settings;
|
||||
- settings.params = mojom::PrintParams::New();
|
||||
- GetPrintManagerHost()->GetDefaultPrintSettings(&settings.params);
|
||||
+bool PrintRenderFrameHelper::InitPrintSettings(
|
||||
+ bool fit_to_paper_size,
|
||||
+ const base::DictionaryValue& new_settings) {
|
||||
mojom::PrintPagesParams settings;
|
||||
settings.params = mojom::PrintParams::New();
|
||||
GetPrintManagerHost()->GetDefaultPrintSettings(&settings.params);
|
||||
@@ -2151,12 +2194,14 @@ bool PrintRenderFrameHelper::InitPrintSettings(bool fit_to_paper_size) {
|
||||
+ mojom::PrintPagesParamsPtr settings;
|
||||
+
|
||||
+ if (new_settings.DictEmpty()) {
|
||||
+ settings = mojom::PrintPagesParams::New();
|
||||
+ settings->params = mojom::PrintParams::New();
|
||||
+ GetPrintManagerHost()->GetDefaultPrintSettings(&settings->params);
|
||||
+ } else {
|
||||
+ bool canceled = false;
|
||||
+ int cookie =
|
||||
+ print_pages_params_ ? print_pages_params_->params->document_cookie : 0;
|
||||
+ GetPrintManagerHost()->UpdatePrintSettings(cookie, new_settings.Clone(), &settings, &canceled);
|
||||
+ if (canceled)
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
// Check if the printer returned any settings, if the settings is empty, we
|
||||
// can safely assume there are no printer drivers configured. So we safely
|
||||
// terminate.
|
||||
bool result = true;
|
||||
- if (!PrintMsg_Print_Params_IsValid(*settings.params))
|
||||
+ if (!PrintMsg_Print_Params_IsValid(*settings->params))
|
||||
result = false;
|
||||
|
||||
// Reset to default values.
|
||||
ignore_css_margins_ = false;
|
||||
- settings.pages.clear();
|
||||
+ settings->pages.clear();
|
||||
|
||||
- settings.params->print_scaling_option =
|
||||
+ settings->params->print_scaling_option =
|
||||
fit_to_paper_size ? mojom::PrintScalingOption::kFitToPrintableArea
|
||||
: mojom::PrintScalingOption::kSourceSize;
|
||||
|
||||
- SetPrintPagesParams(settings);
|
||||
+ SetPrintPagesParams(*settings);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -548,7 +582,7 @@ index b2f6053c94a272f91849b1f351ede6d64af09d4f..d54c332b7ee80106bb54de2a2123f18d
|
||||
notify_browser_of_print_failure_ = false;
|
||||
GetPrintManagerHost()->ShowInvalidPrinterSettingsError();
|
||||
return false;
|
||||
@@ -2527,18 +2572,7 @@ void PrintRenderFrameHelper::RequestPrintPreview(PrintPreviewRequestType type) {
|
||||
@@ -2527,18 +2583,7 @@ void PrintRenderFrameHelper::RequestPrintPreview(PrintPreviewRequestType type) {
|
||||
}
|
||||
|
||||
bool PrintRenderFrameHelper::CheckForCancel() {
|
||||
|
||||
@@ -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 7ade75635619fb33151ca2414add02045bccc836..b337d4890f8f1b45ce57bb7ed1607bc9de752b7a 100644
|
||||
--- a/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc
|
||||
+++ b/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc
|
||||
@@ -65,6 +65,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_;
|
||||
@@ -95,6 +96,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),
|
||||
@@ -178,7 +186,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,291 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Rayan Kanso <rayankans@google.com>
|
||||
Date: Tue, 9 Nov 2021 14:10:59 +0000
|
||||
Subject: Use WeakPtrs for the ThreadedIconLoader's background tasks.
|
||||
|
||||
(cherry picked from commit f0375e38d259b3651fd9f305ca2e723ca9c02c64)
|
||||
|
||||
Bug: 1241091
|
||||
Change-Id: I35b9cf705f1c5ffa2a719e47aec7b0f7d98ddc6b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3222803
|
||||
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
|
||||
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
|
||||
Reviewed-by: Kentaro Hara <haraken@chromium.org>
|
||||
Commit-Queue: Kentaro Hara <haraken@chromium.org>
|
||||
Auto-Submit: Rayan Kanso <rayankans@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#937427}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3269570
|
||||
Auto-Submit: Yutaka Hirano <yhirano@chromium.org>
|
||||
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4664@{#897}
|
||||
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/loader/threaded_icon_loader.cc b/third_party/blink/renderer/core/loader/threaded_icon_loader.cc
|
||||
index c995ac86609d44da9fc56e0a44d3bbf7a0161677..37769689879ba3c3d65619850660d4b86b661ffe 100644
|
||||
--- a/third_party/blink/renderer/core/loader/threaded_icon_loader.cc
|
||||
+++ b/third_party/blink/renderer/core/loader/threaded_icon_loader.cc
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "skia/ext/image_operations.h"
|
||||
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
|
||||
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
|
||||
+#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
|
||||
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
|
||||
#include "third_party/blink/renderer/platform/image-decoders/image_frame.h"
|
||||
#include "third_party/blink/renderer/platform/image-decoders/segment_reader.h"
|
||||
@@ -24,6 +25,80 @@
|
||||
|
||||
namespace blink {
|
||||
|
||||
+namespace {
|
||||
+
|
||||
+void DecodeAndResizeImage(
|
||||
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
|
||||
+ scoped_refptr<SegmentReader> data,
|
||||
+ gfx::Size resize_dimensions,
|
||||
+ CrossThreadOnceFunction<void(SkBitmap, double)> done_callback) {
|
||||
+ auto notify_complete = [&](SkBitmap icon, double resize_scale) {
|
||||
+ // This is needed so it can be moved cross-thread.
|
||||
+ icon.setImmutable();
|
||||
+ PostCrossThreadTask(*task_runner, FROM_HERE,
|
||||
+ CrossThreadBindOnce(std::move(done_callback),
|
||||
+ std::move(icon), resize_scale));
|
||||
+ };
|
||||
+
|
||||
+ std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create(
|
||||
+ std::move(data), /* data_complete= */ true,
|
||||
+ ImageDecoder::kAlphaPremultiplied, ImageDecoder::kDefaultBitDepth,
|
||||
+ ColorBehavior::TransformToSRGB());
|
||||
+
|
||||
+ if (!decoder) {
|
||||
+ notify_complete(SkBitmap(), -1.0);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ImageFrame* image_frame = decoder->DecodeFrameBufferAtIndex(0);
|
||||
+
|
||||
+ if (!image_frame) {
|
||||
+ notify_complete(SkBitmap(), -1.0);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ SkBitmap decoded_icon = image_frame->Bitmap();
|
||||
+ if (resize_dimensions.IsEmpty()) {
|
||||
+ notify_complete(std::move(decoded_icon), 1.0);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // If the icon is larger than |resize_dimensions| permits, we need to
|
||||
+ // resize it as well. This can be done synchronously given that we're on a
|
||||
+ // background thread already.
|
||||
+ double scale = std::min(
|
||||
+ static_cast<double>(resize_dimensions.width()) / decoded_icon.width(),
|
||||
+ static_cast<double>(resize_dimensions.height()) / decoded_icon.height());
|
||||
+
|
||||
+ if (scale >= 1.0) {
|
||||
+ notify_complete(std::move(decoded_icon), 1.0);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ int resized_width =
|
||||
+ base::ClampToRange(static_cast<int>(scale * decoded_icon.width()), 1,
|
||||
+ resize_dimensions.width());
|
||||
+ int resized_height =
|
||||
+ base::ClampToRange(static_cast<int>(scale * decoded_icon.height()), 1,
|
||||
+ resize_dimensions.height());
|
||||
+
|
||||
+ // Use the RESIZE_GOOD quality allowing the implementation to pick an
|
||||
+ // appropriate method for the resize. Can be increased to RESIZE_BETTER
|
||||
+ // or RESIZE_BEST if the quality looks poor.
|
||||
+ SkBitmap resized_icon = skia::ImageOperations::Resize(
|
||||
+ decoded_icon, skia::ImageOperations::RESIZE_GOOD, resized_width,
|
||||
+ resized_height);
|
||||
+
|
||||
+ if (resized_icon.isNull()) {
|
||||
+ notify_complete(std::move(decoded_icon), 1.0);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ notify_complete(std::move(resized_icon), scale);
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
void ThreadedIconLoader::Start(
|
||||
ExecutionContext* execution_context,
|
||||
const ResourceRequestHead& resource_request,
|
||||
@@ -83,87 +158,18 @@ void ThreadedIconLoader::DidFinishLoading(uint64_t resource_identifier) {
|
||||
worker_pool::PostTask(
|
||||
FROM_HERE,
|
||||
CrossThreadBindOnce(
|
||||
- &ThreadedIconLoader::DecodeAndResizeImageOnBackgroundThread,
|
||||
- WrapCrossThreadPersistent(this), std::move(task_runner),
|
||||
- SegmentReader::CreateFromSharedBuffer(std::move(data_))));
|
||||
-}
|
||||
-
|
||||
-void ThreadedIconLoader::DecodeAndResizeImageOnBackgroundThread(
|
||||
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
|
||||
- scoped_refptr<SegmentReader> data) {
|
||||
- DCHECK(task_runner);
|
||||
- DCHECK(data);
|
||||
-
|
||||
- auto notify_complete = [&](double refactor_scale) {
|
||||
- PostCrossThreadTask(
|
||||
- *task_runner, FROM_HERE,
|
||||
- CrossThreadBindOnce(&ThreadedIconLoader::OnBackgroundTaskComplete,
|
||||
- WrapCrossThreadPersistent(this), refactor_scale));
|
||||
- };
|
||||
-
|
||||
- std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create(
|
||||
- std::move(data), /* data_complete= */ true,
|
||||
- ImageDecoder::kAlphaPremultiplied, ImageDecoder::kDefaultBitDepth,
|
||||
- ColorBehavior::TransformToSRGB());
|
||||
-
|
||||
- if (!decoder) {
|
||||
- notify_complete(-1.0);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- ImageFrame* image_frame = decoder->DecodeFrameBufferAtIndex(0);
|
||||
-
|
||||
- if (!image_frame) {
|
||||
- notify_complete(-1.0);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- decoded_icon_ = image_frame->Bitmap();
|
||||
- if (!resize_dimensions_) {
|
||||
- notify_complete(1.0);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- // If the icon is larger than |resize_dimensions_| permits, we need to resize
|
||||
- // it as well. This can be done synchronously given that we're on a
|
||||
- // background thread already.
|
||||
- double scale = std::min(
|
||||
- static_cast<double>(resize_dimensions_->width()) / decoded_icon_.width(),
|
||||
- static_cast<double>(resize_dimensions_->height()) /
|
||||
- decoded_icon_.height());
|
||||
-
|
||||
- if (scale >= 1.0) {
|
||||
- notify_complete(1.0);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- int resized_width =
|
||||
- base::ClampToRange(static_cast<int>(scale * decoded_icon_.width()), 1,
|
||||
- resize_dimensions_->width());
|
||||
- int resized_height =
|
||||
- base::ClampToRange(static_cast<int>(scale * decoded_icon_.height()), 1,
|
||||
- resize_dimensions_->height());
|
||||
-
|
||||
- // Use the RESIZE_GOOD quality allowing the implementation to pick an
|
||||
- // appropriate method for the resize. Can be increased to RESIZE_BETTER
|
||||
- // or RESIZE_BEST if the quality looks poor.
|
||||
- SkBitmap resized_icon = skia::ImageOperations::Resize(
|
||||
- decoded_icon_, skia::ImageOperations::RESIZE_GOOD, resized_width,
|
||||
- resized_height);
|
||||
-
|
||||
- if (resized_icon.isNull()) {
|
||||
- notify_complete(1.0);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- decoded_icon_ = std::move(resized_icon);
|
||||
- notify_complete(scale);
|
||||
+ &DecodeAndResizeImage, std::move(task_runner),
|
||||
+ SegmentReader::CreateFromSharedBuffer(std::move(data_)),
|
||||
+ resize_dimensions_ ? *resize_dimensions_ : gfx::Size(),
|
||||
+ CrossThreadBindOnce(&ThreadedIconLoader::OnBackgroundTaskComplete,
|
||||
+ WrapCrossThreadWeakPersistent(this))));
|
||||
}
|
||||
|
||||
-void ThreadedIconLoader::OnBackgroundTaskComplete(double resize_scale) {
|
||||
+void ThreadedIconLoader::OnBackgroundTaskComplete(SkBitmap icon,
|
||||
+ double resize_scale) {
|
||||
if (stopped_)
|
||||
return;
|
||||
- std::move(icon_callback_).Run(std::move(decoded_icon_), resize_scale);
|
||||
+ std::move(icon_callback_).Run(std::move(icon), resize_scale);
|
||||
}
|
||||
|
||||
void ThreadedIconLoader::DidFail(const ResourceError& error) {
|
||||
diff --git a/third_party/blink/renderer/core/loader/threaded_icon_loader.h b/third_party/blink/renderer/core/loader/threaded_icon_loader.h
|
||||
index 4497f329a0339d4aee4e4eb7f9d5a03e5add55d6..41fba43ad7567e36c4b342e9fd51f01c3ef329d8 100644
|
||||
--- a/third_party/blink/renderer/core/loader/threaded_icon_loader.h
|
||||
+++ b/third_party/blink/renderer/core/loader/threaded_icon_loader.h
|
||||
@@ -18,7 +18,6 @@
|
||||
namespace blink {
|
||||
|
||||
class ResourceRequestHead;
|
||||
-class SegmentReader;
|
||||
|
||||
// Utility class for loading, decoding, and potentially rescaling an icon on a
|
||||
// background thread. Note that icons are only downscaled and never upscaled.
|
||||
@@ -52,11 +51,7 @@ class CORE_EXPORT ThreadedIconLoader final
|
||||
void Trace(Visitor* visitor) const override;
|
||||
|
||||
private:
|
||||
- void DecodeAndResizeImageOnBackgroundThread(
|
||||
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
|
||||
- scoped_refptr<SegmentReader> data);
|
||||
-
|
||||
- void OnBackgroundTaskComplete(double resize_scale);
|
||||
+ void OnBackgroundTaskComplete(SkBitmap icon, double resize_scale);
|
||||
|
||||
Member<ThreadableLoader> threadable_loader_;
|
||||
|
||||
@@ -64,9 +59,7 @@ class CORE_EXPORT ThreadedIconLoader final
|
||||
// of the image data starts.
|
||||
scoped_refptr<SharedBuffer> data_;
|
||||
|
||||
- // Accessed from main thread and background thread.
|
||||
base::Optional<gfx::Size> resize_dimensions_;
|
||||
- SkBitmap decoded_icon_;
|
||||
|
||||
IconCallback icon_callback_;
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc b/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc
|
||||
index 79f4224fd96c46d7a6e1caabb44a509443b4bbff..3b5f52a9beb9c86d712332a4605f1b46c40f7682 100644
|
||||
--- a/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc
|
||||
+++ b/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc
|
||||
@@ -26,6 +26,7 @@ constexpr base::TimeDelta kIconFetchTimeout = base::TimeDelta::FromSeconds(30);
|
||||
void FetchIcon(ExecutionContext* execution_context,
|
||||
const KURL& icon_url,
|
||||
const gfx::Size& icon_size,
|
||||
+ ThreadedIconLoader* threaded_icon_loader,
|
||||
ThreadedIconLoader::IconCallback callback) {
|
||||
ResourceRequest resource_request(icon_url);
|
||||
resource_request.SetRequestContext(mojom::blink::RequestContextType::IMAGE);
|
||||
@@ -34,7 +35,6 @@ void FetchIcon(ExecutionContext* execution_context,
|
||||
resource_request.SetPriority(ResourceLoadPriority::kMedium);
|
||||
resource_request.SetTimeoutInterval(kIconFetchTimeout);
|
||||
|
||||
- auto* threaded_icon_loader = MakeGarbageCollected<ThreadedIconLoader>();
|
||||
threaded_icon_loader->Start(execution_context, resource_request, icon_size,
|
||||
std::move(callback));
|
||||
}
|
||||
@@ -100,16 +100,21 @@ void ContentIndexIconLoader::Start(
|
||||
if (icon_url.IsEmpty())
|
||||
icon_url = KURL(image_resources[0].src);
|
||||
|
||||
+ auto* threaded_icon_loader = MakeGarbageCollected<ThreadedIconLoader>();
|
||||
// |icons_ptr| is safe to use since it is owned by |barrier_closure|.
|
||||
FetchIcon(
|
||||
- execution_context, icon_url, icon_size,
|
||||
+ execution_context, icon_url, icon_size, threaded_icon_loader,
|
||||
WTF::Bind(
|
||||
[](base::OnceClosure done_closure, Vector<SkBitmap>* icons_ptr,
|
||||
- SkBitmap icon, double resize_scale) {
|
||||
+ ThreadedIconLoader* icon_loader, SkBitmap icon,
|
||||
+ double resize_scale) {
|
||||
icons_ptr->push_back(std::move(icon));
|
||||
std::move(done_closure).Run();
|
||||
},
|
||||
- barrier_closure, WTF::Unretained(icons_ptr)));
|
||||
+ barrier_closure, WTF::Unretained(icons_ptr),
|
||||
+ // Pass |threaded_icon_loader| to the callback to make sure it
|
||||
+ // doesn't get destroyed.
|
||||
+ WrapPersistent(threaded_icon_loader)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,5 +19,9 @@
|
||||
|
||||
"src/electron/patches/angle": "src/third_party/angle",
|
||||
|
||||
"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"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ feat_initialize_asar_support.patch
|
||||
expose_get_builtin_module_function.patch
|
||||
build_add_gn_build_files.patch
|
||||
fix_add_default_values_for_enable_lto_and_build_v8_with_gn_in.patch
|
||||
feat_add_new_built_with_electron_variable_to_config_gypi.patch
|
||||
feat_add_flags_for_low-level_hooks_and_exceptions.patch
|
||||
fix_expose_tracing_agent_and_use_tracing_tracingcontroller_instead.patch
|
||||
pass_all_globals_through_require.patch
|
||||
@@ -36,3 +35,4 @@ fix_handle_new_tostring_behavior_in_v8_serdes_test.patch
|
||||
fix_the_--harmony-weak-refs_has_been_removed_remove_from_specs.patch
|
||||
node-api_faster_threadsafe_function.patch
|
||||
src_add_missing_context_scopes.patch
|
||||
fix_remove_expired_dst_root_ca_x3.patch
|
||||
|
||||
@@ -7,10 +7,10 @@ This adds GN build files for Node, so we don't have to build with GYP.
|
||||
|
||||
diff --git a/BUILD.gn b/BUILD.gn
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..446119163d1f7bad577cb0b7b217ecf24b994526
|
||||
index 0000000000000000000000000000000000000000..f267a14ffd12828417e441c09ca3a673236dfd34
|
||||
--- /dev/null
|
||||
+++ b/BUILD.gn
|
||||
@@ -0,0 +1,360 @@
|
||||
@@ -0,0 +1,352 @@
|
||||
+import("//electron/build/asar.gni")
|
||||
+import("//v8/gni/v8.gni")
|
||||
+
|
||||
@@ -75,20 +75,12 @@ index 0000000000000000000000000000000000000000..446119163d1f7bad577cb0b7b217ecf2
|
||||
+ ]
|
||||
+}
|
||||
+
|
||||
+action("generate_config_gypi") {
|
||||
+ outputs = [
|
||||
+ "$target_gen_dir/config.gypi",
|
||||
+ ]
|
||||
+ script = "tools/generate_config_gypi.py"
|
||||
+ args = rebase_path(outputs, root_build_dir)
|
||||
+}
|
||||
+
|
||||
+chdir_action("node_js2c") {
|
||||
+ deps = [
|
||||
+ ":generate_config_gypi",
|
||||
+ "//electron:generate_config_gypi",
|
||||
+ ":node_js2c_inputs",
|
||||
+ ]
|
||||
+ config_gypi = [ "$target_gen_dir/config.gypi" ]
|
||||
+ config_gypi = [ "$root_gen_dir/config.gypi" ]
|
||||
+ inputs = library_files + config_gypi
|
||||
+ outputs = [
|
||||
+ "$target_gen_dir/node_javascript.cc",
|
||||
@@ -319,10 +311,10 @@ index 0000000000000000000000000000000000000000..446119163d1f7bad577cb0b7b217ecf2
|
||||
+
|
||||
+copy("node_gypi_headers") {
|
||||
+ deps = [
|
||||
+ ":generate_config_gypi",
|
||||
+ "//electron:generate_config_gypi",
|
||||
+ ]
|
||||
+ sources = [
|
||||
+ "$target_gen_dir/config.gypi",
|
||||
+ "$root_gen_dir/config.gypi",
|
||||
+ "common.gypi",
|
||||
+ ]
|
||||
+ outputs = [
|
||||
@@ -1647,23 +1639,6 @@ index 0f72abc0bf0302e1f535f71803f5aa063424f8b9..c6a76e408312d8fcfc48490827273319
|
||||
|
||||
// The NAPI_VERSION provided by this version of the runtime. This is the version
|
||||
// which the Node binary being built supports.
|
||||
diff --git a/tools/generate_config_gypi.py b/tools/generate_config_gypi.py
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..01f62d4ae6e3b9d539444e3dff069f0011353caa
|
||||
--- /dev/null
|
||||
+++ b/tools/generate_config_gypi.py
|
||||
@@ -0,0 +1,11 @@
|
||||
+# TODO: assess which if any of the config variables are important to include in
|
||||
+# the js2c'd config.gypi.
|
||||
+import sys
|
||||
+
|
||||
+def main(args):
|
||||
+ out = args[0]
|
||||
+ with open(out, 'w') as f:
|
||||
+ f.write("{'variables':{}}\n")
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ main(sys.argv[1:])
|
||||
diff --git a/tools/generate_gn_filenames_json.py b/tools/generate_gn_filenames_json.py
|
||||
new file mode 100755
|
||||
index 0000000000000000000000000000000000000000..e5fd79da5323e7039730fd8cca66caae8c84e903
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Tue, 2 Oct 2018 11:39:58 -0700
|
||||
Subject: feat: add new built_with_electron variable to config.gypi
|
||||
|
||||
This allows 3rd-party native modules to know whether they're being built
|
||||
against Electron.
|
||||
|
||||
diff --git a/tools/generate_config_gypi.py b/tools/generate_config_gypi.py
|
||||
index 01f62d4ae6e3b9d539444e3dff069f0011353caa..d8b279f590c115108d5dca879747de7b0c9f1934 100644
|
||||
--- a/tools/generate_config_gypi.py
|
||||
+++ b/tools/generate_config_gypi.py
|
||||
@@ -5,7 +5,7 @@ import sys
|
||||
def main(args):
|
||||
out = args[0]
|
||||
with open(out, 'w') as f:
|
||||
- f.write("{'variables':{}}\n")
|
||||
+ f.write("{'variables':{'built_with_electron': 1}}\n")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1:])
|
||||
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 137556e4fd3de77521ae50c3f2f00d6e43651149..e0186e5c58aa09f24b263783a700cf627bd727ec 100644
|
||||
--- a/core/fxge/dib/cfx_dibbase.cpp
|
||||
+++ b/core/fxge/dib/cfx_dibbase.cpp
|
||||
@@ -628,15 +628,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 5012d4400be224189fa175fc4a6603ff88069835..ad23d4bb6bb82767bf2e27f3f4538e3f2f29c481 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) {
|
||||
@@ -16,3 +16,9 @@ cherry-pick-034c2003be31.patch
|
||||
regexp_add_a_currently_failing_cctest_for_irregexp_reentrancy.patch
|
||||
regexp_allow_reentrant_irregexp_execution.patch
|
||||
regexp_remove_the_stack_parameter_from_regexp_matchers.patch
|
||||
cherry-pick-5c4acf2ae64a.patch
|
||||
cherry-pick-6de4e210688e.patch
|
||||
merged_cppgc_fix_marking_of_ephemerons_with_keys_in_construction.patch
|
||||
cherry-pick-feef10137b16.patch
|
||||
cherry-pick-014e1f857c33.patch
|
||||
cherry-pick-5d2b5e7c006c.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 35d1da5cd92900114a609f4553a738018269ee1e..e489d5a304385e4bafaa2ca4619edadc6108b0be 100644
|
||||
--- a/src/ic/accessor-assembler.cc
|
||||
+++ b/src/ic/accessor-assembler.cc
|
||||
@@ -655,8 +655,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 81e31d1c2d83d6a807745234ffdae513e0904cbe..94829bd199a0baa5730889746e3b65797bdae08a 100644
|
||||
--- a/src/ic/ic.cc
|
||||
+++ b/src/ic/ic.cc
|
||||
@@ -860,7 +860,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();
|
||||
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 eb1511f71d9491f05636d422c3ba9d3ecf401efa..085af904369da631d2dc9aa3db05ab5e1b3812fe 100644
|
||||
--- a/src/heap/concurrent-marking.cc
|
||||
+++ b/src/heap/concurrent-marking.cc
|
||||
@@ -433,7 +433,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);
|
||||
@@ -443,7 +443,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -484,6 +484,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);
|
||||
@@ -499,7 +500,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -519,8 +520,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 a0938359817fa88008a3280efa478de45417b6a8..efedcdb32b6c71f3030618b47dcb21797495af89 100644
|
||||
--- a/src/heap/incremental-marking.cc
|
||||
+++ b/src/heap/incremental-marking.cc
|
||||
@@ -921,7 +921,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 951b49507cab7116a61895deebe5368d5518b9e2..7ab09caf7b509734e1bf52c2e7310c503499fc65 100644
|
||||
--- a/src/heap/mark-compact.cc
|
||||
+++ b/src/heap/mark-compact.cc
|
||||
@@ -1602,24 +1602,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(),
|
||||
@@ -1630,47 +1630,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1678,7 +1685,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() {
|
||||
@@ -1764,6 +1771,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() {
|
||||
@@ -1785,9 +1798,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) ||
|
||||
@@ -1827,18 +1842,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);
|
||||
|
||||
@@ -1863,7 +1879,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 733588ae80ae3530fd53988c706de7c58084d2cf..0674ce674fc37c993294536afd324909f4dea05e 100644
|
||||
--- a/src/heap/mark-compact.h
|
||||
+++ b/src/heap/mark-compact.h
|
||||
@@ -588,7 +588,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,
|
||||
@@ -634,8 +634,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.
|
||||
39
patches/v8/cherry-pick-5d2b5e7c006c.patch
Normal file
39
patches/v8/cherry-pick-5d2b5e7c006c.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nico Hartmann <nicohartmann@chromium.org>
|
||||
Date: Mon, 25 Oct 2021 10:58:59 +0200
|
||||
Subject: Merged: [TurboFan] Do not use NumberConstant as immediate in x86
|
||||
|
||||
Bug: chromium:1254189
|
||||
(cherry picked from commit bdf31d5883607db4377b519d7308fb1e639a0448)
|
||||
|
||||
Change-Id: I1d4426fee8392c7a680ad67af4bf2745d04b2e52
|
||||
No-Try: true
|
||||
No-Presubmit: true
|
||||
No-Tree-Checks: true
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3268905
|
||||
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
|
||||
Reviewed-by: Maya Lekova <mslekova@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/9.6@{#22}
|
||||
Cr-Branched-From: 0b7bda016178bf438f09b3c93da572ae3663a1f7-refs/heads/9.6.180@{#1}
|
||||
Cr-Branched-From: 41a5a247d9430b953e38631e88d17790306f7a4c-refs/heads/main@{#77244}
|
||||
|
||||
diff --git a/src/compiler/backend/ia32/instruction-selector-ia32.cc b/src/compiler/backend/ia32/instruction-selector-ia32.cc
|
||||
index 033a566e1138fd366a33d76b30a4b12cbcde78f2..573e720a982bdfd5767f1f5c3776db178e13e633 100644
|
||||
--- a/src/compiler/backend/ia32/instruction-selector-ia32.cc
|
||||
+++ b/src/compiler/backend/ia32/instruction-selector-ia32.cc
|
||||
@@ -98,11 +98,14 @@ class IA32OperandGenerator final : public OperandGenerator {
|
||||
bool CanBeImmediate(Node* node) {
|
||||
switch (node->opcode()) {
|
||||
case IrOpcode::kInt32Constant:
|
||||
- case IrOpcode::kNumberConstant:
|
||||
case IrOpcode::kExternalConstant:
|
||||
case IrOpcode::kRelocatableInt32Constant:
|
||||
case IrOpcode::kRelocatableInt64Constant:
|
||||
return true;
|
||||
+ case IrOpcode::kNumberConstant: {
|
||||
+ const double value = OpParameter<double>(node->op());
|
||||
+ return bit_cast<int64_t>(value) == 0;
|
||||
+ }
|
||||
case IrOpcode::kHeapConstant: {
|
||||
// TODO(bmeurer): We must not dereference handles concurrently. If we
|
||||
// really have to this here, then we need to find a way to put this
|
||||
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 a085d55e1efe4e302c4c5e91453fae4f0d37dbe5..64e2d44cc85c23efe202d83e7680b3687c6d178d 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();
|
||||
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 96ea770e65b48dbecf7422b49ef4f8d2f0cfe2d0..3486925aed54f03db13554763a6146134e83d2bb 100644
|
||||
--- a/src/execution/isolate-inl.h
|
||||
+++ b/src/execution/isolate-inl.h
|
||||
@@ -35,7 +35,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 d30bb0a8ec26f58c6266a367101594a806d1fd0e..9be2d9cd9064d3cd30db26a8b6d572ce27800ff6 100644
|
||||
--- a/src/heap/cppgc/marker.cc
|
||||
+++ b/src/heap/cppgc/marker.cc
|
||||
@@ -241,6 +241,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 6e08fc3e10e38e9349f09071f74871a37f93f694..bf1f40bdbde2e985b9d69d64e4936d90abe1ee8a 100644
|
||||
--- a/src/heap/cppgc/marking-state.h
|
||||
+++ b/src/heap/cppgc/marking-state.h
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "include/cppgc/trace-trait.h"
|
||||
#include "include/cppgc/visitor.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"
|
||||
@@ -111,6 +112,8 @@ class MarkingStateBase {
|
||||
movable_slots_worklist_.reset();
|
||||
}
|
||||
|
||||
+ void set_in_atomic_pause() { in_atomic_pause_ = true; }
|
||||
+
|
||||
protected:
|
||||
inline void MarkAndPush(HeapObjectHeader&, TraceDescriptor);
|
||||
|
||||
@@ -144,6 +147,7 @@ class MarkingStateBase {
|
||||
movable_slots_worklist_;
|
||||
|
||||
size_t marked_bytes_ = 0;
|
||||
+ bool in_atomic_pause_ = false;
|
||||
};
|
||||
|
||||
MarkingStateBase::MarkingStateBase(HeapBase& heap,
|
||||
@@ -270,10 +274,19 @@ void MarkingStateBase::ProcessWeakContainer(const void* object,
|
||||
void MarkingStateBase::ProcessEphemeron(const void* key, const void* value,
|
||||
TraceDescriptor value_desc,
|
||||
Visitor& visitor) {
|
||||
- // 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) {
|
||||
if (value_desc.base_object_payload) {
|
||||
MarkAndPush(value_desc.base_object_payload, value_desc);
|
||||
} else {
|
||||
diff --git a/test/unittests/heap/cppgc/ephemeron-pair-unittest.cc b/test/unittests/heap/cppgc/ephemeron-pair-unittest.cc
|
||||
index 32a5929fe4094aaece314dcd90670c66c4649f02..f5d07c7fd52f9d5acd1e8ff1894f0eb2473b8612 100644
|
||||
--- a/test/unittests/heap/cppgc/ephemeron-pair-unittest.cc
|
||||
+++ b/test/unittests/heap/cppgc/ephemeron-pair-unittest.cc
|
||||
@@ -239,5 +239,50 @@ TEST_F(EphemeronPairTest, EphemeronPairWithEmptyMixinValue) {
|
||||
FinishMarking();
|
||||
}
|
||||
|
||||
+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 f2f81df3ee76603c24ccc8ce93beaedb7d1eeaac..d6c6944e0efe999ea2e4b1a74184e8a74de7312a 100644
|
||||
--- a/video/rtp_video_stream_receiver_frame_transformer_delegate.cc
|
||||
+++ b/video/rtp_video_stream_receiver_frame_transformer_delegate.cc
|
||||
@@ -58,6 +58,8 @@ class TransformableVideoReceiverFrame
|
||||
return std::move(frame_);
|
||||
}
|
||||
|
||||
+ Direction GetDirection() const override { return Direction::kReceiver; }
|
||||
+
|
||||
private:
|
||||
std::unique_ptr<RtpFrameObject> frame_;
|
||||
const VideoFrameMetadata metadata_;
|
||||
@@ -110,6 +112,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(
|
||||
65
script/generate-config-gypi.py
Executable file
65
script/generate-config-gypi.py
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
import ast
|
||||
import os
|
||||
import pprint
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
ELECTRON_DIR = os.path.abspath(os.path.join(__file__, '..', '..'))
|
||||
NODE_DIR = os.path.join(ELECTRON_DIR, '..', 'third_party', 'electron_node')
|
||||
|
||||
def run_node_configure(target_cpu):
|
||||
configure = os.path.join(NODE_DIR, 'configure.py')
|
||||
args = ['--dest-cpu', target_cpu]
|
||||
# Enabled in Chromium's V8.
|
||||
if target_cpu == 'arm64' or target_cpu == 'x64':
|
||||
args += ['--experimental-enable-pointer-compression']
|
||||
# Work around "No acceptable ASM compiler found" error on some Windows
|
||||
# machines, it breaks nothing since Electron does not use OpenSSL.
|
||||
if sys.platform == 'win32':
|
||||
args += ['--openssl-no-asm']
|
||||
subprocess.check_call([sys.executable, configure] + args)
|
||||
|
||||
def read_node_config_gypi():
|
||||
config_gypi = os.path.join(NODE_DIR, 'config.gypi')
|
||||
with open(config_gypi, 'r') as f:
|
||||
content = f.read()
|
||||
return ast.literal_eval(content)
|
||||
|
||||
def read_electron_args():
|
||||
all_gn = os.path.join(ELECTRON_DIR, 'build', 'args', 'all.gn')
|
||||
args = {}
|
||||
with open(all_gn, 'r') as f:
|
||||
for line in f:
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
m = re.match('([\w_]+) = (.+)', line)
|
||||
if m == None:
|
||||
continue
|
||||
args[m.group(1)] = m.group(2)
|
||||
return args
|
||||
|
||||
def main(target_file, target_cpu):
|
||||
run_node_configure(target_cpu)
|
||||
config = read_node_config_gypi()
|
||||
args = read_electron_args()
|
||||
|
||||
# Remove the generated config.gypi to make the parallel/test-process-config
|
||||
# test pass.
|
||||
os.remove(os.path.join(NODE_DIR, 'config.gypi'))
|
||||
|
||||
v = config['variables']
|
||||
# Electron specific variables:
|
||||
v['built_with_electron'] = 1
|
||||
v['node_module_version'] = int(args['node_module_version'])
|
||||
# Used by certain versions of node-gyp.
|
||||
v['build_v8_with_gn'] = 'false'
|
||||
|
||||
with open(target_file, 'w+') as f:
|
||||
f.write(pprint.pformat(config, indent=2))
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(*sys.argv[1:]))
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/common/extensions/command.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "shell/browser/api/electron_api_system_preferences.h"
|
||||
@@ -21,6 +22,7 @@
|
||||
#include "base/mac/mac_util.h"
|
||||
#endif
|
||||
|
||||
using extensions::Command;
|
||||
using extensions::GlobalShortcutListener;
|
||||
|
||||
namespace {
|
||||
@@ -28,22 +30,23 @@ namespace {
|
||||
#if defined(OS_MAC)
|
||||
bool RegisteringMediaKeyForUntrustedClient(const ui::Accelerator& accelerator) {
|
||||
if (base::mac::IsAtLeastOS10_14()) {
|
||||
constexpr ui::KeyboardCode mediaKeys[] = {
|
||||
ui::VKEY_MEDIA_PLAY_PAUSE, ui::VKEY_MEDIA_NEXT_TRACK,
|
||||
ui::VKEY_MEDIA_PREV_TRACK, ui::VKEY_MEDIA_STOP,
|
||||
ui::VKEY_VOLUME_UP, ui::VKEY_VOLUME_DOWN,
|
||||
ui::VKEY_VOLUME_MUTE};
|
||||
|
||||
if (std::find(std::begin(mediaKeys), std::end(mediaKeys),
|
||||
accelerator.key_code()) != std::end(mediaKeys)) {
|
||||
bool trusted =
|
||||
electron::api::SystemPreferences::IsTrustedAccessibilityClient(false);
|
||||
if (!trusted)
|
||||
if (Command::IsMediaKey(accelerator)) {
|
||||
if (!electron::api::SystemPreferences::IsTrustedAccessibilityClient(
|
||||
false))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MapHasMediaKeys(
|
||||
const std::map<ui::Accelerator, base::RepeatingClosure>& accelerator_map) {
|
||||
auto media_key = std::find_if(
|
||||
accelerator_map.begin(), accelerator_map.end(),
|
||||
[](const auto& ac) { return Command::IsMediaKey(ac.first); });
|
||||
|
||||
return media_key != accelerator_map.end();
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
@@ -83,7 +86,7 @@ bool GlobalShortcut::RegisterAll(
|
||||
|
||||
for (auto& accelerator : accelerators) {
|
||||
if (!Register(accelerator, callback)) {
|
||||
// unregister all shortcuts if any failed
|
||||
// Unregister all shortcuts if any failed.
|
||||
UnregisterSome(registered);
|
||||
return false;
|
||||
}
|
||||
@@ -101,8 +104,12 @@ bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
|
||||
return false;
|
||||
}
|
||||
#if defined(OS_MAC)
|
||||
if (RegisteringMediaKeyForUntrustedClient(accelerator))
|
||||
return false;
|
||||
if (Command::IsMediaKey(accelerator)) {
|
||||
if (RegisteringMediaKeyForUntrustedClient(accelerator))
|
||||
return false;
|
||||
|
||||
GlobalShortcutListener::SetShouldUseInternalMediaKeyHandling(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator,
|
||||
@@ -123,6 +130,13 @@ void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) {
|
||||
if (accelerator_callback_map_.erase(accelerator) == 0)
|
||||
return;
|
||||
|
||||
#if defined(OS_MAC)
|
||||
if (Command::IsMediaKey(accelerator) &&
|
||||
!MapHasMediaKeys(accelerator_callback_map_)) {
|
||||
GlobalShortcutListener::SetShouldUseInternalMediaKeyHandling(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(accelerator,
|
||||
this);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -911,6 +913,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_) {
|
||||
@@ -1415,6 +1423,12 @@ void WebContents::RenderFrameDeleted(
|
||||
// - Cross-origin navigation creates a new RFH in a separate process which
|
||||
// is swapped by content::RenderFrameHostManager.
|
||||
//
|
||||
|
||||
// clear out objects that have been granted permissions
|
||||
if (!granted_devices_.empty()) {
|
||||
granted_devices_.erase(render_frame_host->GetFrameTreeNodeId());
|
||||
}
|
||||
|
||||
// WebFrameMain::FromRenderFrameHost(rfh) will use the RFH's FrameTreeNode ID
|
||||
// to find an existing instance of WebFrameMain. During a cross-origin
|
||||
// navigation, the deleted RFH will be the old host which was swapped out. In
|
||||
@@ -1665,6 +1679,9 @@ void WebContents::MessageTo(bool internal,
|
||||
gin::Handle<WebFrameMain> web_frame_main =
|
||||
WebFrameMain::From(JavascriptEnvironment::GetIsolate(), frame);
|
||||
|
||||
if (!web_frame_main->CheckRenderFrame())
|
||||
return;
|
||||
|
||||
int32_t sender_id = ID();
|
||||
web_frame_main->GetRendererApi()->Message(internal, channel,
|
||||
std::move(arguments), sender_id);
|
||||
@@ -3210,6 +3227,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) {
|
||||
@@ -3258,6 +3295,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);
|
||||
@@ -3816,6 +3889,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)
|
||||
|
||||
@@ -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"
|
||||
@@ -90,6 +91,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>,
|
||||
@@ -323,6 +329,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_; }
|
||||
@@ -428,6 +435,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);
|
||||
@@ -786,6 +808,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_{this};
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebContents);
|
||||
|
||||
@@ -130,8 +130,10 @@ v8::Local<v8::Value> HttpResponseHeadersToV8(
|
||||
net::HttpContentDisposition header(value, std::string());
|
||||
std::string decodedFilename =
|
||||
header.is_attachment() ? " attachment" : " inline";
|
||||
decodedFilename += "; filename=" + header.filename();
|
||||
value = decodedFilename;
|
||||
// The filename must be encased in double quotes for serialization
|
||||
// to happen correctly.
|
||||
std::string filename = "\"" + header.filename() + "\"";
|
||||
value = decodedFilename + "; filename=" + filename;
|
||||
}
|
||||
if (!values)
|
||||
values = response_headers.SetKey(key, base::ListValue());
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -277,6 +285,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,
|
||||
|
||||
@@ -1108,8 +1108,17 @@ void NativeWindowViews::SetIgnoreMouseEvents(bool ignore, bool forward) {
|
||||
|
||||
void NativeWindowViews::SetContentProtection(bool enable) {
|
||||
#if defined(OS_WIN)
|
||||
HWND hwnd = GetAcceleratedWidget();
|
||||
DWORD affinity = enable ? WDA_EXCLUDEFROMCAPTURE : WDA_NONE;
|
||||
::SetWindowDisplayAffinity(GetAcceleratedWidget(), affinity);
|
||||
::SetWindowDisplayAffinity(hwnd, affinity);
|
||||
if (!layered_) {
|
||||
// Workaround to prevent black window on screen capture after hiding and
|
||||
// showing the BrowserWindow.
|
||||
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
ex_style |= WS_EX_LAYERED;
|
||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
||||
layered_ = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 13,5,1,0
|
||||
PRODUCTVERSION 13,5,1,0
|
||||
FILEVERSION 13,6,5,0
|
||||
PRODUCTVERSION 13,6,5,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -68,12 +68,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "13.5.1"
|
||||
VALUE "FileVersion", "13.6.5"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "13.5.1"
|
||||
VALUE "ProductVersion", "13.6.5"
|
||||
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);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/weak_ptr.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"
|
||||
@@ -53,8 +54,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_;
|
||||
|
||||
@@ -62,6 +62,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);
|
||||
|
||||
@@ -40,10 +40,10 @@ int FramelessView::ResizingBorderHitTest(const gfx::Point& point) {
|
||||
: false;
|
||||
|
||||
// https://github.com/electron/electron/issues/611
|
||||
// If window isn't resizable, we should always return HTCLIENT, otherwise the
|
||||
// If window isn't resizable, we should always return HTNOWHERE, otherwise the
|
||||
// hover state of DOM will not be cleared probably.
|
||||
if (!can_ever_resize)
|
||||
return HTCLIENT;
|
||||
return HTNOWHERE;
|
||||
|
||||
// Don't allow overlapping resize handles when the window is maximized or
|
||||
// fullscreen, as it can't be resized in those states.
|
||||
|
||||
@@ -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(
|
||||
@@ -118,6 +140,7 @@ void WebContentsPermissionHelper::RequestMediaAccessPermission(
|
||||
media_types->AppendString("video");
|
||||
}
|
||||
details.SetList("mediaTypes", std::move(media_types));
|
||||
details.SetString("securityOrigin", request.security_origin.spec());
|
||||
|
||||
// The permission type doesn't matter here, AUDIO_CAPTURE/VIDEO_CAPTURE
|
||||
// are presented as same type in content_converter.h.
|
||||
@@ -168,6 +191,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();
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -3628,7 +3628,7 @@ describe('BrowserWindow module', () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
const c = new BrowserWindow({ show: false, parent: w });
|
||||
expect(c.isVisible()).to.be.false('child is visible');
|
||||
expect(c.getParentWindow().isVisible()).to.be.false('parent is visible');
|
||||
expect(c.getParentWindow()!.isVisible()).to.be.false('parent is visible');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -318,7 +318,7 @@ describe('webRequest module', () => {
|
||||
|
||||
it('does not change content-disposition header by default', async () => {
|
||||
ses.webRequest.onHeadersReceived((details, callback) => {
|
||||
expect(details.responseHeaders!['content-disposition']).to.deep.equal([' attachment; filename=aa中aa.txt']);
|
||||
expect(details.responseHeaders!['content-disposition']).to.deep.equal([' attachment; filename="aa中aa.txt"']);
|
||||
callback({});
|
||||
});
|
||||
const { data, headers } = await ajax(defaultURL + 'contentDisposition');
|
||||
|
||||
@@ -940,6 +940,7 @@ describe('chromium features', () => {
|
||||
afterEach(closeAllWindows);
|
||||
afterEach(() => {
|
||||
session.defaultSession.setPermissionCheckHandler(null);
|
||||
session.defaultSession.setPermissionRequestHandler(null);
|
||||
});
|
||||
|
||||
it('can return labels of enumerated devices', async () => {
|
||||
@@ -989,6 +990,32 @@ describe('chromium features', () => {
|
||||
const [, secondDeviceIds] = await emittedOnce(ipcMain, 'deviceIds', () => w.webContents.reload());
|
||||
expect(firstDeviceIds).to.not.deep.equal(secondDeviceIds);
|
||||
});
|
||||
|
||||
it('provides a securityOrigin to the request handler', async () => {
|
||||
session.defaultSession.setPermissionRequestHandler(
|
||||
(wc, permission, callback, details) => {
|
||||
if (details.securityOrigin !== undefined) {
|
||||
callback(true);
|
||||
} else {
|
||||
callback(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
const w = new BrowserWindow({ show: false });
|
||||
w.loadFile(path.join(fixturesPath, 'pages', 'blank.html'));
|
||||
const labels = await w.webContents.executeJavaScript(`navigator.mediaDevices.getUserMedia({
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: "desktop",
|
||||
minWidth: 1280,
|
||||
maxWidth: 1280,
|
||||
minHeight: 720,
|
||||
maxHeight: 720
|
||||
}
|
||||
}
|
||||
}).then((stream) => stream.getVideoTracks())`);
|
||||
expect(labels.some((l: any) => l)).to.be.true();
|
||||
});
|
||||
});
|
||||
|
||||
describe('window.opener access', () => {
|
||||
|
||||
@@ -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 () {});
|
||||
});
|
||||
});
|
||||
|
||||
1
typings/internal-electron.d.ts
vendored
1
typings/internal-electron.d.ts
vendored
@@ -65,6 +65,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