mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
104 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
faf9434e32 | ||
|
|
3b682d6a98 | ||
|
|
8280b2bfbb | ||
|
|
9350e93520 | ||
|
|
72b4d197be | ||
|
|
00be927ad6 | ||
|
|
88d54af01e | ||
|
|
d7b6d3ffa3 | ||
|
|
9307bf2414 | ||
|
|
539b5c5418 | ||
|
|
06b8c9b36d | ||
|
|
f6402150fa | ||
|
|
44341c2c50 | ||
|
|
3fad4f2afa | ||
|
|
61ae10ab4d | ||
|
|
9ddc69b496 | ||
|
|
3e257c7a2d | ||
|
|
f79b489baa | ||
|
|
df1e7a0816 | ||
|
|
a9c419a8cc | ||
|
|
a20dae7e3f | ||
|
|
fbf024dba4 | ||
|
|
2c08cc711f | ||
|
|
98b44f86cb | ||
|
|
8ad7e2213d | ||
|
|
4e202b8bd0 | ||
|
|
99bbec4487 | ||
|
|
f59d898f5c | ||
|
|
6d34d0759d | ||
|
|
4737ea8a6d | ||
|
|
579bfa9403 | ||
|
|
a822d2639a | ||
|
|
9d6ac058c9 | ||
|
|
cbe66f27e7 | ||
|
|
4f10bde056 | ||
|
|
473c7dbe73 | ||
|
|
4515c4db00 | ||
|
|
6dd394a155 | ||
|
|
4ace4995c8 | ||
|
|
71e329663e | ||
|
|
67002fdf11 | ||
|
|
348b2fb9de | ||
|
|
f6ce6cafed | ||
|
|
76072270b5 | ||
|
|
c1842ab6ed | ||
|
|
1e38fb1a8d | ||
|
|
42efa2ad04 | ||
|
|
8b61d26a70 | ||
|
|
783590276e | ||
|
|
f7b6249d00 | ||
|
|
28350b4e00 | ||
|
|
31e8b9f4ba | ||
|
|
06902de06b | ||
|
|
f92b42eda5 | ||
|
|
3704dc9284 | ||
|
|
d321e2940e | ||
|
|
305d75516b | ||
|
|
5d18005338 | ||
|
|
ee27523363 | ||
|
|
368f583399 | ||
|
|
f6d3c565fe | ||
|
|
f11aad0784 | ||
|
|
b0cbf49ee0 | ||
|
|
f7c4199853 | ||
|
|
4a092ccdf2 | ||
|
|
71a104ae48 | ||
|
|
284017b22c | ||
|
|
e8e05f7e99 | ||
|
|
2734773305 | ||
|
|
db7ac3587e | ||
|
|
87d6f6f599 | ||
|
|
496b0f811f | ||
|
|
0d80baf528 | ||
|
|
bcf77df3d9 | ||
|
|
dfc9be60c9 | ||
|
|
3d6125894b | ||
|
|
d5fe2812ff | ||
|
|
13499392e9 | ||
|
|
03e7293384 | ||
|
|
9a7c2fa2af | ||
|
|
974be18991 | ||
|
|
acd8829190 | ||
|
|
cc5acfa0ed | ||
|
|
604cd3d09b | ||
|
|
413e41f7db | ||
|
|
4c485e53a4 | ||
|
|
e9427e7b92 | ||
|
|
36673bf5e6 | ||
|
|
fc9fb0b179 | ||
|
|
4ad03dc60a | ||
|
|
72dbe13f76 | ||
|
|
e6616d62e0 | ||
|
|
aa301f76d9 | ||
|
|
058e2e73bb | ||
|
|
59538c9b36 | ||
|
|
455228bed5 | ||
|
|
f9d18015e0 | ||
|
|
8fd0c11513 | ||
|
|
d40162e4bd | ||
|
|
a57e7eb2e5 | ||
|
|
12afb18487 | ||
|
|
89340008ee | ||
|
|
dd7c9fb55b | ||
|
|
26c6c81540 |
@@ -409,6 +409,7 @@ step-electron-build: &step-electron-build
|
||||
fi
|
||||
cd src
|
||||
ninja -C out/Default electron -j $NUMBER_OF_NINJA_PROCESSES
|
||||
node electron/script/check-symlinks.js
|
||||
|
||||
step-native-unittests-build: &step-native-unittests-build
|
||||
run:
|
||||
@@ -821,7 +822,7 @@ step-restore-out-cache: &step-restore-out-cache
|
||||
paths:
|
||||
- ./src/out/Default
|
||||
keys:
|
||||
- v7-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
- v8-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
name: Restoring out cache
|
||||
|
||||
step-set-git-cache-path: &step-set-git-cache-path
|
||||
@@ -845,7 +846,7 @@ step-save-out-cache: &step-save-out-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- ./src/out/Default
|
||||
key: v7-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
key: v8-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
name: Persisting out cache
|
||||
|
||||
step-run-electron-only-hooks: &step-run-electron-only-hooks
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
"ENABLE_DESKTOP_CAPTURER": "readonly",
|
||||
"ENABLE_ELECTRON_EXTENSIONS": "readonly",
|
||||
"ENABLE_REMOTE_MODULE": "readonly",
|
||||
"ENABLE_VIEW_API": "readonly"
|
||||
"ENABLE_VIEW_API": "readonly",
|
||||
"BigInt": "readonly"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
|
||||
35
BUILD.gn
35
BUILD.gn
@@ -333,10 +333,10 @@ source_set("electron_lib") {
|
||||
"shell/common/api:mojo",
|
||||
"//base:base_static",
|
||||
"//base/allocator:buildflags",
|
||||
"//chrome/app:command_ids",
|
||||
"//chrome/app/resources:platform_locale_settings",
|
||||
"//chrome/services/printing/public/mojom",
|
||||
"//components/certificate_transparency",
|
||||
"//components/crash/core/app",
|
||||
"//components/language/core/browser",
|
||||
"//components/net_log",
|
||||
"//components/network_hints/browser",
|
||||
@@ -442,6 +442,9 @@ source_set("electron_lib") {
|
||||
"*\bviews/*",
|
||||
]
|
||||
}
|
||||
if (!is_mas_build) {
|
||||
deps += [ "//components/crash/core/app" ]
|
||||
}
|
||||
|
||||
set_sources_assignment_filter(
|
||||
sources_assignment_filter + extra_source_filters)
|
||||
@@ -467,10 +470,13 @@ source_set("electron_lib") {
|
||||
deps += [
|
||||
"//components/remote_cocoa/app_shim",
|
||||
"//content/common:mac_helpers",
|
||||
"//third_party/crashpad/crashpad/client",
|
||||
"//ui/accelerated_widget_mac",
|
||||
]
|
||||
|
||||
if (!is_mas_build) {
|
||||
deps += [ "//third_party/crashpad/crashpad/client" ]
|
||||
}
|
||||
|
||||
libs = [
|
||||
"AVFoundation.framework",
|
||||
"Carbon.framework",
|
||||
@@ -491,6 +497,12 @@ source_set("electron_lib") {
|
||||
sources += [ "shell/browser/api/electron_api_app_mas.mm" ]
|
||||
sources -= [ "shell/browser/auto_updater_mac.mm" ]
|
||||
defines += [ "MAS_BUILD" ]
|
||||
sources -= [
|
||||
"shell/app/electron_crash_reporter_client.cc",
|
||||
"shell/app/electron_crash_reporter_client.h",
|
||||
"shell/common/crash_keys.cc",
|
||||
"shell/common/crash_keys.h",
|
||||
]
|
||||
} else {
|
||||
libs += [
|
||||
"Squirrel.framework",
|
||||
@@ -533,6 +545,16 @@ source_set("electron_lib") {
|
||||
|
||||
sources += filenames.lib_sources_nss
|
||||
sources += [
|
||||
"shell/browser/ui/gtk/app_indicator_icon.cc",
|
||||
"shell/browser/ui/gtk/app_indicator_icon.h",
|
||||
"shell/browser/ui/gtk/app_indicator_icon_menu.cc",
|
||||
"shell/browser/ui/gtk/app_indicator_icon_menu.h",
|
||||
"shell/browser/ui/gtk/gtk_status_icon.cc",
|
||||
"shell/browser/ui/gtk/gtk_status_icon.h",
|
||||
"shell/browser/ui/gtk/menu_util.cc",
|
||||
"shell/browser/ui/gtk/menu_util.h",
|
||||
"shell/browser/ui/gtk/status_icon.cc",
|
||||
"shell/browser/ui/gtk/status_icon.h",
|
||||
"shell/browser/ui/gtk_util.cc",
|
||||
"shell/browser/ui/gtk_util.h",
|
||||
]
|
||||
@@ -785,8 +807,10 @@ if (is_mac) {
|
||||
framework_contents = [
|
||||
"Resources",
|
||||
"Libraries",
|
||||
"Helpers",
|
||||
]
|
||||
if (!is_mas_build) {
|
||||
framework_contents += [ "Helpers" ]
|
||||
}
|
||||
public_deps = [
|
||||
":electron_framework_libraries",
|
||||
":electron_lib",
|
||||
@@ -1017,13 +1041,16 @@ if (is_mac) {
|
||||
|
||||
group("electron_symbols") {
|
||||
deps = [
|
||||
":crashpad_handler_syms",
|
||||
":electron_app_syms",
|
||||
":electron_framework_syms",
|
||||
":swiftshader_egl_syms",
|
||||
":swiftshader_gles_syms",
|
||||
]
|
||||
|
||||
if (!is_mas_build) {
|
||||
deps += [ ":crashpad_handler_syms" ]
|
||||
}
|
||||
|
||||
foreach(helper_params, content_mac_helpers) {
|
||||
_helper_target = helper_params[0]
|
||||
deps += [ ":electron_helper_syms_${_helper_target}" ]
|
||||
|
||||
2
DEPS
2
DEPS
@@ -12,7 +12,7 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'83.0.4103.94',
|
||||
'83.0.4103.122',
|
||||
'node_version':
|
||||
'v12.14.1',
|
||||
'nan_version':
|
||||
|
||||
@@ -1 +1 @@
|
||||
9.0.1
|
||||
9.1.2
|
||||
@@ -1,3 +1,4 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
|
||||
@@ -9,6 +10,9 @@ config.output = {
|
||||
filename: path.basename(outPath)
|
||||
}
|
||||
|
||||
const { wrapInitWithProfilingTimeout } = config;
|
||||
delete config.wrapInitWithProfilingTimeout;
|
||||
|
||||
webpack(config, (err, stats) => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
@@ -17,6 +21,18 @@ webpack(config, (err, stats) => {
|
||||
console.error(stats.toString('normal'))
|
||||
process.exit(1)
|
||||
} else {
|
||||
if (wrapInitWithProfilingTimeout) {
|
||||
const contents = fs.readFileSync(outPath, 'utf8');
|
||||
const newContents = `function ___electron_webpack_init__() {
|
||||
${contents}
|
||||
};
|
||||
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
|
||||
setTimeout(___electron_webpack_init__, 0);
|
||||
} else {
|
||||
___electron_webpack_init__();
|
||||
}`;
|
||||
fs.writeFileSync(outPath, newContents);
|
||||
}
|
||||
process.exit(0)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
|
||||
const electronRoot = path.resolve(__dirname, '../..')
|
||||
|
||||
@@ -21,7 +22,7 @@ class AccessDependenciesPlugin {
|
||||
}
|
||||
|
||||
const defines = {
|
||||
BUILDFLAG: ''
|
||||
BUILDFLAG: onlyPrintingGraph ? '(a => a)' : ''
|
||||
}
|
||||
|
||||
const buildFlagsPrefix = '--buildflags='
|
||||
@@ -34,9 +35,8 @@ if (buildFlagArg) {
|
||||
for (const line of flagFile.split(/(\r\n|\r|\n)/g)) {
|
||||
const flagMatch = line.match(/#define BUILDFLAG_INTERNAL_(.+?)\(\) \(([01])\)/)
|
||||
if (flagMatch) {
|
||||
const flagName = flagMatch[1]
|
||||
const flagValue = flagMatch[2]
|
||||
defines[flagName] = JSON.stringify(Boolean(parseInt(flagValue, 10)))
|
||||
const [, flagName, flagValue] = flagMatch;
|
||||
defines[flagName] = JSON.stringify(Boolean(parseInt(flagValue, 10)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,16 +81,12 @@ if (defines['ENABLE_ELECTRON_EXTENSIONS'] === 'false') {
|
||||
)
|
||||
}
|
||||
|
||||
const alias = {}
|
||||
for (const ignoredModule of ignoredModules) {
|
||||
alias[ignoredModule] = path.resolve(electronRoot, 'lib/common/dummy.js')
|
||||
}
|
||||
|
||||
module.exports = ({
|
||||
alwaysHasNode,
|
||||
loadElectronFromAlternateTarget,
|
||||
targetDeletesNodeGlobals,
|
||||
target
|
||||
target,
|
||||
wrapInitWithProfilingTimeout
|
||||
}) => {
|
||||
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts')
|
||||
if (!fs.existsSync(entry)) {
|
||||
@@ -99,30 +95,36 @@ module.exports = ({
|
||||
|
||||
return ({
|
||||
mode: 'development',
|
||||
devtool: 'inline-source-map',
|
||||
devtool: false,
|
||||
entry,
|
||||
target: alwaysHasNode ? 'node' : 'web',
|
||||
output: {
|
||||
filename: `${target}.bundle.js`
|
||||
},
|
||||
wrapInitWithProfilingTimeout,
|
||||
resolve: {
|
||||
alias: {
|
||||
...alias,
|
||||
'@electron/internal': path.resolve(electronRoot, 'lib'),
|
||||
'electron': path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts'),
|
||||
// Force timers to resolve to our dependency that doens't use window.postMessage
|
||||
// Force timers to resolve to our dependency that doesn't use window.postMessage
|
||||
'timers': path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
|
||||
},
|
||||
extensions: ['.ts', '.js']
|
||||
},
|
||||
module: {
|
||||
rules: [{
|
||||
test: (moduleName) => !onlyPrintingGraph && ignoredModules.includes(moduleName),
|
||||
loader: 'null-loader',
|
||||
}, {
|
||||
test: /\.ts$/,
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
configFile: path.resolve(electronRoot, 'tsconfig.electron.json'),
|
||||
transpileOnly: onlyPrintingGraph,
|
||||
ignoreDiagnostics: [6059]
|
||||
ignoreDiagnostics: [
|
||||
// File '{0}' is not under 'rootDir' '{1}'.
|
||||
6059,
|
||||
]
|
||||
}
|
||||
}]
|
||||
},
|
||||
@@ -133,6 +135,17 @@ module.exports = ({
|
||||
// one of our renderer bundles should import it from the 'timers' package
|
||||
setImmediate: false,
|
||||
},
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
terserOptions: {
|
||||
keep_classnames: true,
|
||||
keep_fnames: true,
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new AccessDependenciesPlugin(),
|
||||
...(targetDeletesNodeGlobals ? [
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
module.exports = require('./webpack.config.base')({
|
||||
target: 'renderer',
|
||||
alwaysHasNode: true,
|
||||
targetDeletesNodeGlobals: true
|
||||
targetDeletesNodeGlobals: true,
|
||||
wrapInitWithProfilingTimeout: true
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
module.exports = require('./webpack.config.base')({
|
||||
target: 'sandboxed_renderer',
|
||||
alwaysHasNode: false
|
||||
alwaysHasNode: false,
|
||||
wrapInitWithProfilingTimeout: true,
|
||||
})
|
||||
|
||||
@@ -16,6 +16,7 @@ template("webpack_build") {
|
||||
inputs = [
|
||||
invoker.config_file,
|
||||
"//electron/build/webpack/webpack.config.base.js",
|
||||
"//electron/build/webpack/run-compiler.js",
|
||||
"//electron/tsconfig.json",
|
||||
"//electron/yarn.lock",
|
||||
"//electron/typings/internal-ambient.d.ts",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { app, dialog, BrowserWindow, shell, ipcMain } from 'electron';
|
||||
import * as path from 'path';
|
||||
import * as url from 'url';
|
||||
|
||||
let mainWindow: BrowserWindow | null = null;
|
||||
|
||||
@@ -29,12 +30,11 @@ function isTrustedSender (webContents: Electron.WebContents) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const parsedUrl = new URL(webContents.getURL());
|
||||
const urlPath = process.platform === 'win32'
|
||||
// Strip the prefixed "/" that occurs on windows
|
||||
? path.resolve(parsedUrl.pathname.substr(1))
|
||||
: parsedUrl.pathname;
|
||||
return parsedUrl.protocol === 'file:' && urlPath === indexPath;
|
||||
try {
|
||||
return url.fileURLToPath(webContents.getURL()) === indexPath;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ipcMain.handle('bootstrap', (event) => {
|
||||
|
||||
@@ -369,6 +369,25 @@ Returns:
|
||||
|
||||
Emitted when the renderer process of `webContents` crashes or is killed.
|
||||
|
||||
#### Event: 'render-process-gone'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
* `details` Object
|
||||
* `reason` String - The reason the render process is gone. Possible values:
|
||||
* `clean-exit` - Process exited with an exit code of zero
|
||||
* `abnormal-exit` - Process exited with a non-zero exit code
|
||||
* `killed` - Process was sent a SIGTERM or otherwise killed externally
|
||||
* `crashed` - Process crashed
|
||||
* `oom` - Process ran out of memory
|
||||
* `launch-failure` - Process never successfully launched
|
||||
* `integrity-failure` - Windows code integrity checks failed
|
||||
|
||||
Emitted when the renderer process unexpectedly dissapears. This is normally
|
||||
because it was crashed or killed.
|
||||
|
||||
### Event: 'accessibility-support-changed' _macOS_ _Windows_
|
||||
|
||||
Returns:
|
||||
@@ -1354,7 +1373,7 @@ in your app's initialization to ensure that your overridden value is used.
|
||||
|
||||
A `Boolean` which when `true` disables the overrides that Electron has in place
|
||||
to ensure renderer processes are restarted on every navigation. The current
|
||||
default value for this property is `false`.
|
||||
default value for this property is `true`.
|
||||
|
||||
The intention is for these overrides to become disabled by default and then at
|
||||
some point in the future this property will be removed. This property impacts
|
||||
|
||||
@@ -387,6 +387,13 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
Default is `true`.
|
||||
* `enableWebSQL` Boolean (optional) - Whether to enable the [WebSQL api](https://www.w3.org/TR/webdatabase/).
|
||||
Default is `true`.
|
||||
* `v8CacheOptions` String (optional) - Enforces the v8 code caching policy
|
||||
used by blink. Accepted values are
|
||||
* `none` - Disables code caching
|
||||
* `code` - Heuristic based code caching
|
||||
* `bypassHeatCheck` - Bypass code caching heuristics but with lazy compilation
|
||||
* `bypassHeatCheckAndEagerCompile` - Same as above except compilation is eager.
|
||||
Default policy is `code`.
|
||||
|
||||
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
|
||||
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
|
||||
@@ -1116,7 +1123,7 @@ Disable or enable the window.
|
||||
|
||||
#### `win.isEnabled()`
|
||||
|
||||
Returns Boolean - whether the window is enabled.
|
||||
Returns `Boolean` - whether the window is enabled.
|
||||
|
||||
#### `win.setSize(width, height[, animate])`
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@ Disables the disk cache for HTTP requests.
|
||||
|
||||
Disable HTTP/2 and SPDY/3.1 protocols.
|
||||
|
||||
### --disable-ntlm-v2
|
||||
|
||||
Disables NTLM v2 for posix platforms, no effect elsewhere.
|
||||
|
||||
## --lang
|
||||
|
||||
Set a custom locale.
|
||||
|
||||
@@ -52,6 +52,8 @@ Returns:
|
||||
* `method` String - Method name.
|
||||
* `params` any - Event parameters defined by the 'parameters'
|
||||
attribute in the remote debugging protocol.
|
||||
* `sessionId` String - Unique identifier of attached debugging session,
|
||||
will match the value sent from `debugger.sendCommand`.
|
||||
|
||||
Emitted whenever the debugging target issues an instrumentation event.
|
||||
|
||||
@@ -74,11 +76,16 @@ Returns `Boolean` - Whether a debugger is attached to the `webContents`.
|
||||
|
||||
Detaches the debugger from the `webContents`.
|
||||
|
||||
#### `debugger.sendCommand(method[, commandParams])`
|
||||
#### `debugger.sendCommand(method[, commandParams, sessionId])`
|
||||
|
||||
* `method` String - Method name, should be one of the methods defined by the
|
||||
[remote debugging protocol][rdp].
|
||||
* `commandParams` any (optional) - JSON object with request parameters.
|
||||
* `sessionId` String (optional) - send command to the target with associated
|
||||
debugging session id. The initial value can be obtained by sending
|
||||
[Target.attachToTarget][attachToTarget] message.
|
||||
|
||||
[attachToTarget]: https://chromedevtools.github.io/devtools-protocol/tot/Target/#method-attachToTarget
|
||||
|
||||
Returns `Promise<any>` - A promise that resolves with the response defined by
|
||||
the 'returns' attribute of the command description in the remote debugging protocol
|
||||
|
||||
@@ -57,7 +57,7 @@ Removes all listeners, or those of the specified `channel`.
|
||||
|
||||
Send an asynchronous message to the main process via `channel`, along with
|
||||
arguments. Arguments will be serialized with the [Structured Clone
|
||||
Algorithm][SCA], just like [`postMessage`][], so prototype chains will not be
|
||||
Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will not be
|
||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
@@ -68,6 +68,10 @@ throw an exception.
|
||||
The main process handles it by listening for `channel` with the
|
||||
[`ipcMain`](ipc-main.md) module.
|
||||
|
||||
If you need to transfer a [`MessagePort`][] to the main process, use [`ipcRenderer.postMessage`](#ipcrendererpostmessagechannel-message-transfer).
|
||||
|
||||
If you want to receive a single response from the main process, like the result of a method call, consider using [`ipcRenderer.invoke`](#ipcrendererinvokechannel-args).
|
||||
|
||||
### `ipcRenderer.invoke(channel, ...args)`
|
||||
|
||||
* `channel` String
|
||||
@@ -77,7 +81,7 @@ Returns `Promise<any>` - Resolves with the response from the main process.
|
||||
|
||||
Send a message to the main process via `channel` and expect a result
|
||||
asynchronously. Arguments will be serialized with the [Structured Clone
|
||||
Algorithm][SCA], just like [`postMessage`][], so prototype chains will not be
|
||||
Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will not be
|
||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
@@ -102,6 +106,10 @@ ipcMain.handle('some-name', async (event, someArgument) => {
|
||||
})
|
||||
```
|
||||
|
||||
If you need to transfer a [`MessagePort`][] to the main process, use [`ipcRenderer.postMessage`](#ipcrendererpostmessagechannel-message-transfer).
|
||||
|
||||
If you do not need a respons to the message, consider using [`ipcRenderer.send`](#ipcrenderersendchannel-args).
|
||||
|
||||
### `ipcRenderer.sendSync(channel, ...args)`
|
||||
|
||||
* `channel` String
|
||||
@@ -111,7 +119,7 @@ Returns `any` - The value sent back by the [`ipcMain`](ipc-main.md) handler.
|
||||
|
||||
Send a message to the main process via `channel` and expect a result
|
||||
synchronously. Arguments will be serialized with the [Structured Clone
|
||||
Algorithm][SCA], just like [`postMessage`][], so prototype chains will not be
|
||||
Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will not be
|
||||
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
|
||||
throw an exception.
|
||||
|
||||
@@ -127,6 +135,35 @@ and replies by setting `event.returnValue`.
|
||||
> last resort. It's much better to use the asynchronous version,
|
||||
> [`invoke()`](ipc-renderer.md#ipcrendererinvokechannel-args).
|
||||
|
||||
### `ipcRenderer.postMessage(channel, message, [transfer])`
|
||||
|
||||
* `channel` String
|
||||
* `message` any
|
||||
* `transfer` MessagePort[] (optional)
|
||||
|
||||
Send a message to the main process, optionally transferring ownership of zero
|
||||
or more [`MessagePort`][] objects.
|
||||
|
||||
The transferred `MessagePort` objects will be available in the main process as
|
||||
[`MessagePortMain`](message-port-main.md) objects by accessing the `ports`
|
||||
property of the emitted event.
|
||||
|
||||
For example:
|
||||
```js
|
||||
// Renderer process
|
||||
const { port1, port2 } = new MessageChannel()
|
||||
ipcRenderer.postMessage('port', { message: 'hello' }, [port1])
|
||||
|
||||
// Main process
|
||||
ipcMain.on('port', (e, msg) => {
|
||||
const [port] = e.ports
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
For more information on using `MessagePort` and `MessageChannel`, see the [MDN
|
||||
documentation](https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel).
|
||||
|
||||
### `ipcRenderer.sendTo(webContentsId, channel, ...args)`
|
||||
|
||||
* `webContentsId` Number
|
||||
@@ -150,4 +187,5 @@ in the [`ipc-renderer-event`](structures/ipc-renderer-event.md) structure docs.
|
||||
|
||||
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
|
||||
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
|
||||
[`postMessage`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
|
||||
[`window.postMessage`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
|
||||
[`MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
|
||||
|
||||
@@ -12,7 +12,7 @@ See [`Menu`](menu.md) for examples.
|
||||
* `click` Function (optional) - Will be called with
|
||||
`click(menuItem, browserWindow, event)` when the menu item is clicked.
|
||||
* `menuItem` MenuItem
|
||||
* `browserWindow` [BrowserWindow](browser-window.md)
|
||||
* `browserWindow` [BrowserWindow](browser-window.md) | undefined - This will not be defined if no window is open.
|
||||
* `event` [KeyboardEvent](structures/keyboard-event.md)
|
||||
* `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
|
||||
`click` property will be ignored. See [roles](#roles).
|
||||
|
||||
30
docs/api/message-channel-main.md
Normal file
30
docs/api/message-channel-main.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# MessageChannelMain
|
||||
|
||||
`MessageChannelMain` is the main-process-side equivalent of the DOM
|
||||
[`MessageChannel`][] object. Its singular function is to create a pair of
|
||||
connected [`MessagePortMain`](message-port-main.md) objects.
|
||||
|
||||
See the [Channel Messaging API][] documentation for more information on using
|
||||
channel messaging.
|
||||
|
||||
## Class: MessageChannelMain
|
||||
|
||||
Example:
|
||||
```js
|
||||
const { port1, port2 } = new MessageChannelMain()
|
||||
w.webContents.postMessage('port', null, [port2])
|
||||
port1.postMessage({ some: 'message' })
|
||||
```
|
||||
|
||||
### Instance Properties
|
||||
|
||||
#### `channel.port1`
|
||||
|
||||
A [`MessagePortMain`](message-port-main.md) property.
|
||||
|
||||
#### `channel.port2`
|
||||
|
||||
A [`MessagePortMain`](message-port-main.md) property.
|
||||
|
||||
[`MessageChannel`]: https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel
|
||||
[Channel Messaging API]: https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API
|
||||
49
docs/api/message-port-main.md
Normal file
49
docs/api/message-port-main.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# MessagePortMain
|
||||
|
||||
`MessagePortMain` is the main-process-side equivalent of the DOM
|
||||
[`MessagePort`][] object. It behaves similarly to the DOM version, with the
|
||||
exception that it uses the Node.js `EventEmitter` event system, instead of the
|
||||
DOM `EventTarget` system. This means you should use `port.on('message', ...)`
|
||||
to listen for events, instead of `port.onmessage = ...` or
|
||||
`port.addEventListener('message', ...)`
|
||||
|
||||
See the [Channel Messaging API][] documentation for more information on using
|
||||
channel messaging.
|
||||
|
||||
`MessagePortMain` is an [EventEmitter][event-emitter].
|
||||
|
||||
## Class: MessagePortMain
|
||||
|
||||
### Instance Methods
|
||||
|
||||
#### `port.postMessage(message, [transfer])`
|
||||
|
||||
* `message` any
|
||||
* `transfer` MessagePortMain[] (optional)
|
||||
|
||||
Sends a message from the port, and optionally, transfers ownership of objects
|
||||
to other browsing contexts.
|
||||
|
||||
#### `port.start()`
|
||||
|
||||
Starts the sending of messages queued on the port. Messages will be queued
|
||||
until this method is called.
|
||||
|
||||
#### `port.close()`
|
||||
|
||||
Disconnects the port, so it is no longer active.
|
||||
|
||||
### Instance Events
|
||||
|
||||
#### Event: 'message'
|
||||
|
||||
Returns:
|
||||
|
||||
* `messageEvent` Object
|
||||
* `data` any
|
||||
* `ports` MessagePortMain[]
|
||||
|
||||
Emitted when a MessagePortMain object receives a message.
|
||||
|
||||
[`MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
|
||||
[Channel Messaging API]: https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API
|
||||
@@ -24,11 +24,11 @@ app.whenReady().then(() => {
|
||||
|
||||
The `powerMonitor` module emits the following events:
|
||||
|
||||
### Event: 'suspend'
|
||||
### Event: 'suspend' _Linux_ _Windows_
|
||||
|
||||
Emitted when the system is suspending.
|
||||
|
||||
### Event: 'resume'
|
||||
### Event: 'resume' _Linux_ _Windows_
|
||||
|
||||
Emitted when system is resuming.
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* `frameId` Integer - The ID of the renderer frame that sent this message
|
||||
* `returnValue` any - Set this to the value to be returned in a synchronous message
|
||||
* `sender` WebContents - Returns the `webContents` that sent the message
|
||||
* `ports` MessagePortMain[] - A list of MessagePorts that were transferred with this message
|
||||
* `reply` Function - A function that will send an IPC message to the renderer frame that sent the original message that you are currently handling. You should use this method to "reply" to the sent message in order to guarantee the reply will go to the correct process and frame.
|
||||
* `channel` String
|
||||
* `...args` any[]
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
|
||||
* `sender` IpcRenderer - The `IpcRenderer` instance that emitted the event originally
|
||||
* `senderId` Integer - The `webContents.id` that sent the message, you can call `event.sender.sendTo(event.senderId, ...)` to reply to the message, see [ipcRenderer.sendTo][ipc-renderer-sendto] for more information. This only applies to messages sent from a different renderer. Messages sent directly from the main process set `event.senderId` to `0`.
|
||||
* `ports` MessagePort[] - A list of MessagePorts that were transferred with this message
|
||||
|
||||
[ipc-renderer-sendto]: #ipcrenderersendtowindowid-channel--arg1-arg2-
|
||||
|
||||
@@ -416,7 +416,7 @@ This API itself will not protect your user data; rather, it is a mechanism to al
|
||||
|
||||
Returns `Boolean` - `true` if the current process is a trusted accessibility client and `false` if it is not.
|
||||
|
||||
### `systemPreferences.getMediaAccessStatus(mediaType)` _macOS_
|
||||
### `systemPreferences.getMediaAccessStatus(mediaType)` _Windows_ _macOS_
|
||||
|
||||
* `mediaType` String - Can be `microphone`, `camera` or `screen`.
|
||||
|
||||
@@ -426,6 +426,9 @@ This user consent was not required on macOS 10.13 High Sierra or lower so this m
|
||||
macOS 10.14 Mojave or higher requires consent for `microphone` and `camera` access.
|
||||
macOS 10.15 Catalina or higher requires consent for `screen` access.
|
||||
|
||||
Windows 10 has a global setting controlling `microphone` and `camera` access for all win32 applications.
|
||||
It will always return `granted` for `screen` and for all media types on older versions of Windows.
|
||||
|
||||
### `systemPreferences.askForMediaAccess(mediaType)` _macOS_
|
||||
|
||||
* `mediaType` String - the type of media being requested; can be `microphone`, `camera`.
|
||||
|
||||
@@ -325,7 +325,7 @@ win.webContents.on('will-prevent-unload', (event) => {
|
||||
})
|
||||
```
|
||||
|
||||
#### Event: 'crashed'
|
||||
#### Event: 'crashed' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -334,6 +334,29 @@ Returns:
|
||||
|
||||
Emitted when the renderer process crashes or is killed.
|
||||
|
||||
**Deprecated:** This event is superceded by the `render-process-gone` event
|
||||
which contains more information about why the render process dissapeared. It
|
||||
isn't always because it crashed. The `killed` boolean can be replaced by
|
||||
checking `reason === 'killed'` when you switch to that event.
|
||||
|
||||
#### Event: 'render-process-gone'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `reason` String - The reason the render process is gone. Possible values:
|
||||
* `clean-exit` - Process exited with an exit code of zero
|
||||
* `abnormal-exit` - Process exited with a non-zero exit code
|
||||
* `killed` - Process was sent a SIGTERM or otherwise killed externally
|
||||
* `crashed` - Process crashed
|
||||
* `oom` - Process ran out of memory
|
||||
* `launch-failure` - Process never successfully launched
|
||||
* `integrity-failure` - Windows code integrity checks failed
|
||||
|
||||
Emitted when the renderer process unexpectedly dissapears. This is normally
|
||||
because it was crashed or killed.
|
||||
|
||||
#### Event: 'unresponsive'
|
||||
|
||||
Emitted when the web page becomes unresponsive.
|
||||
@@ -366,6 +389,7 @@ Returns:
|
||||
* `key` String - Equivalent to [KeyboardEvent.key][keyboardevent].
|
||||
* `code` String - Equivalent to [KeyboardEvent.code][keyboardevent].
|
||||
* `isAutoRepeat` Boolean - Equivalent to [KeyboardEvent.repeat][keyboardevent].
|
||||
* `isComposing` Boolean - Equivalent to [KeyboardEvent.isComposing][keyboardevent].
|
||||
* `shift` Boolean - Equivalent to [KeyboardEvent.shiftKey][keyboardevent].
|
||||
* `control` Boolean - Equivalent to [KeyboardEvent.controlKey][keyboardevent].
|
||||
* `alt` Boolean - Equivalent to [KeyboardEvent.altKey][keyboardevent].
|
||||
@@ -1274,6 +1298,8 @@ Returns [`PrinterInfo[]`](structures/printer-info.md)
|
||||
* `success` Boolean - Indicates success of the print call.
|
||||
* `failureReason` String - Error description called back if the print fails.
|
||||
|
||||
When a custom `pageSize` is passed, Chromium attempts to validate platform specific minumum values for `width_microns` and `height_microns`. Width and height must both be minimum 353 microns but may be higher on some operating systems.
|
||||
|
||||
Prints window's web page. When `silent` is set to `true`, Electron will pick
|
||||
the system's default printer if `deviceName` is empty and the default settings for printing.
|
||||
|
||||
@@ -1297,13 +1323,12 @@ win.webContents.print(options, (success, errorType) => {
|
||||
* `landscape` Boolean (optional) - `true` for landscape, `false` for portrait.
|
||||
* `marginsType` Integer (optional) - Specifies the type of margins to use. Uses 0 for
|
||||
default margin, 1 for no margin, and 2 for minimum margin.
|
||||
and `width` in microns.
|
||||
* `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100.
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print.
|
||||
* `from` Number - the first page to print.
|
||||
* `to` Number - the last page to print (inclusive).
|
||||
* `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height`
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` and `width` in microns.
|
||||
* `printBackground` Boolean (optional) - Whether to print CSS backgrounds.
|
||||
* `printSelectionOnly` Boolean (optional) - Whether to print selection only.
|
||||
|
||||
@@ -1579,6 +1604,32 @@ ipcMain.on('ping', (event) => {
|
||||
})
|
||||
```
|
||||
|
||||
#### `contents.postMessage(channel, message, [transfer])`
|
||||
|
||||
* `channel` String
|
||||
* `message` any
|
||||
* `transfer` MessagePortMain[] (optional)
|
||||
|
||||
Send a message to the renderer process, optionally transferring ownership of
|
||||
zero or more [`MessagePortMain`][] objects.
|
||||
|
||||
The transferred `MessagePortMain` objects will be available in the renderer
|
||||
process by accessing the `ports` property of the emitted event. When they
|
||||
arrive in the renderer, they will be native DOM `MessagePort` objects.
|
||||
|
||||
For example:
|
||||
```js
|
||||
// Main process
|
||||
const { port1, port2 } = new MessageChannelMain()
|
||||
webContents.postMessage('port', { message: 'hello' }, [port1])
|
||||
|
||||
// Renderer process
|
||||
ipcRenderer.on('port', (e, msg) => {
|
||||
const [port] = e.ports
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
#### `contents.enableDeviceEmulation(parameters)`
|
||||
|
||||
* `parameters` Object
|
||||
|
||||
@@ -55,7 +55,9 @@ template("electron_extra_paks") {
|
||||
output = "${invoker.output_dir}/resources.pak"
|
||||
sources = [
|
||||
"$root_gen_dir/components/components_resources.pak",
|
||||
"$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
|
||||
"$root_gen_dir/content/browser/tracing/tracing_resources.pak",
|
||||
"$root_gen_dir/content/browser/webrtc/resources/webrtc_internals_resources.pak",
|
||||
"$root_gen_dir/content/content_resources.pak",
|
||||
"$root_gen_dir/content/dev_ui_content_resources.pak",
|
||||
"$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
|
||||
@@ -68,7 +70,9 @@ template("electron_extra_paks") {
|
||||
"//components/resources",
|
||||
"//content:content_resources",
|
||||
"//content:dev_ui_content_resources",
|
||||
"//content/browser/resources/media:media_internals_resources",
|
||||
"//content/browser/tracing:resources",
|
||||
"//content/browser/webrtc/resources",
|
||||
"//electron:resources",
|
||||
"//mojo/public/js:resources",
|
||||
"//net:net_resources",
|
||||
|
||||
@@ -32,6 +32,8 @@ auto_filenames = {
|
||||
"docs/api/locales.md",
|
||||
"docs/api/menu-item.md",
|
||||
"docs/api/menu.md",
|
||||
"docs/api/message-channel-main.md",
|
||||
"docs/api/message-port-main.md",
|
||||
"docs/api/modernization",
|
||||
"docs/api/native-image.md",
|
||||
"docs/api/native-theme.md",
|
||||
@@ -223,6 +225,7 @@ auto_filenames = {
|
||||
"lib/browser/api/menu-item.js",
|
||||
"lib/browser/api/menu-utils.js",
|
||||
"lib/browser/api/menu.js",
|
||||
"lib/browser/api/message-channel.ts",
|
||||
"lib/browser/api/module-list.ts",
|
||||
"lib/browser/api/native-theme.ts",
|
||||
"lib/browser/api/net-log.js",
|
||||
@@ -258,6 +261,7 @@ auto_filenames = {
|
||||
"lib/browser/ipc-main-impl.ts",
|
||||
"lib/browser/ipc-main-internal-utils.ts",
|
||||
"lib/browser/ipc-main-internal.ts",
|
||||
"lib/browser/message-port-main.ts",
|
||||
"lib/browser/navigation-controller.js",
|
||||
"lib/browser/remote/objects-registry.ts",
|
||||
"lib/browser/remote/server.ts",
|
||||
|
||||
@@ -125,6 +125,8 @@ filenames = {
|
||||
"shell/browser/api/gpu_info_enumerator.h",
|
||||
"shell/browser/api/gpuinfo_manager.cc",
|
||||
"shell/browser/api/gpuinfo_manager.h",
|
||||
"shell/browser/api/message_port.cc",
|
||||
"shell/browser/api/message_port.h",
|
||||
"shell/browser/api/process_metric.cc",
|
||||
"shell/browser/api/process_metric.h",
|
||||
"shell/browser/api/save_page_handler.cc",
|
||||
@@ -510,8 +512,11 @@ filenames = {
|
||||
"shell/common/gin_helper/event_emitter_caller.h",
|
||||
"shell/common/gin_helper/function_template.cc",
|
||||
"shell/common/gin_helper/function_template.h",
|
||||
"shell/common/gin_helper/function_template_extensions.h",
|
||||
"shell/common/gin_helper/locker.cc",
|
||||
"shell/common/gin_helper/locker.h",
|
||||
"shell/common/gin_helper/microtasks_scope.cc",
|
||||
"shell/common/gin_helper/microtasks_scope.h",
|
||||
"shell/common/gin_helper/object_template_builder.cc",
|
||||
"shell/common/gin_helper/object_template_builder.h",
|
||||
"shell/common/gin_helper/persistent_dictionary.cc",
|
||||
@@ -559,6 +564,8 @@ filenames = {
|
||||
"shell/common/skia_util.h",
|
||||
"shell/common/v8_value_converter.cc",
|
||||
"shell/common/v8_value_converter.h",
|
||||
"shell/common/v8_value_serializer.cc",
|
||||
"shell/common/v8_value_serializer.h",
|
||||
"shell/common/world_ids.h",
|
||||
"shell/renderer/api/context_bridge/object_cache.cc",
|
||||
"shell/renderer/api/context_bridge/object_cache.h",
|
||||
|
||||
@@ -249,7 +249,11 @@ module.exports = {
|
||||
},
|
||||
|
||||
showCertificateTrustDialog: function (window, options) {
|
||||
if (window && window.constructor !== BrowserWindow) options = window;
|
||||
if (window && window.constructor !== BrowserWindow) {
|
||||
options = window;
|
||||
window = null;
|
||||
}
|
||||
|
||||
if (options == null || typeof options !== 'object') {
|
||||
throw new TypeError('options must be an object');
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ const roles = {
|
||||
},
|
||||
pasteandmatchstyle: {
|
||||
label: 'Paste and Match Style',
|
||||
accelerator: 'Shift+CommandOrControl+V',
|
||||
accelerator: isMac ? 'Cmd+Option+Shift+V' : 'Shift+CommandOrControl+V',
|
||||
webContentsMethod: 'pasteAndMatchStyle',
|
||||
registerAccelerator: false
|
||||
},
|
||||
|
||||
12
lib/browser/api/message-channel.ts
Normal file
12
lib/browser/api/message-channel.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { MessagePortMain } from '@electron/internal/browser/message-port-main';
|
||||
const { createPair } = process.electronBinding('message_port');
|
||||
|
||||
export default class MessageChannelMain {
|
||||
port1: MessagePortMain;
|
||||
port2: MessagePortMain;
|
||||
constructor () {
|
||||
const { port1, port2 } = createPair();
|
||||
this.port1 = new MessagePortMain(port1);
|
||||
this.port2 = new MessagePortMain(port2);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ export const browserModuleList: ElectronInternal.ModuleEntry[] = [
|
||||
{ name: 'inAppPurchase', loader: () => require('./in-app-purchase') },
|
||||
{ name: 'Menu', loader: () => require('./menu') },
|
||||
{ name: 'MenuItem', loader: () => require('./menu-item') },
|
||||
{ name: 'MessageChannelMain', loader: () => require('./message-channel') },
|
||||
{ name: 'nativeTheme', loader: () => require('./native-theme') },
|
||||
{ name: 'net', loader: () => require('./net') },
|
||||
{ name: 'netLog', loader: () => require('./net-log') },
|
||||
|
||||
@@ -20,6 +20,7 @@ export const browserModuleNames = [
|
||||
'nativeTheme',
|
||||
'net',
|
||||
'netLog',
|
||||
'MessageChannelMain',
|
||||
'Notification',
|
||||
'powerMonitor',
|
||||
'powerSaveBlocker',
|
||||
|
||||
@@ -10,6 +10,7 @@ const { internalWindowOpen } = require('@electron/internal/browser/guest-window-
|
||||
const NavigationController = require('@electron/internal/browser/navigation-controller');
|
||||
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal');
|
||||
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils');
|
||||
const { MessagePortMain } = require('@electron/internal/browser/message-port-main');
|
||||
|
||||
// session is not used here, the purpose is to make sure session is initalized
|
||||
// before the webContents module.
|
||||
@@ -62,6 +63,19 @@ const PDFPageSizes = {
|
||||
}
|
||||
};
|
||||
|
||||
// The minimum micron size Chromium accepts is that where:
|
||||
// Per printing/units.h:
|
||||
// * kMicronsPerInch - Length of an inch in 0.001mm unit.
|
||||
// * kPointsPerInch - Length of an inch in CSS's 1pt unit.
|
||||
//
|
||||
// Formula: (kPointsPerInch / kMicronsPerInch) * size >= 1
|
||||
//
|
||||
// Practically, this means microns need to be > 352 microns.
|
||||
// We therefore need to verify this or it will silently fail.
|
||||
const isValidCustomPageSize = (width, height) => {
|
||||
return [width, height].every(x => x > 352);
|
||||
};
|
||||
|
||||
// Default printing setting
|
||||
const defaultPrintingSetting = {
|
||||
// Customizable.
|
||||
@@ -114,6 +128,13 @@ WebContents.prototype.send = function (channel, ...args) {
|
||||
return this._send(internal, sendToAll, channel, args);
|
||||
};
|
||||
|
||||
WebContents.prototype.postMessage = function (...args) {
|
||||
if (Array.isArray(args[2])) {
|
||||
args[2] = args[2].map(o => o instanceof MessagePortMain ? o._internalPort : o);
|
||||
}
|
||||
this._postMessage(...args);
|
||||
};
|
||||
|
||||
WebContents.prototype.sendToAll = function (channel, ...args) {
|
||||
if (typeof channel !== 'string') {
|
||||
throw new Error('Missing required channel argument');
|
||||
@@ -309,13 +330,20 @@ WebContents.prototype.printToPDF = function (options) {
|
||||
const error = new Error('height and width properties are required for pageSize');
|
||||
return Promise.reject(error);
|
||||
}
|
||||
// Dimensions in Microns
|
||||
// 1 meter = 10^6 microns
|
||||
|
||||
// Dimensions in Microns - 1 meter = 10^6 microns
|
||||
const height = Math.ceil(pageSize.height);
|
||||
const width = Math.ceil(pageSize.width);
|
||||
if (!isValidCustomPageSize(width, height)) {
|
||||
const error = new Error('height and width properties must be minimum 352 microns.');
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
printSettings.mediaSize = {
|
||||
name: 'CUSTOM',
|
||||
custom_display_name: 'Custom',
|
||||
height_microns: Math.ceil(pageSize.height),
|
||||
width_microns: Math.ceil(pageSize.width)
|
||||
height_microns: height,
|
||||
width_microns: width
|
||||
};
|
||||
} else if (PDFPageSizes[pageSize]) {
|
||||
printSettings.mediaSize = PDFPageSizes[pageSize];
|
||||
@@ -350,12 +378,19 @@ WebContents.prototype.print = function (options = {}, callback) {
|
||||
if (!pageSize.height || !pageSize.width) {
|
||||
throw new Error('height and width properties are required for pageSize');
|
||||
}
|
||||
|
||||
// Dimensions in Microns - 1 meter = 10^6 microns
|
||||
const height = Math.ceil(pageSize.height);
|
||||
const width = Math.ceil(pageSize.width);
|
||||
if (!isValidCustomPageSize(width, height)) {
|
||||
throw new Error('height and width properties must be minimum 352 microns.');
|
||||
}
|
||||
|
||||
options.mediaSize = {
|
||||
name: 'CUSTOM',
|
||||
custom_display_name: 'Custom',
|
||||
height_microns: Math.ceil(pageSize.height),
|
||||
width_microns: Math.ceil(pageSize.width)
|
||||
height_microns: height,
|
||||
width_microns: width
|
||||
};
|
||||
} else if (PDFPageSizes[pageSize]) {
|
||||
options.mediaSize = PDFPageSizes[pageSize];
|
||||
@@ -471,6 +506,11 @@ WebContents.prototype._init = function () {
|
||||
}
|
||||
});
|
||||
|
||||
this.on('-ipc-ports', function (event, internal, channel, message, ports) {
|
||||
event.ports = ports.map(p => new MessagePortMain(p));
|
||||
ipcMain.emit(channel, event, message);
|
||||
});
|
||||
|
||||
// Handle context menu action request from pepper plugin.
|
||||
this.on('pepper-context-menu', function (event, params, callback) {
|
||||
// Access Menu via electron.Menu to prevent circular require.
|
||||
@@ -487,6 +527,10 @@ WebContents.prototype._init = function () {
|
||||
app.emit('renderer-process-crashed', event, this, ...args);
|
||||
});
|
||||
|
||||
this.on('render-process-gone', (event, ...args) => {
|
||||
app.emit('render-process-gone', event, this, ...args);
|
||||
});
|
||||
|
||||
// The devtools requests the webContents to reload.
|
||||
this.on('devtools-reload-page', function () {
|
||||
this.reload();
|
||||
|
||||
@@ -32,6 +32,7 @@ const supportedWebViewEvents = [
|
||||
'focus-change',
|
||||
'close',
|
||||
'crashed',
|
||||
'render-process-gone',
|
||||
'plugin-crashed',
|
||||
'destroyed',
|
||||
'page-title-updated',
|
||||
|
||||
25
lib/browser/message-port-main.ts
Normal file
25
lib/browser/message-port-main.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
export class MessagePortMain extends EventEmitter {
|
||||
_internalPort: any
|
||||
constructor (internalPort: any) {
|
||||
super();
|
||||
this._internalPort = internalPort;
|
||||
this._internalPort.emit = (channel: string, event: {ports: any[]}) => {
|
||||
if (channel === 'message') { event = { ...event, ports: event.ports.map(p => new MessagePortMain(p)) }; }
|
||||
this.emit(channel, event);
|
||||
};
|
||||
}
|
||||
start () {
|
||||
return this._internalPort.start();
|
||||
}
|
||||
close () {
|
||||
return this._internalPort.close();
|
||||
}
|
||||
postMessage (...args: any[]) {
|
||||
if (Array.isArray(args[1])) {
|
||||
args[1] = args[1].map((o: any) => o instanceof MessagePortMain ? o._internalPort : o);
|
||||
}
|
||||
return this._internalPort.postMessage(...args);
|
||||
}
|
||||
}
|
||||
@@ -572,7 +572,7 @@
|
||||
};
|
||||
|
||||
const { readdir } = fs;
|
||||
fs.readdir = function (pathArgument, options, callback) {
|
||||
fs.readdir = function (pathArgument, options = {}, callback) {
|
||||
const { isAsar, asarPath, filePath } = splitPath(pathArgument);
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
@@ -594,13 +594,29 @@
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.withFileTypes) {
|
||||
const dirents = [];
|
||||
for (const file of files) {
|
||||
const stats = archive.stat(file);
|
||||
if (stats.isFile) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
|
||||
} else if (stats.isDirectory) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_DIR));
|
||||
} else if (stats.isLink) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_LINK));
|
||||
}
|
||||
}
|
||||
nextTick(callback, [null, dirents]);
|
||||
return;
|
||||
}
|
||||
|
||||
nextTick(callback, [null, files]);
|
||||
};
|
||||
|
||||
fs.promises.readdir = util.promisify(fs.readdir);
|
||||
|
||||
const { readdirSync } = fs;
|
||||
fs.readdirSync = function (pathArgument, options) {
|
||||
fs.readdirSync = function (pathArgument, options = {}) {
|
||||
const { isAsar, asarPath, filePath } = splitPath(pathArgument);
|
||||
if (!isAsar) return readdirSync.apply(this, arguments);
|
||||
|
||||
@@ -614,6 +630,21 @@
|
||||
throw createError(AsarError.NOT_FOUND, { asarPath, filePath });
|
||||
}
|
||||
|
||||
if (options.withFileTypes) {
|
||||
const dirents = [];
|
||||
for (const file of files) {
|
||||
const stats = archive.stat(file);
|
||||
if (stats.isFile) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
|
||||
} else if (stats.isDirectory) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_DIR));
|
||||
} else if (stats.isLink) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_LINK));
|
||||
}
|
||||
}
|
||||
return dirents;
|
||||
}
|
||||
|
||||
return files;
|
||||
};
|
||||
|
||||
|
||||
@@ -31,4 +31,8 @@ if (!ipcRenderer.send) {
|
||||
};
|
||||
}
|
||||
|
||||
ipcRenderer.postMessage = function (channel: string, message: any, transferables: any) {
|
||||
return ipc.postMessage(channel, message, transferables);
|
||||
};
|
||||
|
||||
export default ipcRenderer;
|
||||
|
||||
@@ -45,9 +45,9 @@ v8Util.setHiddenValue(global, 'ipc', ipcEmitter);
|
||||
v8Util.setHiddenValue(global, 'ipc-internal', ipcInternalEmitter);
|
||||
|
||||
v8Util.setHiddenValue(global, 'ipcNative', {
|
||||
onMessage (internal: boolean, channel: string, args: any[], senderId: number) {
|
||||
onMessage (internal: boolean, channel: string, ports: any[], args: any[], senderId: number) {
|
||||
const sender = internal ? ipcInternalEmitter : ipcEmitter;
|
||||
sender.emit(channel, { sender, senderId }, ...args);
|
||||
sender.emit(channel, { sender, senderId, ports }, ...args);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -54,9 +54,9 @@ const loadedModules = new Map([
|
||||
// ElectronApiServiceImpl will look for the "ipcNative" hidden object when
|
||||
// invoking the 'onMessage' callback.
|
||||
v8Util.setHiddenValue(global, 'ipcNative', {
|
||||
onMessage (internal, channel, args, senderId) {
|
||||
onMessage (internal, channel, ports, args, senderId) {
|
||||
const sender = internal ? ipcRendererInternal : electron.ipcRenderer;
|
||||
sender.emit(channel, { sender, senderId }, ...args);
|
||||
sender.emit(channel, { sender, senderId, ports }, ...args);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "9.0.1",
|
||||
"version": "9.1.2",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
@@ -47,6 +47,7 @@
|
||||
"lint-staged": "^8.1.0",
|
||||
"minimist": "^1.2.0",
|
||||
"nugget": "^2.0.1",
|
||||
"null-loader": "^4.0.0",
|
||||
"pre-flight": "^1.1.0",
|
||||
"remark-cli": "^4.0.0",
|
||||
"remark-preset-lint-markdown-style-guide": "^2.1.1",
|
||||
@@ -61,8 +62,8 @@
|
||||
"ts-loader": "^6.0.2",
|
||||
"ts-node": "^6.0.3",
|
||||
"typescript": "^3.5.2",
|
||||
"webpack": "^4.32.2",
|
||||
"webpack-cli": "^3.3.2"
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -71,6 +71,7 @@ expose_setuseragent_on_networkcontext.patch
|
||||
feat_add_set_theme_source_to_allow_apps_to.patch
|
||||
revert_cleanup_remove_menu_subtitles_sublabels.patch
|
||||
export_fetchapi_mojo_traits_to_fix_component_build.patch
|
||||
add_webmessageportconverter_entangleandinjectmessageportchannel.patch
|
||||
revert_remove_contentrendererclient_shouldfork.patch
|
||||
ignore_rc_check.patch
|
||||
remove_usage_of_incognito_apis_in_the_spellchecker.patch
|
||||
@@ -99,3 +100,19 @@ breakpad_treat_node_processes_as_browser_processes.patch
|
||||
upload_list_add_loadsync_method.patch
|
||||
breakpad_allow_getting_string_values_for_crash_keys.patch
|
||||
fix_hunspell_crash.patch
|
||||
fix_swap_global_proxies_before_initializing_the_windows_proxies.patch
|
||||
fix_default_to_ntlm_v2_in_network_service.patch
|
||||
a11y_iterate_all_descendants_for_getselectioncount.patch
|
||||
a11y_allows_klistboxoption_as_an_item_to_kgroup.patch
|
||||
fix_handling_non_client_pointer_events_from_pen_on_windows_10.patch
|
||||
allow_ime_to_insert_zero_length_composition_string.patch
|
||||
remove_menu_window_task_item.patch
|
||||
backport_1087629.patch
|
||||
backport_1065122.patch
|
||||
backport_1074317.patch
|
||||
backport_1090543.patch
|
||||
backport_1081722.patch
|
||||
backport_1073409.patch
|
||||
backport_1074340.patch
|
||||
backport_1016278.patch
|
||||
backport_1042986.patch
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Julie Jeongeun Kim <jkim@igalia.com>
|
||||
Date: Fri, 3 Apr 2020 19:22:20 +0000
|
||||
Subject: a11y: Allows kListBoxOption as an item to kGroup
|
||||
|
||||
This CL adds ListBoxOption role as an item for Group role in
|
||||
AXNode::SetRoleMatchesItemRole() since Group role could have
|
||||
ListBoxOption as an item[1]. With this change, when the parent
|
||||
of ListBoxOption is a group role, PosInSet and SetSize has
|
||||
proper values.
|
||||
|
||||
[1]https://w3c.github.io/aria-practices/examples/listbox/listbox-grouped.html
|
||||
|
||||
Bug: 1066632
|
||||
Change-Id: I23cf0c34ee479d6e8ee33b3f9e327def820527e1
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2134037
|
||||
Commit-Queue: Dominic Mazzoni <dmazzoni@chromium.org>
|
||||
Reviewed-by: Dominic Mazzoni <dmazzoni@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#756360}
|
||||
|
||||
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc
|
||||
index b2012c7ac2169d366923b9b1f5645f03401ea44a..0db263e38b2364fb660d305dddf42c65483e015a 100644
|
||||
--- a/ui/accessibility/ax_node.cc
|
||||
+++ b/ui/accessibility/ax_node.cc
|
||||
@@ -819,6 +819,7 @@ bool AXNode::SetRoleMatchesItemRole(const AXNode* ordered_set) const {
|
||||
item_role == ax::mojom::Role::kListItem ||
|
||||
item_role == ax::mojom::Role::kMenuItem ||
|
||||
item_role == ax::mojom::Role::kMenuItemRadio ||
|
||||
+ item_role == ax::mojom::Role::kListBoxOption ||
|
||||
item_role == ax::mojom::Role::kTreeItem;
|
||||
case ax::mojom::Role::kMenu:
|
||||
return item_role == ax::mojom::Role::kMenuItem ||
|
||||
diff --git a/ui/accessibility/ax_tree_unittest.cc b/ui/accessibility/ax_tree_unittest.cc
|
||||
index c48318b7a8cc592cf9adc97a2cb29124c7578250..3cf7532755f2163a372233ca63c88cae20b8f272 100644
|
||||
--- a/ui/accessibility/ax_tree_unittest.cc
|
||||
+++ b/ui/accessibility/ax_tree_unittest.cc
|
||||
@@ -3647,6 +3647,43 @@ TEST(AXTreeTest, TestSetSizePosInSetMenuItemValidChildOfMenuListPopup) {
|
||||
EXPECT_OPTIONAL_EQ(2, item2->GetSetSize());
|
||||
}
|
||||
|
||||
+TEST(AXTreeTest, TestSetSizePostInSetListBoxOptionWithGroup) {
|
||||
+ AXTreeUpdate initial_state;
|
||||
+ initial_state.root_id = 1;
|
||||
+ initial_state.nodes.resize(7);
|
||||
+ initial_state.nodes[0].id = 1;
|
||||
+ initial_state.nodes[0].child_ids = {2, 3};
|
||||
+ initial_state.nodes[0].role = ax::mojom::Role::kListBox;
|
||||
+ initial_state.nodes[1].id = 2;
|
||||
+ initial_state.nodes[1].child_ids = {4, 5};
|
||||
+ initial_state.nodes[1].role = ax::mojom::Role::kGroup;
|
||||
+ initial_state.nodes[2].id = 3;
|
||||
+ initial_state.nodes[2].child_ids = {6, 7};
|
||||
+ initial_state.nodes[2].role = ax::mojom::Role::kGroup;
|
||||
+ initial_state.nodes[3].id = 4;
|
||||
+ initial_state.nodes[3].role = ax::mojom::Role::kListBoxOption;
|
||||
+ initial_state.nodes[4].id = 5;
|
||||
+ initial_state.nodes[4].role = ax::mojom::Role::kListBoxOption;
|
||||
+ initial_state.nodes[5].id = 6;
|
||||
+ initial_state.nodes[5].role = ax::mojom::Role::kListBoxOption;
|
||||
+ initial_state.nodes[6].id = 7;
|
||||
+ initial_state.nodes[6].role = ax::mojom::Role::kListBoxOption;
|
||||
+ AXTree tree(initial_state);
|
||||
+
|
||||
+ AXNode* listbox_option1 = tree.GetFromId(4);
|
||||
+ EXPECT_OPTIONAL_EQ(1, listbox_option1->GetPosInSet());
|
||||
+ EXPECT_OPTIONAL_EQ(2, listbox_option1->GetSetSize());
|
||||
+ AXNode* listbox_option2 = tree.GetFromId(5);
|
||||
+ EXPECT_OPTIONAL_EQ(2, listbox_option2->GetPosInSet());
|
||||
+ EXPECT_OPTIONAL_EQ(2, listbox_option2->GetSetSize());
|
||||
+ AXNode* listbox_option3 = tree.GetFromId(6);
|
||||
+ EXPECT_OPTIONAL_EQ(1, listbox_option3->GetPosInSet());
|
||||
+ EXPECT_OPTIONAL_EQ(2, listbox_option3->GetSetSize());
|
||||
+ AXNode* listbox_option4 = tree.GetFromId(7);
|
||||
+ EXPECT_OPTIONAL_EQ(2, listbox_option4->GetPosInSet());
|
||||
+ EXPECT_OPTIONAL_EQ(2, listbox_option4->GetSetSize());
|
||||
+}
|
||||
+
|
||||
TEST(AXTreeTest, OnNodeWillBeDeletedHasValidUnignoredParent) {
|
||||
AXTreeUpdate initial_state;
|
||||
initial_state.root_id = 1;
|
||||
@@ -0,0 +1,580 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Julie Jeongeun Kim <jkim@igalia.com>
|
||||
Date: Fri, 10 Apr 2020 05:50:17 +0000
|
||||
Subject: a11y: Iterate all descendants for GetSelectionCount
|
||||
|
||||
This CL iterates all descendants for GetSelectionCount and
|
||||
GetSelectedChild. When listbox has group children, it should
|
||||
iterates their children as well to check the select state.
|
||||
|
||||
Bug: 1058961
|
||||
Change-Id: Ib6459bf6f47023d4258ef4c2f2dc545739d7a61b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2115211
|
||||
Commit-Queue: Julie Kim <jkim@igalia.com>
|
||||
Reviewed-by: Nektarios Paisios <nektar@chromium.org>
|
||||
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
|
||||
Reviewed-by: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
Cr-Commit-Position: refs/heads/master@{#758140}
|
||||
|
||||
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
|
||||
index 773ca872f48b548af2cf9bf5b27291e85a7a563d..2f150dbbae32f9faae0f8b55a65133fb333aa5e5 100644
|
||||
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
|
||||
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
|
||||
@@ -1512,19 +1512,10 @@ AtkObject* RefSelection(AtkSelection* selection, gint requested_child_index) {
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
- int child_count = obj->GetChildCount();
|
||||
- gint selected_count = 0;
|
||||
- for (int i = 0; i < child_count; ++i) {
|
||||
- AtkObject* child = obj->ChildAtIndex(i);
|
||||
- AXPlatformNodeAuraLinux* child_ax_node =
|
||||
- AtkObjectToAXPlatformNodeAuraLinux(child);
|
||||
- if (!child_ax_node)
|
||||
- continue;
|
||||
-
|
||||
- if (child_ax_node->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
|
||||
- if (selected_count == requested_child_index)
|
||||
- return static_cast<AtkObject*>(g_object_ref(child));
|
||||
- ++selected_count;
|
||||
+ if (auto* selected_child = obj->GetSelectedItem(requested_child_index)) {
|
||||
+ if (AtkObject* atk_object = selected_child->GetNativeViewAccessible()) {
|
||||
+ g_object_ref(atk_object);
|
||||
+ return atk_object;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1539,19 +1530,7 @@ gint GetSelectionCount(AtkSelection* selection) {
|
||||
if (!obj)
|
||||
return 0;
|
||||
|
||||
- int child_count = obj->GetChildCount();
|
||||
- gint selected_count = 0;
|
||||
- for (int i = 0; i < child_count; ++i) {
|
||||
- AXPlatformNodeAuraLinux* child =
|
||||
- AtkObjectToAXPlatformNodeAuraLinux(obj->ChildAtIndex(i));
|
||||
- if (!child)
|
||||
- continue;
|
||||
-
|
||||
- if (child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
|
||||
- ++selected_count;
|
||||
- }
|
||||
-
|
||||
- return selected_count;
|
||||
+ return obj->GetSelectionCount();
|
||||
}
|
||||
|
||||
gboolean IsChildSelected(AtkSelection* selection, gint index) {
|
||||
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
|
||||
index fdae0972a0197133d80bfb8a935a4d30ec73a8e3..9ce1fa7e36aa6fd4255772226718388c1c148f40 100644
|
||||
--- a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
|
||||
+++ b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
|
||||
@@ -1859,6 +1859,8 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkSelectionInterface) {
|
||||
AXNodeData root;
|
||||
root.id = 1;
|
||||
root.role = ax::mojom::Role::kListBox;
|
||||
+ root.AddState(ax::mojom::State::kFocusable);
|
||||
+ root.AddState(ax::mojom::State::kMultiselectable);
|
||||
root.child_ids.push_back(2);
|
||||
root.child_ids.push_back(3);
|
||||
root.child_ids.push_back(4);
|
||||
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc
|
||||
index ebff0e2b2640fa44ff189a735e98ec2c558fe44d..12ec1674a79bdc1f28d5d2b1bb4792b81cd8608f 100644
|
||||
--- a/ui/accessibility/platform/ax_platform_node_base.cc
|
||||
+++ b/ui/accessibility/platform/ax_platform_node_base.cc
|
||||
@@ -130,7 +130,7 @@ int AXPlatformNodeBase::GetChildCount() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
-gfx::NativeViewAccessible AXPlatformNodeBase::ChildAtIndex(int index) {
|
||||
+gfx::NativeViewAccessible AXPlatformNodeBase::ChildAtIndex(int index) const {
|
||||
if (delegate_)
|
||||
return delegate_->ChildAtIndex(index);
|
||||
return nullptr;
|
||||
@@ -2058,6 +2058,54 @@ ui::TextAttributeList AXPlatformNodeBase::ComputeTextAttributes() const {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
+int AXPlatformNodeBase::GetSelectionCount() const {
|
||||
+ int max_items = GetMaxSelectableItems();
|
||||
+ if (!max_items)
|
||||
+ return 0;
|
||||
+ return GetSelectedItems(max_items);
|
||||
+}
|
||||
+
|
||||
+AXPlatformNodeBase* AXPlatformNodeBase::GetSelectedItem(
|
||||
+ int selected_index) const {
|
||||
+ DCHECK_GE(selected_index, 0);
|
||||
+ int max_items = GetMaxSelectableItems();
|
||||
+ if (max_items == 0)
|
||||
+ return nullptr;
|
||||
+ if (selected_index >= max_items)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ std::vector<AXPlatformNodeBase*> selected_children;
|
||||
+ int requested_count = selected_index + 1;
|
||||
+ int returned_count = GetSelectedItems(requested_count, &selected_children);
|
||||
+
|
||||
+ if (returned_count <= selected_index)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ DCHECK(!selected_children.empty());
|
||||
+ DCHECK_LT(selected_index, static_cast<int>(selected_children.size()));
|
||||
+ return selected_children[selected_index];
|
||||
+}
|
||||
+
|
||||
+int AXPlatformNodeBase::GetSelectedItems(
|
||||
+ int max_items,
|
||||
+ std::vector<AXPlatformNodeBase*>* out_selected_items) const {
|
||||
+ int selected_count = 0;
|
||||
+ // TODO(Nektar): Remove const_cast by making all tree traversal methods const.
|
||||
+ for (AXPlatformNodeBase* child =
|
||||
+ const_cast<AXPlatformNodeBase*>(this)->GetFirstChild();
|
||||
+ child && selected_count < max_items; child = child->GetNextSibling()) {
|
||||
+ if (!IsItemLike(child->GetData().role)) {
|
||||
+ selected_count += child->GetSelectedItems(max_items - selected_count,
|
||||
+ out_selected_items);
|
||||
+ } else if (child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
|
||||
+ selected_count++;
|
||||
+ if (out_selected_items)
|
||||
+ out_selected_items->emplace_back(child);
|
||||
+ }
|
||||
+ }
|
||||
+ return selected_count;
|
||||
+}
|
||||
+
|
||||
void AXPlatformNodeBase::SanitizeTextAttributeValue(const std::string& input,
|
||||
std::string* output) const {
|
||||
DCHECK(output);
|
||||
@@ -2116,4 +2164,20 @@ std::string AXPlatformNodeBase::ComputeDetailsRoles() const {
|
||||
return base::JoinString(details_roles_vector, " ");
|
||||
}
|
||||
|
||||
+int AXPlatformNodeBase::GetMaxSelectableItems() const {
|
||||
+ if (!GetData().HasState(ax::mojom::State::kFocusable))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (IsLeaf())
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!IsContainerWithSelectableChildren(GetData().role))
|
||||
+ return 0;
|
||||
+
|
||||
+ int max_items = 1;
|
||||
+ if (GetData().HasState(ax::mojom::State::kMultiselectable))
|
||||
+ max_items = std::numeric_limits<int>::max();
|
||||
+ return max_items;
|
||||
+}
|
||||
+
|
||||
} // namespace ui
|
||||
diff --git a/ui/accessibility/platform/ax_platform_node_base.h b/ui/accessibility/platform/ax_platform_node_base.h
|
||||
index b46cf48d223b49d196aff10b5822e35628a45469..0355f281a600979f59a25086fd7400201693bf89 100644
|
||||
--- a/ui/accessibility/platform/ax_platform_node_base.h
|
||||
+++ b/ui/accessibility/platform/ax_platform_node_base.h
|
||||
@@ -64,7 +64,7 @@ class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode {
|
||||
gfx::NativeViewAccessible GetFocus();
|
||||
gfx::NativeViewAccessible GetParent() const;
|
||||
int GetChildCount() const;
|
||||
- gfx::NativeViewAccessible ChildAtIndex(int index);
|
||||
+ gfx::NativeViewAccessible ChildAtIndex(int index) const;
|
||||
|
||||
std::string GetName() const;
|
||||
base::string16 GetNameAsString16() const;
|
||||
@@ -312,6 +312,24 @@ class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode {
|
||||
|
||||
ui::TextAttributeList ComputeTextAttributes() const;
|
||||
|
||||
+ // Get the number of items selected. It checks kMultiselectable and
|
||||
+ // kFocusable. and uses GetSelectedItems to get the selected number.
|
||||
+ int GetSelectionCount() const;
|
||||
+
|
||||
+ // If this object is a container that supports selectable children, returns
|
||||
+ // the selected item at the provided index.
|
||||
+ AXPlatformNodeBase* GetSelectedItem(int selected_index) const;
|
||||
+
|
||||
+ // If this object is a container that supports selectable children,
|
||||
+ // returns the number of selected items in this container.
|
||||
+ // |out_selected_items| could be set to nullptr if the caller just
|
||||
+ // needs to know the number of items selected.
|
||||
+ // |max_items| represents the number that the caller expects as a
|
||||
+ // maximum. For a single selection list box, it will be 1.
|
||||
+ int GetSelectedItems(
|
||||
+ int max_items,
|
||||
+ std::vector<AXPlatformNodeBase*>* out_selected_items = nullptr) const;
|
||||
+
|
||||
//
|
||||
// Delegate. This is a weak reference which owns |this|.
|
||||
//
|
||||
@@ -454,6 +472,11 @@ class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode {
|
||||
|
||||
std::string GetInvalidValue() const;
|
||||
|
||||
+ // Based on the characteristics of this object, such as its role and the
|
||||
+ // presence of a multiselectable attribute, returns the maximum number of
|
||||
+ // selectable children that this object could potentially contain.
|
||||
+ int GetMaxSelectableItems() const;
|
||||
+
|
||||
mutable AXHypertext hypertext_;
|
||||
|
||||
private:
|
||||
diff --git a/ui/accessibility/platform/ax_platform_node_base_unittest.cc b/ui/accessibility/platform/ax_platform_node_base_unittest.cc
|
||||
index d0bc34a70e5c96062a2d1a24b2a6e8c087098b47..401d5be24b9f1957f4425f32b150006d094c6838 100644
|
||||
--- a/ui/accessibility/platform/ax_platform_node_base_unittest.cc
|
||||
+++ b/ui/accessibility/platform/ax_platform_node_base_unittest.cc
|
||||
@@ -96,4 +96,200 @@ TEST(AXPlatformNodeBaseTest, InnerTextIgnoresInvisibleAndIgnored) {
|
||||
}
|
||||
}
|
||||
|
||||
+TEST(AXPlatformNodeBaseTest, TestSelectedChildren) {
|
||||
+ AXPlatformNode::NotifyAddAXModeFlags(kAXModeComplete);
|
||||
+
|
||||
+ AXNodeData root_data;
|
||||
+ root_data.id = 1;
|
||||
+ root_data.role = ax::mojom::Role::kListBox;
|
||||
+ root_data.AddState(ax::mojom::State::kFocusable);
|
||||
+ root_data.child_ids = {2, 3};
|
||||
+
|
||||
+ AXNodeData item_1_data;
|
||||
+ item_1_data.id = 2;
|
||||
+ item_1_data.role = ax::mojom::Role::kListBoxOption;
|
||||
+ item_1_data.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
|
||||
+
|
||||
+ AXNodeData item_2_data;
|
||||
+ item_2_data.id = 3;
|
||||
+ item_2_data.role = ax::mojom::Role::kListBoxOption;
|
||||
+
|
||||
+ AXTreeUpdate update;
|
||||
+ update.root_id = 1;
|
||||
+ update.nodes = {root_data, item_1_data, item_2_data};
|
||||
+ AXTree tree(update);
|
||||
+
|
||||
+ auto* root = static_cast<AXPlatformNodeBase*>(
|
||||
+ TestAXNodeWrapper::GetOrCreate(&tree, tree.root())->ax_platform_node());
|
||||
+
|
||||
+ int num = root->GetSelectionCount();
|
||||
+ EXPECT_EQ(num, 1);
|
||||
+
|
||||
+ gfx::NativeViewAccessible first_child = root->ChildAtIndex(0);
|
||||
+ AXPlatformNodeBase* first_selected_node = root->GetSelectedItem(0);
|
||||
+ EXPECT_EQ(first_child, first_selected_node->GetNativeViewAccessible());
|
||||
+ EXPECT_EQ(nullptr, root->GetSelectedItem(1));
|
||||
+}
|
||||
+
|
||||
+TEST(AXPlatformNodeBaseTest, TestSelectedChildrenWithGroup) {
|
||||
+ AXPlatformNode::NotifyAddAXModeFlags(kAXModeComplete);
|
||||
+
|
||||
+ AXNodeData root_data;
|
||||
+ root_data.id = 1;
|
||||
+ root_data.role = ax::mojom::Role::kListBox;
|
||||
+ root_data.AddState(ax::mojom::State::kFocusable);
|
||||
+ root_data.AddState(ax::mojom::State::kMultiselectable);
|
||||
+ root_data.child_ids = {2, 3};
|
||||
+
|
||||
+ AXNodeData group_1_data;
|
||||
+ group_1_data.id = 2;
|
||||
+ group_1_data.role = ax::mojom::Role::kGroup;
|
||||
+ group_1_data.child_ids = {4, 5};
|
||||
+
|
||||
+ AXNodeData group_2_data;
|
||||
+ group_2_data.id = 3;
|
||||
+ group_2_data.role = ax::mojom::Role::kGroup;
|
||||
+ group_2_data.child_ids = {6, 7};
|
||||
+
|
||||
+ AXNodeData item_1_data;
|
||||
+ item_1_data.id = 4;
|
||||
+ item_1_data.role = ax::mojom::Role::kListBoxOption;
|
||||
+ item_1_data.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
|
||||
+
|
||||
+ AXNodeData item_2_data;
|
||||
+ item_2_data.id = 5;
|
||||
+ item_2_data.role = ax::mojom::Role::kListBoxOption;
|
||||
+
|
||||
+ AXNodeData item_3_data;
|
||||
+ item_3_data.id = 6;
|
||||
+ item_3_data.role = ax::mojom::Role::kListBoxOption;
|
||||
+
|
||||
+ AXNodeData item_4_data;
|
||||
+ item_4_data.id = 7;
|
||||
+ item_4_data.role = ax::mojom::Role::kListBoxOption;
|
||||
+ item_4_data.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
|
||||
+
|
||||
+ AXTreeUpdate update;
|
||||
+ update.root_id = 1;
|
||||
+ update.nodes = {root_data, group_1_data, group_2_data, item_1_data,
|
||||
+ item_2_data, item_3_data, item_4_data};
|
||||
+ AXTree tree(update);
|
||||
+
|
||||
+ auto* root = static_cast<AXPlatformNodeBase*>(
|
||||
+ TestAXNodeWrapper::GetOrCreate(&tree, tree.root())->ax_platform_node());
|
||||
+
|
||||
+ int num = root->GetSelectionCount();
|
||||
+ EXPECT_EQ(num, 2);
|
||||
+
|
||||
+ gfx::NativeViewAccessible first_group_child =
|
||||
+ static_cast<AXPlatformNodeBase*>(
|
||||
+ AXPlatformNode::FromNativeViewAccessible(root->ChildAtIndex(0)))
|
||||
+ ->ChildAtIndex(0);
|
||||
+ AXPlatformNodeBase* first_selected_node = root->GetSelectedItem(0);
|
||||
+ EXPECT_EQ(first_group_child, first_selected_node->GetNativeViewAccessible());
|
||||
+
|
||||
+ gfx::NativeViewAccessible second_group_child =
|
||||
+ static_cast<AXPlatformNodeBase*>(
|
||||
+ AXPlatformNode::FromNativeViewAccessible(root->ChildAtIndex(1)))
|
||||
+ ->ChildAtIndex(1);
|
||||
+ AXPlatformNodeBase* second_selected_node = root->GetSelectedItem(1);
|
||||
+ EXPECT_EQ(second_group_child,
|
||||
+ second_selected_node->GetNativeViewAccessible());
|
||||
+}
|
||||
+
|
||||
+TEST(AXPlatformNodeBaseTest, TestSelectedChildrenMixed) {
|
||||
+ AXPlatformNode::NotifyAddAXModeFlags(kAXModeComplete);
|
||||
+
|
||||
+ // Build the below tree which is mixed with listBoxOption and group.
|
||||
+ // id=1 listBox FOCUSABLE MULTISELECTABLE (0, 0)-(0, 0) child_ids=2,3,4,9
|
||||
+ // ++id=2 listBoxOption (0, 0)-(0, 0) selected=true
|
||||
+ // ++id=3 group (0, 0)-(0, 0) child_ids=5,6
|
||||
+ // ++++id=5 listBoxOption (0, 0)-(0, 0) selected=true
|
||||
+ // ++++id=6 listBoxOption (0, 0)-(0, 0)
|
||||
+ // ++id=4 group (0, 0)-(0, 0) child_ids=7,8
|
||||
+ // ++++id=7 listBoxOption (0, 0)-(0, 0)
|
||||
+ // ++++id=8 listBoxOption (0, 0)-(0, 0) selected=true
|
||||
+ // ++id=9 listBoxOption (0, 0)-(0, 0) selected=true
|
||||
+
|
||||
+ AXNodeData root_data;
|
||||
+ root_data.id = 1;
|
||||
+ root_data.role = ax::mojom::Role::kListBox;
|
||||
+ root_data.AddState(ax::mojom::State::kFocusable);
|
||||
+ root_data.AddState(ax::mojom::State::kMultiselectable);
|
||||
+ root_data.child_ids = {2, 3, 4, 9};
|
||||
+
|
||||
+ AXNodeData item_1_data;
|
||||
+ item_1_data.id = 2;
|
||||
+ item_1_data.role = ax::mojom::Role::kListBoxOption;
|
||||
+ item_1_data.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
|
||||
+
|
||||
+ AXNodeData group_1_data;
|
||||
+ group_1_data.id = 3;
|
||||
+ group_1_data.role = ax::mojom::Role::kGroup;
|
||||
+ group_1_data.child_ids = {5, 6};
|
||||
+
|
||||
+ AXNodeData item_2_data;
|
||||
+ item_2_data.id = 5;
|
||||
+ item_2_data.role = ax::mojom::Role::kListBoxOption;
|
||||
+ item_2_data.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
|
||||
+
|
||||
+ AXNodeData item_3_data;
|
||||
+ item_3_data.id = 6;
|
||||
+ item_3_data.role = ax::mojom::Role::kListBoxOption;
|
||||
+
|
||||
+ AXNodeData group_2_data;
|
||||
+ group_2_data.id = 4;
|
||||
+ group_2_data.role = ax::mojom::Role::kGroup;
|
||||
+ group_2_data.child_ids = {7, 8};
|
||||
+
|
||||
+ AXNodeData item_4_data;
|
||||
+ item_4_data.id = 7;
|
||||
+ item_4_data.role = ax::mojom::Role::kListBoxOption;
|
||||
+
|
||||
+ AXNodeData item_5_data;
|
||||
+ item_5_data.id = 8;
|
||||
+ item_5_data.role = ax::mojom::Role::kListBoxOption;
|
||||
+ item_5_data.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
|
||||
+
|
||||
+ AXNodeData item_6_data;
|
||||
+ item_6_data.id = 9;
|
||||
+ item_6_data.role = ax::mojom::Role::kListBoxOption;
|
||||
+ item_6_data.AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
|
||||
+
|
||||
+ AXTreeUpdate update;
|
||||
+ update.root_id = 1;
|
||||
+ update.nodes = {root_data, item_1_data, group_1_data,
|
||||
+ item_2_data, item_3_data, group_2_data,
|
||||
+ item_4_data, item_5_data, item_6_data};
|
||||
+ AXTree tree(update);
|
||||
+
|
||||
+ auto* root = static_cast<AXPlatformNodeBase*>(
|
||||
+ TestAXNodeWrapper::GetOrCreate(&tree, tree.root())->ax_platform_node());
|
||||
+
|
||||
+ int num = root->GetSelectionCount();
|
||||
+ EXPECT_EQ(num, 4);
|
||||
+
|
||||
+ gfx::NativeViewAccessible first_child = root->ChildAtIndex(0);
|
||||
+ AXPlatformNodeBase* first_selected_node = root->GetSelectedItem(0);
|
||||
+ EXPECT_EQ(first_child, first_selected_node->GetNativeViewAccessible());
|
||||
+
|
||||
+ gfx::NativeViewAccessible first_group_child =
|
||||
+ static_cast<AXPlatformNodeBase*>(
|
||||
+ AXPlatformNode::FromNativeViewAccessible(root->ChildAtIndex(1)))
|
||||
+ ->ChildAtIndex(0);
|
||||
+ AXPlatformNodeBase* second_selected_node = root->GetSelectedItem(1);
|
||||
+ EXPECT_EQ(first_group_child, second_selected_node->GetNativeViewAccessible());
|
||||
+
|
||||
+ gfx::NativeViewAccessible second_group_child =
|
||||
+ static_cast<AXPlatformNodeBase*>(
|
||||
+ AXPlatformNode::FromNativeViewAccessible(root->ChildAtIndex(2)))
|
||||
+ ->ChildAtIndex(1);
|
||||
+ AXPlatformNodeBase* third_selected_node = root->GetSelectedItem(2);
|
||||
+ EXPECT_EQ(second_group_child, third_selected_node->GetNativeViewAccessible());
|
||||
+
|
||||
+ gfx::NativeViewAccessible fourth_child = root->ChildAtIndex(3);
|
||||
+ AXPlatformNodeBase* fourth_selected_node = root->GetSelectedItem(3);
|
||||
+ EXPECT_EQ(fourth_child, fourth_selected_node->GetNativeViewAccessible());
|
||||
+}
|
||||
+
|
||||
} // namespace ui
|
||||
diff --git a/ui/accessibility/platform/ax_platform_node_unittest.cc b/ui/accessibility/platform/ax_platform_node_unittest.cc
|
||||
index c652b37ec7f3a345da4986463962fee9423f213b..480a723325393b55774bbe80b14934dbe1ce95df 100644
|
||||
--- a/ui/accessibility/platform/ax_platform_node_unittest.cc
|
||||
+++ b/ui/accessibility/platform/ax_platform_node_unittest.cc
|
||||
@@ -356,13 +356,13 @@ AXTreeUpdate AXPlatformNodeTest::BuildListBox(
|
||||
bool option_1_is_selected,
|
||||
bool option_2_is_selected,
|
||||
bool option_3_is_selected,
|
||||
- ax::mojom::State additional_state /* ax::mojom::State::kNone */) {
|
||||
+ const std::vector<ax::mojom::State>& additional_state) {
|
||||
AXNodeData listbox;
|
||||
listbox.id = 1;
|
||||
listbox.SetName("ListBox");
|
||||
listbox.role = ax::mojom::Role::kListBox;
|
||||
- if (additional_state != ax::mojom::State::kNone)
|
||||
- listbox.AddState(additional_state);
|
||||
+ for (auto state : additional_state)
|
||||
+ listbox.AddState(state);
|
||||
|
||||
AXNodeData option_1;
|
||||
option_1.id = 2;
|
||||
diff --git a/ui/accessibility/platform/ax_platform_node_unittest.h b/ui/accessibility/platform/ax_platform_node_unittest.h
|
||||
index 3207332eb8370edf850bac6d8eee72ff8f9fad85..d004a0585ebbdaa6944e05ba48be8936a775e3cd 100644
|
||||
--- a/ui/accessibility/platform/ax_platform_node_unittest.h
|
||||
+++ b/ui/accessibility/platform/ax_platform_node_unittest.h
|
||||
@@ -48,10 +48,11 @@ class AXPlatformNodeTest : public testing::Test, public TestAXTreeManager {
|
||||
AXTreeUpdate Build3X3Table();
|
||||
AXTreeUpdate BuildAriaColumnAndRowCountGrids();
|
||||
|
||||
- AXTreeUpdate BuildListBox(bool option_1_is_selected,
|
||||
- bool option_2_is_selected,
|
||||
- bool option_3_is_selected,
|
||||
- ax::mojom::State additional_state);
|
||||
+ AXTreeUpdate BuildListBox(
|
||||
+ bool option_1_is_selected,
|
||||
+ bool option_2_is_selected,
|
||||
+ bool option_3_is_selected,
|
||||
+ const std::vector<ax::mojom::State>& additional_state);
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
|
||||
index eadcb741d948798bab9269044170ede3474f237d..a61d4121d9eeb336e72dbb6a3e2bf884a9b4e799 100644
|
||||
--- a/ui/accessibility/platform/ax_platform_node_win.cc
|
||||
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
|
||||
@@ -2131,15 +2131,10 @@ IFACEMETHODIMP AXPlatformNodeWin::GetSelection(SAFEARRAY** result) {
|
||||
WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_SELECTION_GETSELECTION);
|
||||
UIA_VALIDATE_CALL_1_ARG(result);
|
||||
|
||||
- std::vector<AXPlatformNodeWin*> selected_children;
|
||||
- LONG child_count = GetDelegate()->GetChildCount();
|
||||
- for (LONG i = 0; i < child_count; ++i) {
|
||||
- auto* child = static_cast<AXPlatformNodeWin*>(
|
||||
- FromNativeViewAccessible(GetDelegate()->ChildAtIndex(i)));
|
||||
- DCHECK(child);
|
||||
- if (child->GetData().GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
|
||||
- selected_children.push_back(child);
|
||||
- }
|
||||
+ std::vector<AXPlatformNodeBase*> selected_children;
|
||||
+ int max_items = GetMaxSelectableItems();
|
||||
+ if (max_items)
|
||||
+ GetSelectedItems(max_items, &selected_children);
|
||||
|
||||
LONG selected_children_count = selected_children.size();
|
||||
*result = SafeArrayCreateVector(VT_UNKNOWN, 0, selected_children_count);
|
||||
@@ -2147,9 +2142,10 @@ IFACEMETHODIMP AXPlatformNodeWin::GetSelection(SAFEARRAY** result) {
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
for (LONG i = 0; i < selected_children_count; ++i) {
|
||||
+ AXPlatformNodeWin* children =
|
||||
+ static_cast<AXPlatformNodeWin*>(selected_children[i]);
|
||||
HRESULT hr = SafeArrayPutElement(
|
||||
- *result, &i,
|
||||
- static_cast<IRawElementProviderSimple*>(selected_children[i]));
|
||||
+ *result, &i, static_cast<IRawElementProviderSimple*>(children));
|
||||
if (FAILED(hr)) {
|
||||
SafeArrayDestroy(*result);
|
||||
*result = nullptr;
|
||||
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
|
||||
index 4a1df770606ac88bb44121b58f67198258c8adf2..2092d5c263dafa452c4977d53678ad81aa6575e1 100644
|
||||
--- a/ui/accessibility/platform/ax_platform_node_win_unittest.cc
|
||||
+++ b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
|
||||
@@ -4655,8 +4655,7 @@ TEST_F(AXPlatformNodeWinTest, TestUIANavigate) {
|
||||
TEST_F(AXPlatformNodeWinTest, TestISelectionProviderCanSelectMultipleDefault) {
|
||||
Init(BuildListBox(/*option_1_is_selected*/ false,
|
||||
/*option_2_is_selected*/ false,
|
||||
- /*option_3_is_selected*/ false,
|
||||
- /*additional_state*/ ax::mojom::State::kNone));
|
||||
+ /*option_3_is_selected*/ false, {}));
|
||||
|
||||
ComPtr<ISelectionProvider> selection_provider(
|
||||
QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
|
||||
@@ -4668,10 +4667,12 @@ TEST_F(AXPlatformNodeWinTest, TestISelectionProviderCanSelectMultipleDefault) {
|
||||
}
|
||||
|
||||
TEST_F(AXPlatformNodeWinTest, TestISelectionProviderCanSelectMultipleTrue) {
|
||||
+ const std::vector<ax::mojom::State> state = {
|
||||
+ ax::mojom::State::kMultiselectable, ax::mojom::State::kFocusable};
|
||||
Init(BuildListBox(/*option_1_is_selected*/ false,
|
||||
/*option_2_is_selected*/ false,
|
||||
/*option_3_is_selected*/ false,
|
||||
- /*additional_state*/ ax::mojom::State::kMultiselectable));
|
||||
+ /*additional_state*/ state));
|
||||
|
||||
ComPtr<ISelectionProvider> selection_provider(
|
||||
QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
|
||||
@@ -4687,7 +4688,7 @@ TEST_F(AXPlatformNodeWinTest,
|
||||
Init(BuildListBox(/*option_1_is_selected*/ false,
|
||||
/*option_2_is_selected*/ false,
|
||||
/*option_3_is_selected*/ false,
|
||||
- /*additional_state*/ ax::mojom::State::kNone));
|
||||
+ /*additional_state*/ {}));
|
||||
|
||||
ComPtr<ISelectionProvider> selection_provider(
|
||||
QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
|
||||
@@ -4702,7 +4703,7 @@ TEST_F(AXPlatformNodeWinTest, TestISelectionProviderIsSelectionRequiredTrue) {
|
||||
Init(BuildListBox(/*option_1_is_selected*/ false,
|
||||
/*option_2_is_selected*/ false,
|
||||
/*option_3_is_selected*/ false,
|
||||
- /*additional_state*/ ax::mojom::State::kRequired));
|
||||
+ /*additional_state*/ {ax::mojom::State::kRequired}));
|
||||
|
||||
ComPtr<ISelectionProvider> selection_provider(
|
||||
QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
|
||||
@@ -4717,7 +4718,7 @@ TEST_F(AXPlatformNodeWinTest, TestISelectionProviderGetSelectionNoneSelected) {
|
||||
Init(BuildListBox(/*option_1_is_selected*/ false,
|
||||
/*option_2_is_selected*/ false,
|
||||
/*option_3_is_selected*/ false,
|
||||
- /*additional_state*/ ax::mojom::State::kNone));
|
||||
+ /*additional_state*/ {ax::mojom::State::kFocusable}));
|
||||
|
||||
ComPtr<ISelectionProvider> selection_provider(
|
||||
QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
|
||||
@@ -4743,7 +4744,7 @@ TEST_F(AXPlatformNodeWinTest,
|
||||
Init(BuildListBox(/*option_1_is_selected*/ false,
|
||||
/*option_2_is_selected*/ true,
|
||||
/*option_3_is_selected*/ false,
|
||||
- /*additional_state*/ ax::mojom::State::kNone));
|
||||
+ /*additional_state*/ {ax::mojom::State::kFocusable}));
|
||||
|
||||
ComPtr<ISelectionProvider> selection_provider(
|
||||
QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
|
||||
@@ -4775,10 +4776,12 @@ TEST_F(AXPlatformNodeWinTest,
|
||||
|
||||
TEST_F(AXPlatformNodeWinTest,
|
||||
TestISelectionProviderGetSelectionMultipleItemsSelected) {
|
||||
+ const std::vector<ax::mojom::State> state = {
|
||||
+ ax::mojom::State::kMultiselectable, ax::mojom::State::kFocusable};
|
||||
Init(BuildListBox(/*option_1_is_selected*/ true,
|
||||
/*option_2_is_selected*/ true,
|
||||
/*option_3_is_selected*/ true,
|
||||
- /*additional_state*/ ax::mojom::State::kNone));
|
||||
+ /*additional_state*/ state));
|
||||
|
||||
ComPtr<ISelectionProvider> selection_provider(
|
||||
QueryInterfaceFromNode<ISelectionProvider>(GetRootAsAXNode()));
|
||||
@@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jeremy Apthorp <nornagon@nornagon.net>
|
||||
Date: Fri, 25 Oct 2019 11:23:03 -0700
|
||||
Subject: add WebMessagePortConverter::EntangleAndInjectMessagePortChannel
|
||||
|
||||
This adds a method to the public Blink API that would otherwise require
|
||||
accessing Blink internals. Its inverse, which already exists, is used in
|
||||
Android WebView.
|
||||
|
||||
diff --git a/third_party/blink/public/web/web_message_port_converter.h b/third_party/blink/public/web/web_message_port_converter.h
|
||||
index ad603aa7c557bfd4f571a541d70e2edf9ae757d9..d4b0bf8f5e8f3af9328b0099b65d9963414dfcc1 100644
|
||||
--- a/third_party/blink/public/web/web_message_port_converter.h
|
||||
+++ b/third_party/blink/public/web/web_message_port_converter.h
|
||||
@@ -13,6 +13,7 @@ class Isolate;
|
||||
template <class T>
|
||||
class Local;
|
||||
class Value;
|
||||
+class Context;
|
||||
} // namespace v8
|
||||
|
||||
namespace blink {
|
||||
@@ -25,6 +26,9 @@ class WebMessagePortConverter {
|
||||
// neutered, it will return nullopt.
|
||||
BLINK_EXPORT static base::Optional<MessagePortChannel>
|
||||
DisentangleAndExtractMessagePortChannel(v8::Isolate*, v8::Local<v8::Value>);
|
||||
+
|
||||
+ BLINK_EXPORT static v8::Local<v8::Value>
|
||||
+ EntangleAndInjectMessagePortChannel(v8::Local<v8::Context>, MessagePortChannel);
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/exported/web_message_port_converter.cc b/third_party/blink/renderer/core/exported/web_message_port_converter.cc
|
||||
index 333760d667f6b98b3e7674bf9082f999743dadfa..fc2f517de1951380482fbfa92c038041e15d9c3e 100644
|
||||
--- a/third_party/blink/renderer/core/exported/web_message_port_converter.cc
|
||||
+++ b/third_party/blink/renderer/core/exported/web_message_port_converter.cc
|
||||
@@ -21,4 +21,15 @@ WebMessagePortConverter::DisentangleAndExtractMessagePortChannel(
|
||||
return port->Disentangle();
|
||||
}
|
||||
|
||||
+v8::Local<v8::Value>
|
||||
+WebMessagePortConverter::EntangleAndInjectMessagePortChannel(
|
||||
+ v8::Local<v8::Context> context,
|
||||
+ MessagePortChannel port_channel) {
|
||||
+ auto* execution_context = ToExecutionContext(context);
|
||||
+ CHECK(execution_context);
|
||||
+ auto* port = MakeGarbageCollected<MessagePort>(*execution_context);
|
||||
+ port->Entangle(std::move(port_channel));
|
||||
+ return ToV8(port, context->Global(), context->GetIsolate());
|
||||
+}
|
||||
+
|
||||
} // namespace blink
|
||||
@@ -0,0 +1,142 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Siye Liu <siliu@microsoft.com>
|
||||
Date: Mon, 8 Jun 2020 21:19:00 +0000
|
||||
Subject: Allow IME to insert zero-length composition string.
|
||||
|
||||
Some IMEs and Windows OS dictation will either insert zero-length text
|
||||
or delete existing composition text to commit active composition.
|
||||
Therefore, we should allow IMEs to cancel composition by committing zero
|
||||
length text.
|
||||
|
||||
Bug: 1091069
|
||||
Change-Id: I99cb213dc2ba1965abfa88ccf6858b89bd7e82df
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2233234
|
||||
Commit-Queue: Siye Liu <siliu@microsoft.com>
|
||||
Reviewed-by: Yohei Yukawa <yukawa@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#776198}
|
||||
|
||||
diff --git a/ui/base/ime/win/tsf_text_store.cc b/ui/base/ime/win/tsf_text_store.cc
|
||||
index 2a8cde4995fc41305847fd995654e3a012f68e1d..31174ba0eb0559aa461cfba1689d9ef627914e71 100644
|
||||
--- a/ui/base/ime/win/tsf_text_store.cc
|
||||
+++ b/ui/base/ime/win/tsf_text_store.cc
|
||||
@@ -647,9 +647,7 @@ HRESULT TSFTextStore::RequestLock(DWORD lock_flags, HRESULT* result) {
|
||||
// 3. User commits current composition text.
|
||||
if (((new_composition_start > last_composition_start &&
|
||||
text_input_client_->HasCompositionText()) ||
|
||||
- (wparam_keydown_fired_ == 0 && !has_composition_range_ &&
|
||||
- !text_input_client_->HasCompositionText()) ||
|
||||
- (wparam_keydown_fired_ != 0 && !has_composition_range_)) &&
|
||||
+ !has_composition_range_) &&
|
||||
text_input_client_) {
|
||||
CommitTextAndEndCompositionIfAny(last_composition_start,
|
||||
new_composition_start);
|
||||
@@ -1355,8 +1353,11 @@ void TSFTextStore::CommitTextAndEndCompositionIfAny(size_t old_size,
|
||||
: new_committed_string_size);
|
||||
// TODO(crbug.com/978678): Unify the behavior of
|
||||
// |TextInputClient::InsertText(text)| for the empty text.
|
||||
- if (!new_committed_string.empty())
|
||||
+ if (!new_committed_string.empty()) {
|
||||
text_input_client_->InsertText(new_committed_string);
|
||||
+ } else {
|
||||
+ text_input_client_->ClearCompositionText();
|
||||
+ }
|
||||
// Notify accessibility about this committed composition
|
||||
text_input_client_->SetActiveCompositionForAccessibility(
|
||||
replace_text_range_, new_committed_string,
|
||||
diff --git a/ui/base/ime/win/tsf_text_store_unittest.cc b/ui/base/ime/win/tsf_text_store_unittest.cc
|
||||
index 081809d75a1fbbedbcbc722302d4d915eabc46d4..4e81d7c1012f86712f1bba2bfe4037ed1ef79772 100644
|
||||
--- a/ui/base/ime/win/tsf_text_store_unittest.cc
|
||||
+++ b/ui/base/ime/win/tsf_text_store_unittest.cc
|
||||
@@ -3394,5 +3394,92 @@ TEST_F(TSFTextStoreTest, RegressionTest7) {
|
||||
EXPECT_EQ(S_OK, result);
|
||||
}
|
||||
|
||||
+// regression tests for crbug.com/1091069.
|
||||
+// We should allow inserting empty compositon string to cancel composition.
|
||||
+class RegressionTest8Callback : public TSFTextStoreTestCallback {
|
||||
+ public:
|
||||
+ explicit RegressionTest8Callback(TSFTextStore* text_store)
|
||||
+ : TSFTextStoreTestCallback(text_store) {}
|
||||
+
|
||||
+ HRESULT LockGranted1(DWORD flags) {
|
||||
+ SetTextTest(0, 0, L"bbbb", S_OK);
|
||||
+ SetSelectionTest(0, 4, S_OK);
|
||||
+
|
||||
+ text_spans()->clear();
|
||||
+ ImeTextSpan text_span_1;
|
||||
+ text_span_1.start_offset = 0;
|
||||
+ text_span_1.end_offset = 4;
|
||||
+ text_span_1.underline_color = SK_ColorBLACK;
|
||||
+ text_span_1.thickness = ImeTextSpan::Thickness::kThin;
|
||||
+ text_span_1.background_color = SK_ColorTRANSPARENT;
|
||||
+ text_spans()->push_back(text_span_1);
|
||||
+
|
||||
+ *edit_flag() = true;
|
||||
+ *composition_start() = 0;
|
||||
+ composition_range()->set_start(0);
|
||||
+ composition_range()->set_end(4);
|
||||
+ *has_composition_range() = true;
|
||||
+
|
||||
+ text_store_->OnKeyTraceDown(65u, 1966081u);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+
|
||||
+ void SetCompositionText1(const ui::CompositionText& composition) {
|
||||
+ EXPECT_EQ(L"bbbb", composition.text);
|
||||
+ EXPECT_EQ(0u, composition.selection.start());
|
||||
+ EXPECT_EQ(4u, composition.selection.end());
|
||||
+ ASSERT_EQ(1u, composition.ime_text_spans.size());
|
||||
+ EXPECT_EQ(0u, composition.ime_text_spans[0].start_offset);
|
||||
+ EXPECT_EQ(4u, composition.ime_text_spans[0].end_offset);
|
||||
+ SetHasCompositionText(true);
|
||||
+ }
|
||||
+
|
||||
+ HRESULT LockGranted2(DWORD flags) {
|
||||
+ GetTextTest(0, -1, L"bbbb", 4);
|
||||
+ SetTextTest(0, 4, L"", S_OK);
|
||||
+
|
||||
+ text_spans()->clear();
|
||||
+ *edit_flag() = true;
|
||||
+ *composition_start() = 0;
|
||||
+ composition_range()->set_start(0);
|
||||
+ composition_range()->set_end(0);
|
||||
+
|
||||
+ *has_composition_range() = false;
|
||||
+ text_store_->OnKeyTraceUp(65u, 1966081u);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+
|
||||
+ void ClearCompositionText2() { EXPECT_EQ(false, *has_composition_range()); }
|
||||
+
|
||||
+ private:
|
||||
+ DISALLOW_COPY_AND_ASSIGN(RegressionTest8Callback);
|
||||
+};
|
||||
+
|
||||
+TEST_F(TSFTextStoreTest, RegressionTest8) {
|
||||
+ RegressionTest8Callback callback(text_store_.get());
|
||||
+ EXPECT_CALL(text_input_client_, SetCompositionText(_))
|
||||
+ .WillOnce(
|
||||
+ Invoke(&callback, &RegressionTest8Callback::SetCompositionText1));
|
||||
+
|
||||
+ EXPECT_CALL(text_input_client_, ClearCompositionText())
|
||||
+ .WillOnce(
|
||||
+ Invoke(&callback, &RegressionTest8Callback::ClearCompositionText2));
|
||||
+
|
||||
+ EXPECT_CALL(*sink_, OnLockGranted(_))
|
||||
+ .WillOnce(Invoke(&callback, &RegressionTest8Callback::LockGranted1))
|
||||
+ .WillOnce(Invoke(&callback, &RegressionTest8Callback::LockGranted2));
|
||||
+
|
||||
+ ON_CALL(text_input_client_, HasCompositionText())
|
||||
+ .WillByDefault(
|
||||
+ Invoke(&callback, &TSFTextStoreTestCallback::HasCompositionText));
|
||||
+
|
||||
+ HRESULT result = kInvalidResult;
|
||||
+ EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result));
|
||||
+ EXPECT_EQ(S_OK, result);
|
||||
+ result = kInvalidResult;
|
||||
+ EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result));
|
||||
+ EXPECT_EQ(S_OK, result);
|
||||
+}
|
||||
+
|
||||
} // namespace
|
||||
} // namespace ui
|
||||
83
patches/chromium/backport_1016278.patch
Normal file
83
patches/chromium/backport_1016278.patch
Normal file
@@ -0,0 +1,83 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: check whether Fetch domain is enabled before handling commands
|
||||
|
||||
[1016278] [Low] [CVE-2020-6530]: Security: EXC_BAD_ACCESS / KERN_INVALID_ADDRESS when exec chrome.debugger.sendCommand
|
||||
Backport https://chromium.googlesource.com/chromium/src/+/d4938b0019bc23f96e2c7d3659c0a4102973d8c2
|
||||
|
||||
diff --git a/content/browser/devtools/protocol/fetch_handler.cc b/content/browser/devtools/protocol/fetch_handler.cc
|
||||
index a5af86b99b46bb1cc6e6cf2011bc90d82f1ff7f5..433f22ac30ffcb1d94ad2d9aeca44b1f1b7a5aba 100644
|
||||
--- a/content/browser/devtools/protocol/fetch_handler.cc
|
||||
+++ b/content/browser/devtools/protocol/fetch_handler.cc
|
||||
@@ -315,6 +315,10 @@ void FetchHandler::ContinueWithAuth(
|
||||
void FetchHandler::GetResponseBody(
|
||||
const String& requestId,
|
||||
std::unique_ptr<GetResponseBodyCallback> callback) {
|
||||
+ if (!interceptor_) {
|
||||
+ callback->sendFailure(Response::ServerError("Fetch domain is not enabled"));
|
||||
+ return;
|
||||
+ }
|
||||
auto weapped_callback = std::make_unique<CallbackWrapper<
|
||||
GetResponseBodyCallback,
|
||||
DevToolsURLLoaderInterceptor::GetResponseBodyForInterceptionCallback,
|
||||
@@ -325,6 +329,10 @@ void FetchHandler::GetResponseBody(
|
||||
void FetchHandler::TakeResponseBodyAsStream(
|
||||
const String& requestId,
|
||||
std::unique_ptr<TakeResponseBodyAsStreamCallback> callback) {
|
||||
+ if (!interceptor_) {
|
||||
+ callback->sendFailure(Response::ServerError("Fetch domain is not enabled"));
|
||||
+ return;
|
||||
+ }
|
||||
interceptor_->TakeResponseBodyPipe(
|
||||
requestId,
|
||||
base::BindOnce(&FetchHandler::OnResponseBodyPipeTaken,
|
||||
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/calls-while-not-enabled-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/calls-while-not-enabled-expected.txt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..630e4db357dd43d0714c231983672368bc8f162d
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/calls-while-not-enabled-expected.txt
|
||||
@@ -0,0 +1,8 @@
|
||||
+Tests that calls to methods of Fetch domain return proper error if the domain has not been enabled
|
||||
+fulfillRequest: code: -32000 message: Fetch domain is not enabled
|
||||
+failRequest: code: -32000 message: Fetch domain is not enabled
|
||||
+continueRequest: code: -32000 message: Fetch domain is not enabled
|
||||
+continueWithAuth: code: -32000 message: Fetch domain is not enabled
|
||||
+getResponseBody: code: -32000 message: Fetch domain is not enabled
|
||||
+takeResponseBodyAsStream: code: -32000 message: Fetch domain is not enabled
|
||||
+
|
||||
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/calls-while-not-enabled.js b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/calls-while-not-enabled.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..161867adc2ac2fb6e9abb93856eba3e097d78637
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/calls-while-not-enabled.js
|
||||
@@ -0,0 +1,29 @@
|
||||
+(async function(testRunner) {
|
||||
+ var {page, session, dp} = await testRunner.startBlank(
|
||||
+ `Tests that calls to methods of Fetch domain return proper error if the domain has not been enabled`);
|
||||
+
|
||||
+ const methods = [
|
||||
+ "fulfillRequest",
|
||||
+ "failRequest",
|
||||
+ "continueRequest",
|
||||
+ "continueWithAuth",
|
||||
+ "getResponseBody",
|
||||
+ "takeResponseBodyAsStream",
|
||||
+ ];
|
||||
+ const params = {
|
||||
+ requestId: "does not matter",
|
||||
+ responseCode: 404,
|
||||
+ errorReason: "not found",
|
||||
+ authChallengeResponse: {response: 'kensentme'}
|
||||
+ };
|
||||
+ for (const methodName of methods) {
|
||||
+ const method = dp.Fetch[methodName];
|
||||
+ const response = await method.call(dp.Fetch, params);
|
||||
+ if (!response.error)
|
||||
+ testRunner.log(`${methodName}: FAIL: not an error response`);
|
||||
+ else
|
||||
+ testRunner.log(`${methodName}: code: ${response.error.code} message: ${response.error.message}`);
|
||||
+ }
|
||||
+
|
||||
+ testRunner.completeTest();
|
||||
+})
|
||||
273
patches/chromium/backport_1042986.patch
Normal file
273
patches/chromium/backport_1042986.patch
Normal file
@@ -0,0 +1,273 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: text fragment for user activation
|
||||
|
||||
[1042986] [Low] [CVE-2020-6531]: iframe in victim page can detect Scroll To Text Fragment activation
|
||||
Backport https://chromium.googlesource.com/chromium/src/+/6ba752a6236a1adfff4b552bf141abd20f81fa4c
|
||||
|
||||
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
|
||||
index 5e47c91a5f5af59dfec21d4f1930d74cb05a55d9..f53b4c900f0e7786dcdb0824a34bf3720b301538 100644
|
||||
--- a/content/browser/frame_host/navigation_request.h
|
||||
+++ b/content/browser/frame_host/navigation_request.h
|
||||
@@ -901,7 +901,9 @@ class CONTENT_EXPORT NavigationRequest
|
||||
// be set in CreatedNavigationRequest.
|
||||
// Note: |browser_initiated_| and |common_params_| may be mutated by
|
||||
// ContentBrowserClient::OverrideNavigationParams at StartNavigation time
|
||||
- // (i.e. before we actually kick off the navigation).
|
||||
+ // (i.e. before we actually kick off the navigation). |browser_initiated|
|
||||
+ // will always be true for history navigations, even if they began in the
|
||||
+ // renderer using the history API.
|
||||
mojom::CommonNavigationParamsPtr common_params_;
|
||||
mojom::BeginNavigationParamsPtr begin_params_;
|
||||
mojom::CommitNavigationParamsPtr commit_params_;
|
||||
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc
|
||||
index 0a8a18d178ded19600c33ca086d1c79fe30fa717..daffcb50bd9588e7b03d12cd245b6f8a3e9b065d 100644
|
||||
--- a/content/browser/navigation_browsertest.cc
|
||||
+++ b/content/browser/navigation_browsertest.cc
|
||||
@@ -2023,7 +2023,8 @@ IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest, EnabledOnUserNavigation) {
|
||||
WaitForPageLoad(main_contents);
|
||||
frame_observer.WaitForScrollOffsetAtTop(
|
||||
/*expected_scroll_offset_at_top=*/false);
|
||||
- EXPECT_FALSE(main_contents->GetMainFrame()->GetView()->IsScrollOffsetAtTop());
|
||||
+ RunUntilInputProcessed(GetWidgetHost());
|
||||
+ EXPECT_EQ(true, EvalJs(main_contents, "did_scroll;"));
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
@@ -2039,7 +2040,8 @@ IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
WaitForPageLoad(main_contents);
|
||||
frame_observer.WaitForScrollOffsetAtTop(
|
||||
/*expected_scroll_offset_at_top=*/false);
|
||||
- EXPECT_FALSE(main_contents->GetMainFrame()->GetView()->IsScrollOffsetAtTop());
|
||||
+ RunUntilInputProcessed(GetWidgetHost());
|
||||
+ EXPECT_EQ(true, EvalJs(main_contents, "did_scroll;"));
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
@@ -2064,7 +2066,8 @@ IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
WaitForPageLoad(main_contents);
|
||||
frame_observer.WaitForScrollOffsetAtTop(
|
||||
/*expected_scroll_offset_at_top=*/false);
|
||||
- EXPECT_FALSE(main_contents->GetMainFrame()->GetView()->IsScrollOffsetAtTop());
|
||||
+ RunUntilInputProcessed(GetWidgetHost());
|
||||
+ EXPECT_EQ(true, EvalJs(main_contents, "did_scroll;"));
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
@@ -2091,7 +2094,7 @@ IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
|
||||
run_loop.Run();
|
||||
RunUntilInputProcessed(GetWidgetHost());
|
||||
- EXPECT_TRUE(main_contents->GetMainFrame()->GetView()->IsScrollOffsetAtTop());
|
||||
+ EXPECT_EQ(false, EvalJs(main_contents, "did_scroll;"));
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
@@ -2127,7 +2130,13 @@ IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
|
||||
run_loop.Run();
|
||||
RunUntilInputProcessed(GetWidgetHost());
|
||||
- EXPECT_TRUE(main_contents->GetMainFrame()->GetView()->IsScrollOffsetAtTop());
|
||||
+
|
||||
+ // Note: we use a scroll handler in the page to check whether any scrolls
|
||||
+ // happened at all, rather than checking the current scroll offset. This is
|
||||
+ // to ensure that if the offset is reset back to the top for other reasons
|
||||
+ // (e.g. history restoration) we still fail this test. See
|
||||
+ // https://crbug.com/1042986 for why this matters.
|
||||
+ EXPECT_EQ(false, EvalJs(main_contents, "did_scroll;"));
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
@@ -2142,11 +2151,13 @@ IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
|
||||
WaitForPageLoad(main_contents);
|
||||
frame_observer.WaitForScrollOffsetAtTop(false);
|
||||
- EXPECT_FALSE(main_contents->GetMainFrame()->GetView()->IsScrollOffsetAtTop());
|
||||
|
||||
- // Scroll the page back to top.
|
||||
+ // Scroll the page back to top. Make sure we reset the |did_scroll| variable
|
||||
+ // we'll use below to ensure the same-document navigation invokes the text
|
||||
+ // fragment.
|
||||
EXPECT_TRUE(ExecuteScript(main_contents, "window.scrollTo(0, 0)"));
|
||||
frame_observer.WaitForScrollOffsetAtTop(true);
|
||||
+ EXPECT_TRUE(ExecJs(main_contents, "did_scroll = false;"));
|
||||
|
||||
// Perform a same-document browser initiated navigation
|
||||
GURL same_doc_url(embedded_test_server()->GetURL(
|
||||
@@ -2156,7 +2167,8 @@ IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
WaitForPageLoad(main_contents);
|
||||
frame_observer.WaitForScrollOffsetAtTop(
|
||||
/*expected_scroll_offset_at_top=*/false);
|
||||
- EXPECT_FALSE(main_contents->GetMainFrame()->GetView()->IsScrollOffsetAtTop());
|
||||
+ RunUntilInputProcessed(GetWidgetHost());
|
||||
+ EXPECT_EQ(true, EvalJs(main_contents, "did_scroll;"));
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
@@ -2184,7 +2196,7 @@ IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
|
||||
run_loop.Run();
|
||||
RunUntilInputProcessed(GetWidgetHost());
|
||||
- EXPECT_TRUE(main_contents->GetMainFrame()->GetView()->IsScrollOffsetAtTop());
|
||||
+ EXPECT_EQ(false, EvalJs(main_contents, "did_scroll;"));
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest, EnabledByDocumentPolicy) {
|
||||
@@ -2211,6 +2223,12 @@ IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest, EnabledByDocumentPolicy) {
|
||||
"Content-Type: text/html; charset=utf-8\r\n"
|
||||
"Document-Policy: no-force-load-at-top\r\n"
|
||||
"\r\n"
|
||||
+ "<script>"
|
||||
+ " let did_scroll = false;"
|
||||
+ " window.addEventListener('scroll', () => {"
|
||||
+ " did_scroll = true;"
|
||||
+ " });"
|
||||
+ "</script>"
|
||||
"<p style='position: absolute; top: 10000px;'>Some text</p>");
|
||||
response.Done();
|
||||
|
||||
@@ -2221,7 +2239,8 @@ IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest, EnabledByDocumentPolicy) {
|
||||
WaitForPageLoad(main_contents);
|
||||
frame_observer.WaitForScrollOffsetAtTop(
|
||||
/*expected_scroll_offset_at_top=*/false);
|
||||
- EXPECT_FALSE(main_contents->GetMainFrame()->GetView()->IsScrollOffsetAtTop());
|
||||
+ RunUntilInputProcessed(GetWidgetHost());
|
||||
+ EXPECT_EQ(true, EvalJs(main_contents, "did_scroll;"));
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
@@ -2248,6 +2267,12 @@ IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
"Content-Type: text/html; charset=utf-8\r\n"
|
||||
"Document-Policy: force-load-at-top\r\n"
|
||||
"\r\n"
|
||||
+ "<script>"
|
||||
+ " let did_scroll = false;"
|
||||
+ " window.addEventListener('scroll', () => {"
|
||||
+ " did_scroll = true;"
|
||||
+ " });"
|
||||
+ "</script>"
|
||||
"<p style='position: absolute; top: 10000px;'>Some text</p>");
|
||||
response.Done();
|
||||
|
||||
@@ -2262,7 +2287,7 @@ IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
|
||||
FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
|
||||
run_loop.Run();
|
||||
RunUntilInputProcessed(GetWidgetHost());
|
||||
- EXPECT_TRUE(main_contents->GetMainFrame()->GetView()->IsScrollOffsetAtTop());
|
||||
+ EXPECT_EQ(false, EvalJs(main_contents, "did_scroll;"));
|
||||
}
|
||||
|
||||
// Regression test for https://crbug.com/996044
|
||||
diff --git a/content/test/data/scrollable_page_with_content.html b/content/test/data/scrollable_page_with_content.html
|
||||
index c37d095d22231d12faa19985e8e98b3f9368fab1..1ef150d3a4289caef3a883c92feb79216f77f457 100644
|
||||
--- a/content/test/data/scrollable_page_with_content.html
|
||||
+++ b/content/test/data/scrollable_page_with_content.html
|
||||
@@ -1,6 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0">
|
||||
+ <script>
|
||||
+ let did_scroll = false;
|
||||
+ window.addEventListener('scroll', () => {
|
||||
+ did_scroll = true;
|
||||
+ });
|
||||
+ </script>
|
||||
<style>
|
||||
p {
|
||||
position: absolute;
|
||||
diff --git a/content/test/data/target_text_link.html b/content/test/data/target_text_link.html
|
||||
index 00f40bf042aed3476f07a9cc0575159c52cba9f2..ade7e42029f40b213c9110dd88ac270edb8d26f3 100644
|
||||
--- a/content/test/data/target_text_link.html
|
||||
+++ b/content/test/data/target_text_link.html
|
||||
@@ -5,4 +5,4 @@
|
||||
<body>
|
||||
<a id="link" href="/scrollable_page_with_content.html#:~:text=text">link</a>
|
||||
</body>
|
||||
-</html>>
|
||||
+</html>
|
||||
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h
|
||||
index 31fc5754a02318ab5eb7b239cea1530baf80ecba..cbf0e87fd81e48f77dac052a7f5992cf0dbaa2e0 100644
|
||||
--- a/third_party/blink/renderer/core/loader/document_loader.h
|
||||
+++ b/third_party/blink/renderer/core/loader/document_loader.h
|
||||
@@ -294,6 +294,9 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
|
||||
|
||||
bool HadTransientActivation() const { return had_transient_activation_; }
|
||||
|
||||
+ // Whether the navigation originated from the browser process. Note: history
|
||||
+ // navigation is always considered to be browser initiated, even if the
|
||||
+ // navigation was started using the history API in the renderer.
|
||||
bool IsBrowserInitiated() const { return is_browser_initiated_; }
|
||||
|
||||
bool IsSameOriginNavigation() const { return is_same_origin_navigation_; }
|
||||
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
|
||||
index ebdb5b14f8a36ee44f6f80e57c3221ac79f566e7..cc7cde84dcfd8543e7cc0bb5048c5225c13703e9 100644
|
||||
--- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
|
||||
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc
|
||||
@@ -61,12 +61,25 @@ bool ParseTextDirective(const String& fragment,
|
||||
bool CheckSecurityRestrictions(LocalFrame& frame,
|
||||
bool same_document_navigation) {
|
||||
// This algorithm checks the security restrictions detailed in
|
||||
- // https://wicg.github.io/ScrollToTextFragment/#should-allow-text-fragment
|
||||
-
|
||||
- // We only allow text fragment anchors for user or browser initiated
|
||||
- // navigations, i.e. no script navigations.
|
||||
- if (!(frame.Loader().GetDocumentLoader()->HadTransientActivation() ||
|
||||
- frame.Loader().GetDocumentLoader()->IsBrowserInitiated())) {
|
||||
+ // https://wicg.github.io/ScrollToTextFragment/#should-allow-a-text-fragment
|
||||
+ // TODO(bokan): These are really only relevant for observable actions like
|
||||
+ // scrolling. We should consider allowing highlighting regardless of these
|
||||
+ // conditions. See the TODO in the relevant spec section:
|
||||
+ // https://wicg.github.io/ScrollToTextFragment/#restricting-the-text-fragment
|
||||
+
|
||||
+ // History navigation is special because it's considered to be browser
|
||||
+ // initiated even if the navigation originated via use of the history API
|
||||
+ // within the renderer. We avoid creating a text fragment for history
|
||||
+ // navigations since history scroll restoration should take precedence but
|
||||
+ // it'd be bad if we ever got here for a history navigation since the check
|
||||
+ // below would pass even if the user took no action.
|
||||
+ SECURITY_CHECK(frame.Loader().GetDocumentLoader()->GetNavigationType() !=
|
||||
+ kWebNavigationTypeBackForward);
|
||||
+
|
||||
+ // We only allow text fragment anchors for user navigations, e.g. link
|
||||
+ // clicks, omnibox navigations, no script navigations.
|
||||
+ if (!frame.Loader().GetDocumentLoader()->HadTransientActivation() &&
|
||||
+ !frame.Loader().GetDocumentLoader()->IsBrowserInitiated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -104,6 +117,17 @@ TextFragmentAnchor* TextFragmentAnchor::TryCreateFragmentDirective(
|
||||
if (!frame.GetDocument()->GetFragmentDirective())
|
||||
return nullptr;
|
||||
|
||||
+ // Avoid invoking the text fragment for history or reload navigations as
|
||||
+ // they'll be clobbered by scroll restoration; this prevents a transient
|
||||
+ // scroll as well as user gesture issues; see https://crbug.com/1042986 for
|
||||
+ // details.
|
||||
+ auto navigation_type =
|
||||
+ frame.Loader().GetDocumentLoader()->GetNavigationType();
|
||||
+ if (navigation_type == kWebNavigationTypeBackForward ||
|
||||
+ navigation_type == kWebNavigationTypeReload) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
if (!CheckSecurityRestrictions(frame, same_document_navigation))
|
||||
return nullptr;
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
|
||||
index c8c87c95319a63d93a90123a4150cb3a4b2f95bf..258b9ac343a8fbcec635ddb6103cc485d540b50e 100644
|
||||
--- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
|
||||
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
|
||||
@@ -1611,7 +1611,11 @@ TEST_F(TextFragmentAnchorTest, TextDirectiveInSvg) {
|
||||
}
|
||||
|
||||
// Ensure we restore the text highlight on page reload
|
||||
-TEST_F(TextFragmentAnchorTest, HighlightOnReload) {
|
||||
+// TODO(bokan): This test is disabled as this functionality was suppressed in
|
||||
+// https://crrev.com/c/2135407; it would be better addressed by providing a
|
||||
+// highlight-only function. See the TODO in
|
||||
+// https://wicg.github.io/ScrollToTextFragment/#restricting-the-text-fragment
|
||||
+TEST_F(TextFragmentAnchorTest, DISABLED_HighlightOnReload) {
|
||||
SimRequest request("https://example.com/test.html#:~:text=test", "text/html");
|
||||
LoadURL("https://example.com/test.html#:~:text=test");
|
||||
const String& html = R"HTML(
|
||||
91
patches/chromium/backport_1065122.patch
Normal file
91
patches/chromium/backport_1065122.patch
Normal file
@@ -0,0 +1,91 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: add some crash debugging checks
|
||||
|
||||
[1065122] [High]: heap-use-after-free : ui::AXTreeSerializerblink::WebAXObject,content::AXContentNodeData,content::AXContentTreeData::LeastCommonAncestor
|
||||
Backport https://chromium.googlesource.com/chromium/src/+/e0a661af6c2c7346183c47b106afecb01adbfa2e
|
||||
|
||||
diff --git a/ui/accessibility/ax_tree_serializer.h b/ui/accessibility/ax_tree_serializer.h
|
||||
index 18fe3aa1b5f088632291f074ff9b29c5ce7694af..b9e6fc36fa68a45112dbacc97a912ca2d7ac2c71 100644
|
||||
--- a/ui/accessibility/ax_tree_serializer.h
|
||||
+++ b/ui/accessibility/ax_tree_serializer.h
|
||||
@@ -180,6 +180,8 @@ class AXTreeSerializer {
|
||||
// like when Reset() is called.
|
||||
void InternalReset();
|
||||
|
||||
+ ClientTreeNode* GetClientTreeNodeParent(ClientTreeNode* obj);
|
||||
+
|
||||
// The tree source.
|
||||
AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree_;
|
||||
|
||||
@@ -269,7 +271,7 @@ AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::LeastCommonAncestor(
|
||||
std::vector<ClientTreeNode*> client_ancestors;
|
||||
while (client_node) {
|
||||
client_ancestors.push_back(client_node);
|
||||
- client_node = client_node->parent;
|
||||
+ client_node = GetClientTreeNodeParent(client_node);
|
||||
}
|
||||
|
||||
// Start at the root. Keep going until the source ancestor chain and
|
||||
@@ -304,9 +306,12 @@ AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::LeastCommonAncestor(
|
||||
// that we're inside of an invalid subtree that all needs to be
|
||||
// re-serialized, so the LCA should be higher.
|
||||
ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node));
|
||||
- while (
|
||||
- tree_->IsValid(node) &&
|
||||
- (!client_node || (client_node->parent && client_node->parent->invalid))) {
|
||||
+ while (tree_->IsValid(node)) {
|
||||
+ if (client_node) {
|
||||
+ ClientTreeNode* parent = GetClientTreeNodeParent(client_node);
|
||||
+ if (!parent || !parent->invalid)
|
||||
+ break;
|
||||
+ }
|
||||
node = tree_->GetParent(node);
|
||||
if (tree_->IsValid(node))
|
||||
client_node = ClientTreeNodeById(tree_->GetId(node));
|
||||
@@ -326,12 +331,13 @@ bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
|
||||
int child_id = tree_->GetId(child);
|
||||
ClientTreeNode* client_child = ClientTreeNodeById(child_id);
|
||||
if (client_child) {
|
||||
- if (!client_child->parent) {
|
||||
+ ClientTreeNode* parent = client_child->parent;
|
||||
+ if (!parent) {
|
||||
// If the client child has no parent, it must have been the
|
||||
// previous root node, so there is no LCA and we can exit early.
|
||||
*out_lca = tree_->GetNull();
|
||||
return true;
|
||||
- } else if (client_child->parent->id != id) {
|
||||
+ } else if (parent->id != id) {
|
||||
// If the client child's parent is not this node, update the LCA
|
||||
// and return true (reparenting was found).
|
||||
*out_lca = LeastCommonAncestor(*out_lca, client_child);
|
||||
@@ -366,6 +372,19 @@ AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::ClientTreeNodeById(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
+template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
|
||||
+ClientTreeNode*
|
||||
+AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::GetClientTreeNodeParent(
|
||||
+ ClientTreeNode* obj) {
|
||||
+ ClientTreeNode* parent = obj->parent;
|
||||
+#if DCHECK_IS_ON()
|
||||
+ if (!parent)
|
||||
+ return nullptr;
|
||||
+ DCHECK(ClientTreeNodeById(parent->id)) << "Parent not in id map.";
|
||||
+#endif // DCHECK_IS_ON()
|
||||
+ return parent;
|
||||
+}
|
||||
+
|
||||
template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
|
||||
bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::SerializeChanges(
|
||||
AXSourceNode node,
|
||||
@@ -549,7 +568,7 @@ bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
|
||||
// above. If this happens, reset and return an error.
|
||||
|
||||
ClientTreeNode* client_child = ClientTreeNodeById(new_child_id);
|
||||
- if (client_child && client_child->parent != client_node) {
|
||||
+ if (client_child && GetClientTreeNodeParent(client_child) != client_node) {
|
||||
DVLOG(1) << "Illegal reparenting detected";
|
||||
#if defined(ADDRESS_SANITIZER)
|
||||
// Wrapping this in ADDRESS_SANITIZER will cause it to run on
|
||||
52
patches/chromium/backport_1073409.patch
Normal file
52
patches/chromium/backport_1073409.patch
Normal file
@@ -0,0 +1,52 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: use parseHTMLSubset() in chrome://histograms.
|
||||
|
||||
[1073409] [Low] [CVE-2020-6535]: XSS on chrome://histograms/ with a compromised renderer
|
||||
Backport https://chromium.googlesource.com/chromium/src/+/9a31a7ea51e0c7548f4ed77f5007e4a924ef0fbb
|
||||
|
||||
diff --git a/content/browser/resources/histograms/BUILD.gn b/content/browser/resources/histograms/BUILD.gn
|
||||
index cc4ce92ab285567195aac47d260dc9c819c69ae4..529ffa95c146b5e9afb95e091486faf1cdcf3005 100644
|
||||
--- a/content/browser/resources/histograms/BUILD.gn
|
||||
+++ b/content/browser/resources/histograms/BUILD.gn
|
||||
@@ -11,6 +11,7 @@ js_type_check("closure_compile") {
|
||||
js_library("histograms_internals") {
|
||||
deps = [
|
||||
"//ui/webui/resources/js:cr",
|
||||
+ "//ui/webui/resources/js:parse_html_subset",
|
||||
"//ui/webui/resources/js:util",
|
||||
]
|
||||
}
|
||||
diff --git a/content/browser/resources/histograms/histograms_internals.html b/content/browser/resources/histograms/histograms_internals.html
|
||||
index 37e45404843d70bd2621fffc6f5f4e4e69786005..b997e6d2ff88f86c00bf4e4a099cd4999d66c061 100644
|
||||
--- a/content/browser/resources/histograms/histograms_internals.html
|
||||
+++ b/content/browser/resources/histograms/histograms_internals.html
|
||||
@@ -8,6 +8,7 @@
|
||||
<script src="chrome://resources/js/cr.js"></script>
|
||||
<script src="chrome://resources/js/promise_resolver.js"></script>
|
||||
<script src="chrome://resources/js/util.js"></script>
|
||||
+ <script src="chrome://resources/js/parse_html_subset.js"></script>
|
||||
<script src="histograms_internals.js"></script>
|
||||
<title>Histograms</title>
|
||||
</head>
|
||||
diff --git a/content/browser/resources/histograms/histograms_internals.js b/content/browser/resources/histograms/histograms_internals.js
|
||||
index 24c55fb23c9f390a484572fe098e0cdcc79bc4ac..b70641ed43512391e4b75383b68196ba99590638 100644
|
||||
--- a/content/browser/resources/histograms/histograms_internals.js
|
||||
+++ b/content/browser/resources/histograms/histograms_internals.js
|
||||
@@ -24,9 +24,12 @@ function addHistograms(histograms) {
|
||||
htmlOutput += histogram;
|
||||
}
|
||||
|
||||
- // NOTE: This is generally unsafe due to XSS attacks. Make sure |htmlOutput|
|
||||
- // cannot be modified by an external party.
|
||||
- $('histograms').innerHTML = htmlOutput;
|
||||
+ // The following HTML tags are coming from
|
||||
+ // |HistogramsMessageHandler::HandleRequestHistograms|.
|
||||
+ const sanitizedHTML = parseHtmlSubset(`<span>${htmlOutput}</span>`, [
|
||||
+ 'PRE', 'H4', 'BR', 'HR'
|
||||
+ ]).firstChild.innerHTML;
|
||||
+ $('histograms').innerHTML = sanitizedHTML;
|
||||
}
|
||||
|
||||
/**
|
||||
89
patches/chromium/backport_1074317.patch
Normal file
89
patches/chromium/backport_1074317.patch
Normal file
@@ -0,0 +1,89 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: stop leaking cross-origin post-redirect data using StackTrace
|
||||
|
||||
[1074317] [High] [CVE-2020-6511]: Security: The CSP reports and stacktraces of errors leaks post-redirect URL for <script>
|
||||
Backport https://chromium.googlesource.com/chromium/src/+/0b707cbaa2cb806162797be55caf9f8074fbdccf
|
||||
|
||||
diff --git a/third_party/blink/renderer/bindings/core/v8/script_source_code.cc b/third_party/blink/renderer/bindings/core/v8/script_source_code.cc
|
||||
index 46148496dd4e71f5b2976fe24e17974111d09a89..38d117601d68112dfe0d9c41e384d04476e38e9c 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/script_source_code.cc
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/script_source_code.cc
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
|
||||
|
||||
+#include "base/feature_list.h"
|
||||
#include "third_party/blink/renderer/core/loader/resource/script_resource.h"
|
||||
#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h"
|
||||
|
||||
@@ -47,8 +48,16 @@ String SourceMapUrlFromResponse(const ResourceResponse& response) {
|
||||
return response.HttpHeaderField(http_names::kXSourceMap);
|
||||
}
|
||||
|
||||
+const base::Feature kUnsafeScriptReportPostRedirectURL{
|
||||
+ "UnsafeScriptReportPostRedirectURL", base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
+
|
||||
} // namespace
|
||||
|
||||
+// static
|
||||
+bool ScriptSourceCode::UsePostRedirectURL() {
|
||||
+ return base::FeatureList::IsEnabled(kUnsafeScriptReportPostRedirectURL);
|
||||
+}
|
||||
+
|
||||
ScriptSourceCode::ScriptSourceCode(
|
||||
const ParkableString& source,
|
||||
ScriptSourceLocationType source_location_type,
|
||||
@@ -84,8 +93,9 @@ ScriptSourceCode::ScriptSourceCode(ScriptStreamer* streamer,
|
||||
cache_handler_(resource->CacheHandler()),
|
||||
streamer_(streamer),
|
||||
not_streaming_reason_(reason),
|
||||
- url_(
|
||||
- StripFragmentIdentifier(resource->GetResponse().CurrentRequestUrl())),
|
||||
+ url_(StripFragmentIdentifier(
|
||||
+ UsePostRedirectURL() ? resource->GetResponse().CurrentRequestUrl()
|
||||
+ : resource->Url())),
|
||||
source_map_url_(SourceMapUrlFromResponse(resource->GetResponse())),
|
||||
start_position_(TextPosition::MinimumPosition()),
|
||||
source_location_type_(ScriptSourceLocationType::kExternalFile) {
|
||||
diff --git a/third_party/blink/renderer/bindings/core/v8/script_source_code.h b/third_party/blink/renderer/bindings/core/v8/script_source_code.h
|
||||
index eff28959c340b47033f923751c721fab2b003a32..f7e38a00d20052a32f3c5bf4fef2f4baa6c874e1 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/script_source_code.h
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/script_source_code.h
|
||||
@@ -49,6 +49,20 @@ class CORE_EXPORT ScriptSourceCode final {
|
||||
DISALLOW_NEW();
|
||||
|
||||
public:
|
||||
+ // Return whether chrome should use the request URL or the response URL as the
|
||||
+ // 'url' of the script. This can be observed in:
|
||||
+ // 1) The 'source-file' in CSP violations reports.
|
||||
+ // 2) The URL(s) in javascript stack traces.
|
||||
+ // 3) How relative source map are resolved.
|
||||
+ //
|
||||
+ // This returns false by default. This corresponds to the current
|
||||
+ // specification and matches Firefox behavior. This also avoids leaking
|
||||
+ // post-redirect data cross-origin. See https://crbug.com/1074317.
|
||||
+ //
|
||||
+ // This can be enabled using the switch:
|
||||
+ // --enable-features=UnsafeScriptReportPostRedirectURL
|
||||
+ static bool UsePostRedirectURL();
|
||||
+
|
||||
// For inline scripts.
|
||||
ScriptSourceCode(
|
||||
const String& source,
|
||||
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.cc b/third_party/blink/renderer/core/workers/worker_global_scope.cc
|
||||
index ee2b239577f2e76369492ce40beb690aa113e0bc..28b392f231f3bcb04c1f6e2fca50cf8c1550aaab 100644
|
||||
--- a/third_party/blink/renderer/core/workers/worker_global_scope.cc
|
||||
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.cc
|
||||
@@ -297,7 +297,9 @@ void WorkerGlobalScope::ImportScriptsInternal(const Vector<String>& urls,
|
||||
source_code.length(), handler ? handler->GetCodeCacheSize() : 0);
|
||||
ScriptController()->Evaluate(
|
||||
ScriptSourceCode(source_code, ScriptSourceLocationType::kUnknown,
|
||||
- handler, response_url),
|
||||
+ handler,
|
||||
+ ScriptSourceCode::UsePostRedirectURL() ? response_url
|
||||
+ : complete_url),
|
||||
sanitize_script_errors, &error_event, GetV8CacheOptions());
|
||||
if (error_event) {
|
||||
ScriptController()->RethrowExceptionFromImportedScript(error_event,
|
||||
21
patches/chromium/backport_1074340.patch
Normal file
21
patches/chromium/backport_1074340.patch
Normal file
@@ -0,0 +1,21 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: uninitialized frame policy issue in javascript url
|
||||
|
||||
[1074340] [Low] [CVE-2020-6526]: Security: javascript URI sandbox flags aren't propagated in a blank string case
|
||||
Backport https://chromium.googlesource.com/chromium/src/+/45bcb4d547a5efecae80f4c9a48cef854af91d7f
|
||||
|
||||
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
|
||||
index aa5720bd81d5f714ce91484e0804220aa1d88e55..350e2f1d822afbe9f8366daef7681874148fb56d 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
|
||||
@@ -299,6 +299,8 @@ void ScriptController::ExecuteJavaScriptURL(
|
||||
WebFeature::kReplaceDocumentViaJavaScriptURL);
|
||||
auto params = std::make_unique<WebNavigationParams>();
|
||||
params->url = GetFrame()->GetDocument()->Url();
|
||||
+ if (auto* owner = GetFrame()->Owner())
|
||||
+ params->frame_policy = owner->GetFramePolicy();
|
||||
|
||||
String result = ToCoreString(v8::Local<v8::String>::Cast(v8_result));
|
||||
WebNavigationParams::FillStaticResponse(params.get(), "text/html", "UTF-8",
|
||||
30
patches/chromium/backport_1081722.patch
Normal file
30
patches/chromium/backport_1081722.patch
Normal file
@@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: replace memcopy with memmove for overlapping copies
|
||||
|
||||
[1081722] [Medium] [CVE-2020-6524]: Security: memcpy-param-overlap in AudioBuffer::copyFromChannel
|
||||
Backport https://chromium.googlesource.com/chromium/src/+/2be9b1c27fb97e8a82e068794fc0fba555182c03
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.cc b/third_party/blink/renderer/modules/webaudio/audio_buffer.cc
|
||||
index 37a1650dfa295c7bf25acf8fa4146c2475105bf1..e587ec83a4728a02eb01ce58339e2cfad5a0c24d 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/audio_buffer.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.cc
|
||||
@@ -254,7 +254,7 @@ void AudioBuffer::copyFromChannel(NotShared<DOMFloat32Array> destination,
|
||||
DCHECK_LE(count, data_length);
|
||||
DCHECK_LE(buffer_offset + count, data_length);
|
||||
|
||||
- memcpy(dst, src + buffer_offset, count * sizeof(*src));
|
||||
+ memmove(dst, src + buffer_offset, count * sizeof(*src));
|
||||
}
|
||||
|
||||
void AudioBuffer::copyToChannel(NotShared<DOMFloat32Array> source,
|
||||
@@ -297,7 +297,7 @@ void AudioBuffer::copyToChannel(NotShared<DOMFloat32Array> source,
|
||||
DCHECK_LE(buffer_offset + count, channel_data->lengthAsSizeT());
|
||||
DCHECK_LE(count, source.View()->lengthAsSizeT());
|
||||
|
||||
- memcpy(dst + buffer_offset, src, count * sizeof(*dst));
|
||||
+ memmove(dst + buffer_offset, src, count * sizeof(*dst));
|
||||
}
|
||||
|
||||
void AudioBuffer::Zero() {
|
||||
43
patches/chromium/backport_1087629.patch
Normal file
43
patches/chromium/backport_1087629.patch
Normal file
@@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: update sqlite to v3.32.1
|
||||
|
||||
[1087629] [High]: Upgrade SQLite to 3.32.1
|
||||
Backport https://chromium.googlesource.com/chromium/src/+/fd7b2899867a6acbe0721be9321a6555e39be70c
|
||||
|
||||
diff --git a/DEPS b/DEPS
|
||||
index 530e4a466615dbb648543212498db0245a8f36fb..738bdc51dc20b9358cdaefb54c40f2f913d8ecd7 100644
|
||||
--- a/DEPS
|
||||
+++ b/DEPS
|
||||
@@ -1381,7 +1381,7 @@ deps = {
|
||||
Var('chromium_git') + '/external/github.com/google/snappy.git' + '@' + 'f5acee902c4d2110f671455460172cb6d3bf5b73',
|
||||
|
||||
'src/third_party/sqlite/src':
|
||||
- Var('chromium_git') + '/chromium/deps/sqlite.git' + '@' + '15401f78a1078345251d13469ac56cc607f825db',
|
||||
+ Var('chromium_git') + '/chromium/deps/sqlite.git' + '@' + 'b5399f70d4778fa2f0f0ada1bb5910e14c096be9',
|
||||
|
||||
'src/third_party/sqlite4java': {
|
||||
'packages': [
|
||||
diff --git a/sql/recover_module/module_unittest.cc b/sql/recover_module/module_unittest.cc
|
||||
index ef3e3e2b7b4b04d0abcf1d93275537803b6ce455..ba620b7fda684af09bce36b806b4051345775fbf 100644
|
||||
--- a/sql/recover_module/module_unittest.cc
|
||||
+++ b/sql/recover_module/module_unittest.cc
|
||||
@@ -534,7 +534,7 @@ TEST_F(RecoverModuleTest, Floats) {
|
||||
ASSERT_TRUE(statement.Step());
|
||||
EXPECT_EQ(2, statement.ColumnInt(0));
|
||||
EXPECT_EQ("INTEGER", statement.ColumnString(1));
|
||||
- EXPECT_EQ(sql::ColumnType::kFloat, statement.GetColumnType(2));
|
||||
+ EXPECT_EQ(sql::ColumnType::kInteger, statement.GetColumnType(2));
|
||||
EXPECT_EQ(17, statement.ColumnInt(2));
|
||||
ASSERT_TRUE(statement.Step());
|
||||
EXPECT_EQ(3, statement.ColumnInt(0));
|
||||
@@ -556,7 +556,7 @@ TEST_F(RecoverModuleTest, NonNullFloats) {
|
||||
ASSERT_TRUE(statement.Step());
|
||||
EXPECT_EQ(2, statement.ColumnInt(0));
|
||||
EXPECT_EQ("INTEGER", statement.ColumnString(1));
|
||||
- EXPECT_EQ(sql::ColumnType::kFloat, statement.GetColumnType(2));
|
||||
+ EXPECT_EQ(sql::ColumnType::kInteger, statement.GetColumnType(2));
|
||||
EXPECT_EQ(17, statement.ColumnInt(2));
|
||||
ASSERT_TRUE(statement.Step());
|
||||
EXPECT_EQ(3, statement.ColumnInt(0));
|
||||
32
patches/chromium/backport_1090543.patch
Normal file
32
patches/chromium/backport_1090543.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: guard against UaF in NavigationRequest
|
||||
|
||||
[1090543] [High]: heap-use-after-free : content::NavigationRequest::OnWillProcessResponseProcessed
|
||||
Backport https://chromium.googlesource.com/chromium/src/+/8a7c8c1affd3b03a41c6f79afa8ebce4168ded5b
|
||||
|
||||
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
|
||||
index 934fa63595053156b446dbc5fdccb196f1a0ba15..0b47fe73860e7b9ee200ac177d1e008881eb683c 100644
|
||||
--- a/content/browser/frame_host/navigation_request.cc
|
||||
+++ b/content/browser/frame_host/navigation_request.cc
|
||||
@@ -3242,11 +3242,19 @@ void NavigationRequest::OnWillProcessResponseProcessed(
|
||||
DCHECK(processing_navigation_throttle_);
|
||||
processing_navigation_throttle_ = false;
|
||||
if (result.action() == NavigationThrottle::PROCEED) {
|
||||
+ base::WeakPtr<NavigationRequest> weak_self(weak_factory_.GetWeakPtr());
|
||||
+
|
||||
// If the navigation is done processing the response, then it's ready to
|
||||
// commit. Inform observers that the navigation is now ready to commit,
|
||||
// unless it is not set to commit (204/205s/downloads).
|
||||
if (render_frame_host_)
|
||||
ReadyToCommitNavigation(false);
|
||||
+
|
||||
+ // The call above might block on showing a user dialog. The interaction of
|
||||
+ // the user with this dialog might result in the WebContents owning this
|
||||
+ // NavigationRequest to be destroyed. Return if this is the case.
|
||||
+ if (!weak_self)
|
||||
+ return;
|
||||
} else {
|
||||
state_ = CANCELING;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ potentially prevent a window from being created.
|
||||
TODO(loc): this patch is currently broken.
|
||||
|
||||
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
|
||||
index 657306b0c95c9a499ca626c033c4b5b73de71d59..d1503246dfa0edf16a918d0c5b141bf89ae95bb1 100644
|
||||
index b1ea181a9088bce0422701ac7d3e118b999fec5b..8a3afc59f96e0f29997d0e239726217d490189d8 100644
|
||||
--- a/content/browser/frame_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/frame_host/render_frame_host_impl.cc
|
||||
@@ -4324,6 +4324,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
|
||||
@@ -87,7 +87,7 @@ index 85378bb565de617b1bd611d28c8714361747a357..36de4c0b0353be2418dacd388e92d7c3
|
||||
}
|
||||
|
||||
diff --git a/ui/base/accelerators/system_media_controls_media_keys_listener.cc b/ui/base/accelerators/system_media_controls_media_keys_listener.cc
|
||||
index 9d6084ceaccfd071549e63e3015f55ef292312ec..3f6af8b1b49bf0f226e9336c222884b07bf69e55 100644
|
||||
index 9d6084ceaccfd071549e63e3015f55ef292312ec..846210b04d6e2e193413c643296938ec550f6d25 100644
|
||||
--- a/ui/base/accelerators/system_media_controls_media_keys_listener.cc
|
||||
+++ b/ui/base/accelerators/system_media_controls_media_keys_listener.cc
|
||||
@@ -65,6 +65,11 @@ bool SystemMediaControlsMediaKeysListener::StartWatchingMediaKey(
|
||||
@@ -102,3 +102,15 @@ index 9d6084ceaccfd071549e63e3015f55ef292312ec..3f6af8b1b49bf0f226e9336c222884b0
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
@@ -97,6 +102,11 @@ void SystemMediaControlsMediaKeysListener::StopWatchingMediaKey(
|
||||
case VKEY_MEDIA_STOP:
|
||||
service_->SetIsStopEnabled(false);
|
||||
break;
|
||||
+ case VKEY_VOLUME_DOWN:
|
||||
+ case VKEY_VOLUME_UP:
|
||||
+ case VKEY_VOLUME_MUTE:
|
||||
+ // Do nothing.
|
||||
+ break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
@@ -19,6 +19,21 @@ This can be removed once web content (including WebGL) learn how
|
||||
to deal with color spaces. That is being tracked at
|
||||
https://crbug.com/634542 and https://crbug.com/711107.
|
||||
|
||||
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
|
||||
index 1889f1df493c46f9460cadde1fd80267b141bf98..688a0905c997c86b63bcc607033ec82a74741114 100644
|
||||
--- a/cc/trees/layer_tree_host_impl.cc
|
||||
+++ b/cc/trees/layer_tree_host_impl.cc
|
||||
@@ -1794,6 +1794,10 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw(
|
||||
|
||||
gfx::ColorSpace LayerTreeHostImpl::GetRasterColorSpace(
|
||||
gfx::ContentColorUsage content_color_usage) const {
|
||||
+ if (!settings_.enable_color_correct_rendering) {
|
||||
+ return {};
|
||||
+ }
|
||||
+
|
||||
constexpr gfx::ColorSpace srgb = gfx::ColorSpace::CreateSRGB();
|
||||
|
||||
if (settings_.prefer_raster_in_srgb &&
|
||||
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
|
||||
index 95a901678c215220b9e88db768444d48e32f6dbd..841c809b0b50c8c34a9d9c972c511bd4fd57a7b0 100644
|
||||
--- a/cc/trees/layer_tree_settings.h
|
||||
@@ -293,7 +308,7 @@ index d88680239152858689121d134559765fb8fae1b7..073ed8a8f84ebf994a2b9d9fa7e78f75
|
||||
|
||||
gfx::ColorSpace::TransferID transfer_id =
|
||||
diff --git a/ui/gfx/mac/io_surface.cc b/ui/gfx/mac/io_surface.cc
|
||||
index 2674784dca1ed12b2f5afc7b728e0c6e8cd6ca4a..5b661c70c9c89883a1aaaf1a29a9ec9fe7f16da6 100644
|
||||
index 2674784dca1ed12b2f5afc7b728e0c6e8cd6ca4a..93a9652b71d86441e15b87aafd7a6b1a13f45830 100644
|
||||
--- a/ui/gfx/mac/io_surface.cc
|
||||
+++ b/ui/gfx/mac/io_surface.cc
|
||||
@@ -16,6 +16,7 @@
|
||||
@@ -304,33 +319,37 @@ index 2674784dca1ed12b2f5afc7b728e0c6e8cd6ca4a..5b661c70c9c89883a1aaaf1a29a9ec9f
|
||||
|
||||
namespace gfx {
|
||||
|
||||
@@ -258,6 +259,11 @@ IOSurfaceRef CreateIOSurface(const gfx::Size& size,
|
||||
IOSurfaceSetValue(surface, CFSTR("IOSurfaceColorSpace"), kCGColorSpaceSRGB);
|
||||
} else {
|
||||
CGColorSpaceRef color_space = base::mac::GetSRGBColorSpace();
|
||||
+ auto* cmd_line = base::CommandLine::ForCurrentProcess();
|
||||
+ if (cmd_line->HasSwitch(switches::kDisableColorCorrectRendering)) {
|
||||
+ color_space = base::mac::GetSystemColorSpace();
|
||||
+ }
|
||||
+
|
||||
base::ScopedCFTypeRef<CFDataRef> color_space_icc(
|
||||
CGColorSpaceCopyICCProfile(color_space));
|
||||
IOSurfaceSetValue(surface, CFSTR("IOSurfaceColorSpace"), color_space_icc);
|
||||
@@ -274,6 +280,14 @@ bool IOSurfaceCanSetColorSpace(const ColorSpace& color_space) {
|
||||
|
||||
void IOSurfaceSetColorSpace(IOSurfaceRef io_surface,
|
||||
@@ -119,6 +120,14 @@ void IOSurfaceMachPortTraits::Release(mach_port_t port) {
|
||||
// Common method used by IOSurfaceSetColorSpace and IOSurfaceCanSetColorSpace.
|
||||
bool IOSurfaceSetColorSpace(IOSurfaceRef io_surface,
|
||||
const ColorSpace& color_space) {
|
||||
+ auto* cmd_line = base::CommandLine::ForCurrentProcess();
|
||||
+ if (cmd_line->HasSwitch(switches::kDisableColorCorrectRendering)) {
|
||||
+ base::ScopedCFTypeRef<CFDataRef> system_icc(
|
||||
+ CGColorSpaceCopyICCProfile(base::mac::GetSystemColorSpace()));
|
||||
+ IOSurfaceSetValue(io_surface, CFSTR("IOSurfaceColorSpace"), system_icc);
|
||||
+ return;
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
if (!internal::IOSurfaceSetColorSpace(io_surface, color_space)) {
|
||||
DLOG(ERROR) << "Failed to set color space for IOSurface: "
|
||||
<< color_space.ToString();
|
||||
// Allow but ignore invalid color spaces.
|
||||
if (!color_space.IsValid())
|
||||
return true;
|
||||
@@ -253,6 +262,15 @@ IOSurfaceRef CreateIOSurface(const gfx::Size& size,
|
||||
DCHECK_EQ(kIOReturnSuccess, r);
|
||||
}
|
||||
|
||||
+ auto* cmd_line = base::CommandLine::ForCurrentProcess();
|
||||
+ if (cmd_line->HasSwitch(switches::kDisableColorCorrectRendering)) {
|
||||
+ CGColorSpaceRef color_space = base::mac::GetSystemColorSpace();
|
||||
+ base::ScopedCFTypeRef<CFDataRef> color_space_icc(
|
||||
+ CGColorSpaceCopyICCProfile(color_space));
|
||||
+ IOSurfaceSetValue(surface, CFSTR("IOSurfaceColorSpace"), color_space_icc);
|
||||
+ return surface;
|
||||
+ }
|
||||
+
|
||||
// Ensure that all IOSurfaces start as sRGB.
|
||||
if (__builtin_available(macos 10.12, *)) {
|
||||
IOSurfaceSetValue(surface, CFSTR("IOSurfaceColorSpace"), kCGColorSpaceSRGB);
|
||||
diff --git a/ui/gfx/switches.cc b/ui/gfx/switches.cc
|
||||
index 0f746ead72a2c195321384c9c4ced96d0608fb7b..a9cc7b6d93cdb42c5a9a177e8a09edeb36db8122 100644
|
||||
--- a/ui/gfx/switches.cc
|
||||
|
||||
@@ -6,10 +6,10 @@ Subject: disable_user_gesture_requirement_for_beforeunload_dialogs.patch
|
||||
See https://github.com/electron/electron/issues/10754
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
|
||||
index ef44c779973737d2abc024553b317f0dc2ccccdc..ae9608974be11e28d8d2737302f0d377cd8f674c 100644
|
||||
index f55c90df9969ace76a0813d02237edcb406e079c..6b341a5c046685afdfc2502191f1f209567c2c6e 100644
|
||||
--- a/third_party/blink/renderer/core/dom/document.cc
|
||||
+++ b/third_party/blink/renderer/core/dom/document.cc
|
||||
@@ -4151,7 +4151,9 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient* chrome_client,
|
||||
@@ -4156,7 +4156,9 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient* chrome_client,
|
||||
"frame that never had a user gesture since its load. "
|
||||
"https://www.chromestatus.com/feature/5082396709879808";
|
||||
Intervention::GenerateReport(frame_, "BeforeUnloadNoGesture", message);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Mon, 1 Jun 2020 20:36:16 +0000
|
||||
Subject: fix: default to NTLM v2 in network service for POSIX platforms
|
||||
|
||||
NTLM always defaults to NTLM v2 at the //net layer for quite
|
||||
sometime now https://crbug.com/22532.
|
||||
|
||||
Change-Id: I4ea2dedc10c63a7c4e00101c0acc6d8a713c5054
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2222116
|
||||
Auto-Submit: Deepak Mohan <hop2deep@gmail.com>
|
||||
Reviewed-by: Tom Sepez <tsepez@chromium.org>
|
||||
Commit-Queue: Tom Sepez <tsepez@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#773809}
|
||||
|
||||
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom
|
||||
index 4ed52a1fd6edafd74e0927aeb469603b25e1d0f8..ad42acc4f6b7dab6406cccc8eec945b6962110da 100644
|
||||
--- a/services/network/public/mojom/network_service.mojom
|
||||
+++ b/services/network/public/mojom/network_service.mojom
|
||||
@@ -152,7 +152,7 @@ struct HttpAuthDynamicParams {
|
||||
bool enable_negotiate_port = true;
|
||||
|
||||
// Whether NTLM V2 is enabled on POSIX platforms. No effect elsewhere.
|
||||
- bool ntlm_v2_enabled = false;
|
||||
+ bool ntlm_v2_enabled = true;
|
||||
|
||||
// The AccountManager AccountManagerget.AccountsByTypeAndFeatures on Android
|
||||
// when using Negotiate authentication.
|
||||
@@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: handle non client pointer events from pen on Windows 10
|
||||
|
||||
Refs: https://github.com/electron/electron/issues/21440
|
||||
Refs: https://chromium-review.googlesource.com/c/chromium/src/+/2237535
|
||||
|
||||
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
|
||||
index 281c722d81c0ad5fa7bacbe25c07a7578dfa43b6..037ace982ed86c515e7b024d0cd2862d604ec63b 100644
|
||||
--- a/ui/views/win/hwnd_message_handler.cc
|
||||
+++ b/ui/views/win/hwnd_message_handler.cc
|
||||
@@ -1993,6 +1993,15 @@ LRESULT HWNDMessageHandler::OnPointerEvent(UINT message,
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ // Pen may also send non client pointer messages, treat them as normal
|
||||
+ // touch events so they can be properly handled.
|
||||
+ if (pointer_type == PT_PEN &&
|
||||
+ (message == WM_NCPOINTERDOWN ||
|
||||
+ message == WM_NCPOINTERUP ||
|
||||
+ message == WM_NCPOINTERUPDATE)) {
|
||||
+ pointer_type = PT_TOUCH;
|
||||
+ }
|
||||
+
|
||||
switch (pointer_type) {
|
||||
case PT_PEN:
|
||||
return HandlePointerEventTypePen(message, w_param, l_param);
|
||||
@@ -0,0 +1,79 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <samuel.r.attard@gmail.com>
|
||||
Date: Wed, 20 May 2020 13:48:51 -0700
|
||||
Subject: fix: swap global proxies before initializing the windows proxies
|
||||
|
||||
Electron's Context Isolation implementation has a side-effect of initializing
|
||||
the isolated worlds WindowProxy during the initialization of the main world
|
||||
WindowProxy as a result of creating the isolated world inside the DidCreateScriptContext
|
||||
hook. This results in an assertion failing in Chromium during a frame
|
||||
swap where it expects to be able to set a new global_proxy in the WindowProxy
|
||||
of the isolated world BEFORE it is initialized.
|
||||
|
||||
To meet this assumption this patch splits SetGlobalProxy into two calls,
|
||||
SetGlobalProxyWithoutInitializing and InitializeIfNeeded which has the same
|
||||
resultant effect but means that all of the global_proxy objects are set
|
||||
BEFORE any WindowProxy's are initialized.
|
||||
|
||||
This could probably be upstreamed as it doesn't affect the way Chromium works
|
||||
but also it has no benefit for them at this time.
|
||||
|
||||
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/window_proxy.cc
|
||||
index 389dcd940e93ee043cf7a4435991c64d67386a38..0b5c44d75ae590b493da5584a82ea38a8246a9bf 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/window_proxy.cc
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/window_proxy.cc
|
||||
@@ -104,10 +104,7 @@ v8::Local<v8::Object> WindowProxy::ReleaseGlobalProxy() {
|
||||
}
|
||||
|
||||
void WindowProxy::SetGlobalProxy(v8::Local<v8::Object> global_proxy) {
|
||||
- DCHECK_EQ(lifecycle_, Lifecycle::kContextIsUninitialized);
|
||||
-
|
||||
- CHECK(global_proxy_.IsEmpty());
|
||||
- global_proxy_.Set(isolate_, global_proxy);
|
||||
+ SetGlobalProxyWithoutInitializing(global_proxy);
|
||||
|
||||
// Initialize the window proxy now, to re-establish the connection between
|
||||
// the global object and the v8::Context. This is really only needed for a
|
||||
@@ -118,6 +115,13 @@ void WindowProxy::SetGlobalProxy(v8::Local<v8::Object> global_proxy) {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
+void WindowProxy::SetGlobalProxyWithoutInitializing(v8::Local<v8::Object> global_proxy) {
|
||||
+ DCHECK_EQ(lifecycle_, Lifecycle::kContextIsUninitialized);
|
||||
+
|
||||
+ CHECK(global_proxy_.IsEmpty());
|
||||
+ global_proxy_.Set(isolate_, global_proxy);
|
||||
+}
|
||||
+
|
||||
// Create a new environment and setup the global object.
|
||||
//
|
||||
// The global object corresponds to a DOMWindow instance. However, to
|
||||
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy.h b/third_party/blink/renderer/bindings/core/v8/window_proxy.h
|
||||
index ce6aac22126e0a39fa28fcde56e903abd3a9d510..1cf5e056252af5f8ba4725722ac8d9f9d4a88de2 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/window_proxy.h
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/window_proxy.h
|
||||
@@ -156,6 +156,7 @@ class WindowProxy : public GarbageCollected<WindowProxy> {
|
||||
CORE_EXPORT v8::Local<v8::Object> GlobalProxyIfNotDetached();
|
||||
v8::Local<v8::Object> ReleaseGlobalProxy();
|
||||
void SetGlobalProxy(v8::Local<v8::Object>);
|
||||
+ void SetGlobalProxyWithoutInitializing(v8::Local<v8::Object>);
|
||||
|
||||
// TODO(dcheng): Temporarily exposed to avoid include cycles. Remove the need
|
||||
// for this and remove this getter.
|
||||
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
|
||||
index ba9845625ea960c1f0be69251a41d51a3a1fd313..a1aa5de76a86cc0a135ae775e4d8455993f10e75 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
|
||||
@@ -55,8 +55,11 @@ void WindowProxyManager::ReleaseGlobalProxies(
|
||||
|
||||
void WindowProxyManager::SetGlobalProxies(
|
||||
const GlobalProxyVector& global_proxies) {
|
||||
+ for (const auto& entry : global_proxies) {
|
||||
+ WindowProxyMaybeUninitialized(*entry.first)->SetGlobalProxyWithoutInitializing(entry.second);
|
||||
+ }
|
||||
for (const auto& entry : global_proxies)
|
||||
- WindowProxyMaybeUninitialized(*entry.first)->SetGlobalProxy(entry.second);
|
||||
+ WindowProxyMaybeUninitialized(*entry.first)->InitializeIfNeeded();
|
||||
}
|
||||
|
||||
WindowProxyManager::WindowProxyManager(Frame& frame, FrameType frame_type)
|
||||
@@ -63,7 +63,7 @@ index 33e17f0df3563726767d912fb828ab959c8ec252..780967949746cbe957cd7b3487507892
|
||||
}
|
||||
|
||||
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
|
||||
index 3378f34bd8e3b1cf8156e86d0e9bea97120c101e..c7c611486b158095c10db7d8e425635ed323b7db 100644
|
||||
index 3378f34bd8e3b1cf8156e86d0e9bea97120c101e..6c6d5c885f41412e25ddfc3b884b9c39fabc4f10 100644
|
||||
--- a/chrome/browser/printing/print_view_manager_base.cc
|
||||
+++ b/chrome/browser/printing/print_view_manager_base.cc
|
||||
@@ -27,10 +27,7 @@
|
||||
@@ -167,7 +167,18 @@ index 3378f34bd8e3b1cf8156e86d0e9bea97120c101e..c7c611486b158095c10db7d8e425635e
|
||||
#endif
|
||||
|
||||
ReleasePrinterQuery();
|
||||
@@ -461,9 +474,13 @@ void PrintViewManagerBase::OnNotifyPrintJobEvent(
|
||||
@@ -380,6 +393,10 @@ void PrintViewManagerBase::OnScriptedPrint(
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::OnShowInvalidPrinterSettingsError() {
|
||||
+ if (!callback_.is_null()) {
|
||||
+ std::string cb_str = "Invalid printer settings";
|
||||
+ std::move(callback_).Run(printing_succeeded_, cb_str);
|
||||
+ }
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, base::BindOnce(&ShowWarningMessageBox,
|
||||
l10n_util::GetStringUTF16(
|
||||
@@ -461,9 +478,13 @@ void PrintViewManagerBase::OnNotifyPrintJobEvent(
|
||||
content::NotificationService::NoDetails());
|
||||
break;
|
||||
}
|
||||
@@ -183,7 +194,7 @@ index 3378f34bd8e3b1cf8156e86d0e9bea97120c101e..c7c611486b158095c10db7d8e425635e
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
@@ -558,8 +575,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
@@ -558,8 +579,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
DCHECK(!quit_inner_loop_);
|
||||
DCHECK(query);
|
||||
|
||||
@@ -196,7 +207,7 @@ index 3378f34bd8e3b1cf8156e86d0e9bea97120c101e..c7c611486b158095c10db7d8e425635e
|
||||
|
||||
// We can't print if there is no renderer.
|
||||
if (!web_contents()->GetRenderViewHost() ||
|
||||
@@ -574,8 +593,6 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
@@ -574,8 +597,6 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
print_job_->SetSource(PrintJob::Source::PRINT_PREVIEW, /*source_id=*/"");
|
||||
#endif // defined(OS_CHROMEOS)
|
||||
|
||||
@@ -205,7 +216,7 @@ index 3378f34bd8e3b1cf8156e86d0e9bea97120c101e..c7c611486b158095c10db7d8e425635e
|
||||
printing_succeeded_ = false;
|
||||
return true;
|
||||
}
|
||||
@@ -624,14 +641,22 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
@@ -624,14 +645,22 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
content::RenderFrameHost* rfh = printing_rfh_;
|
||||
printing_rfh_ = nullptr;
|
||||
|
||||
@@ -230,7 +241,7 @@ index 3378f34bd8e3b1cf8156e86d0e9bea97120c101e..c7c611486b158095c10db7d8e425635e
|
||||
// Don't close the worker thread.
|
||||
print_job_ = nullptr;
|
||||
}
|
||||
@@ -667,7 +692,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
@@ -667,7 +696,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
||||
|
||||
20
patches/chromium/remove_menu_window_task_item.patch
Normal file
20
patches/chromium/remove_menu_window_task_item.patch
Normal file
@@ -0,0 +1,20 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: remove menu window from taskbar
|
||||
|
||||
Refs https://chromium-review.googlesource.com/c/chromium/src/+/2245941
|
||||
|
||||
diff --git a/ui/views/widget/widget_hwnd_utils.cc b/ui/views/widget/widget_hwnd_utils.cc
|
||||
index 40e66a212e3ea158b61f11d804a3c1644023b2d7..89f5b62f95dfec59bacf79f33895438039fac1c5 100644
|
||||
--- a/ui/views/widget/widget_hwnd_utils.cc
|
||||
+++ b/ui/views/widget/widget_hwnd_utils.cc
|
||||
@@ -118,6 +118,8 @@ void CalculateWindowStylesFromInitParams(
|
||||
else
|
||||
*style |= WS_BORDER;
|
||||
}
|
||||
+ if (!params.force_show_in_taskbar)
|
||||
+ *ex_style |= WS_EX_TOOLWINDOW;
|
||||
break;
|
||||
case Widget::InitParams::TYPE_TOOLTIP:
|
||||
*style |= WS_POPUP;
|
||||
@@ -5,5 +5,13 @@
|
||||
|
||||
"src/electron/patches/v8": "src/v8",
|
||||
|
||||
"src/electron/patches/node": "src/third_party/electron_node"
|
||||
"src/electron/patches/node": "src/third_party/electron_node",
|
||||
|
||||
"src/electron/patches/pdfium": "src/third_party/pdfium",
|
||||
|
||||
"src/electron/patches/webrtc": "src/third_party/webrtc",
|
||||
|
||||
"src/electron/patches/skia": "src/third_party/skia",
|
||||
|
||||
"src/electron/patches/ffmpeg": "src/third_party/ffmpeg"
|
||||
}
|
||||
|
||||
1
patches/ffmpeg/.patches
Normal file
1
patches/ffmpeg/.patches
Normal file
@@ -0,0 +1 @@
|
||||
backport_1065731.patch
|
||||
30
patches/ffmpeg/backport_1065731.patch
Normal file
30
patches/ffmpeg/backport_1065731.patch
Normal file
@@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: check return value from avio_read()
|
||||
|
||||
[1065731] [Medium]: audio_decoder_fuzzer: Use-of-uninitialized-value in amr_read_header
|
||||
Backport https://chromium.googlesource.com/chromium/third_party/ffmpeg.git/+/5b967f56b6d85f62446836fc8ef64d0dcfcbda17
|
||||
|
||||
diff --git a/libavformat/amr.c b/libavformat/amr.c
|
||||
index eccbbde5b0218e36fd27920850908d88539b9242..b8a5debb167737578f40e3cddc28dbd95871f2b5 100644
|
||||
--- a/libavformat/amr.c
|
||||
+++ b/libavformat/amr.c
|
||||
@@ -89,13 +89,15 @@ static int amr_read_header(AVFormatContext *s)
|
||||
AVStream *st;
|
||||
uint8_t header[9];
|
||||
|
||||
- avio_read(pb, header, 6);
|
||||
+ if (avio_read(pb, header, 6) != 6)
|
||||
+ return AVERROR_INVALIDDATA;
|
||||
|
||||
st = avformat_new_stream(s, NULL);
|
||||
if (!st)
|
||||
return AVERROR(ENOMEM);
|
||||
if (memcmp(header, AMR_header, 6)) {
|
||||
- avio_read(pb, header + 6, 3);
|
||||
+ if (avio_read(pb, header + 6, 3) != 3)
|
||||
+ return AVERROR_INVALIDDATA;
|
||||
if (memcmp(header, AMRWB_header, 9)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -37,3 +37,7 @@ override_existing_v8_reallocate.patch
|
||||
avoid_calling_deprecated_method.patch
|
||||
remove_deprecated_wasm_module_type_check.patch
|
||||
fix_don_t_preparemainexecution_twice.patch
|
||||
win_use_rtlgenrandom_from_advapi32_dll_directly.patch
|
||||
tools_update_certdata_txt.patch
|
||||
crypto_update_root_certificates.patch
|
||||
darwin_work_around_clock_jumping_back_in_time.patch
|
||||
|
||||
@@ -38,7 +38,7 @@ index fabaea75686161f488a03349e07049a513b98fad..5a6b01dc12fb77d5f8c26a1153ead2a1
|
||||
|
||||
bool Exists(const char* id);
|
||||
diff --git a/tools/js2c.py b/tools/js2c.py
|
||||
index 752344d68c3f63b4c5e491b33d4576ed48f8b74f..a6f0805048e3c3f4dd81ce6e90b684c48e52b67c 100755
|
||||
index 752344d68c3f63b4c5e491b33d4576ed48f8b74f..dc3946e3ac579134dd26e5855a1db0a7ed44e405 100755
|
||||
--- a/tools/js2c.py
|
||||
+++ b/tools/js2c.py
|
||||
@@ -187,13 +187,15 @@ namespace native_module {{
|
||||
@@ -100,14 +100,14 @@ index 752344d68c3f63b4c5e491b33d4576ed48f8b74f..a6f0805048e3c3f4dd81ce6e90b684c4
|
||||
- definitions.append(config_def)
|
||||
+ # Electron: Expose fs module without asar support.
|
||||
+ if filename == 'lib/fs.js':
|
||||
+ # Node's 'fs' and 'internal/fs/streams' have a lazy-loaded circular
|
||||
+ # dependency. So to expose the unmodified Node 'fs' functionality here,
|
||||
+ # we have to copy both 'fs' *and* 'internal/fs/streams' and modify the
|
||||
+ # Node's 'fs' and 'internal/fs/<filename> have lazy-loaded circular
|
||||
+ # dependencies. So to expose the unmodified Node 'fs' functionality here,
|
||||
+ # we have to copy both 'fs' *and* 'internal/fs/<filename>' files and modify the
|
||||
+ # copies to depend on each other instead of on our asarified 'fs' code.
|
||||
+ # See https://github.com/electron/electron/pull/16028 for more.
|
||||
+ AddModule('lib/original-fs.js', consts, macros, definitions, initializers, lambda _: ReadFile(filename).replace("require('internal/fs/streams')", "require('internal/original-fs/streams')"))
|
||||
+ elif filename == 'lib/internal/fs/streams.js':
|
||||
+ AddModule('lib/internal/original-fs/streams.js', consts, macros, definitions, initializers, lambda _: ReadFile(filename).replace("require('fs')", "require('original-fs')"))
|
||||
+ AddModule('lib/original-fs.js', consts, macros, definitions, initializers, lambda _: ReadFile(filename).replace("require('internal/fs/", "require('internal/original-fs/"))
|
||||
+ elif filename.startswith('lib/internal/fs/'):
|
||||
+ original_fs_filename = filename.replace('internal/fs/', 'internal/original-fs/')
|
||||
+ AddModule(original_fs_filename, consts, macros, definitions, initializers, lambda _: ReadFile(filename).replace("require('fs')", "require('original-fs')"))
|
||||
+
|
||||
+ config_size = 0
|
||||
+ if not only_js:
|
||||
|
||||
65
patches/node/crypto_update_root_certificates.patch
Normal file
65
patches/node/crypto_update_root_certificates.patch
Normal file
@@ -0,0 +1,65 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: AshCripps <Ashley.Cripps@ibm.com>
|
||||
Date: Mon, 1 Jun 2020 13:34:20 +0100
|
||||
Subject: crypto: update root certificates
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Update the list of root certificates in src/node_root_certs.h with
|
||||
tools/mk-ca-bundle.pl.
|
||||
|
||||
Certificates added:
|
||||
Entrust Root Certification Authority - G4
|
||||
|
||||
Certificates removed:
|
||||
|
||||
PR-URL: https://github.com/nodejs/node/pull/33682
|
||||
Reviewed-By: James M Snell <jasnell@gmail.com>
|
||||
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
|
||||
Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com>
|
||||
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
|
||||
|
||||
diff --git a/src/node_root_certs.h b/src/node_root_certs.h
|
||||
index bc08910c77ad4c9d1121614aa9b97eed0433175c..f8e84e7d231e33736a798c2fd344566df2d2c6a6 100644
|
||||
--- a/src/node_root_certs.h
|
||||
+++ b/src/node_root_certs.h
|
||||
@@ -3421,4 +3421,38 @@
|
||||
"qp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBaLJstxabArahH9CdMOA0uG0k7\n"
|
||||
"UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEGmpv0\n"
|
||||
"-----END CERTIFICATE-----",
|
||||
+
|
||||
+/* Entrust Root Certification Authority - G4 */
|
||||
+"-----BEGIN CERTIFICATE-----\n"
|
||||
+"MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAwgb4xCzAJ\n"
|
||||
+"BgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVu\n"
|
||||
+"dHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMu\n"
|
||||
+"IC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0\n"
|
||||
+"aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDEx\n"
|
||||
+"Nlowgb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9T\n"
|
||||
+"ZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRy\n"
|
||||
+"dXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg\n"
|
||||
+"Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0BAQEFAAOC\n"
|
||||
+"Ag8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ2K+EbTBwXX7zLtJT\n"
|
||||
+"meH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3ET+iq4qA7ec2/a0My3dl0ELn3\n"
|
||||
+"9GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1\n"
|
||||
+"NhSXNdh4IjVS70O92yfbYVaCNNzLiGAMC1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc\n"
|
||||
+"0ieCU0plUmr1POeo8pyvi73TDtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh64\n"
|
||||
+"3IhuJbNsZvc8kPNXwbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmO\n"
|
||||
+"eX7m640A2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm\n"
|
||||
+"nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8dWbrAuMI\n"
|
||||
+"NClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwlN4y6mACXi0mWHv0l\n"
|
||||
+"iqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNjc0kCAwEAAaNCMEAwDwYDVR0T\n"
|
||||
+"AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJ84xFYjwznooHFs6FRM5Og6\n"
|
||||
+"sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ\n"
|
||||
+"9POrYs4QjbRaZIxowLByQzTSGwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5\n"
|
||||
+"ZDIBf9PD3Vht7LGrhFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0g\n"
|
||||
+"kLpHZPt/B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI\n"
|
||||
+"AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbwH5Lk6rWS\n"
|
||||
+"02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+b7DUUH8i119lAg2m\n"
|
||||
+"9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk2fCfDrGA4tGeEWSpiBE6doLl\n"
|
||||
+"YsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47OlIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuI\n"
|
||||
+"jnDrnBdSqEGULoe256YSxXXfW8AKbnuk5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh\n"
|
||||
+"7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw==\n"
|
||||
+"-----END CERTIFICATE-----",
|
||||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
||||
@@ -0,0 +1,64 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Noordhuis <info@bnoordhuis.nl>
|
||||
Date: Wed, 1 Jul 2020 10:32:57 +0200
|
||||
Subject: darwin: work around clock jumping back in time
|
||||
|
||||
It was reported that mach_absolute_time() can jump backward in time when
|
||||
the machine is suspended. Use mach_continuous_time() when available to
|
||||
work around that (macOS 10.12 and up.)
|
||||
|
||||
Fixes: https://github.com/libuv/libuv/issues/2891
|
||||
PR-URL: https://github.com/libuv/libuv/pull/2894
|
||||
Reviewed-By: Phil Willoughby <philwill@fb.com>
|
||||
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
|
||||
|
||||
diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c
|
||||
index 5cf03aea0b405402b88494f3840bcfe606551b53..030ed1adb23966f89877135dd0bd20629248f007 100644
|
||||
--- a/deps/uv/src/unix/darwin.c
|
||||
+++ b/deps/uv/src/unix/darwin.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
+#include <dlfcn.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
|
||||
@@ -32,6 +33,10 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <unistd.h> /* sysconf */
|
||||
|
||||
+static uv_once_t once = UV_ONCE_INIT;
|
||||
+static uint64_t (*time_func)(void);
|
||||
+static mach_timebase_info_data_t timebase;
|
||||
+
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop) {
|
||||
loop->cf_state = NULL;
|
||||
@@ -48,15 +53,19 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
-uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
- static mach_timebase_info_data_t info;
|
||||
-
|
||||
- if ((ACCESS_ONCE(uint32_t, info.numer) == 0 ||
|
||||
- ACCESS_ONCE(uint32_t, info.denom) == 0) &&
|
||||
- mach_timebase_info(&info) != KERN_SUCCESS)
|
||||
+static void uv__hrtime_init_once(void) {
|
||||
+ if (KERN_SUCCESS != mach_timebase_info(&timebase))
|
||||
abort();
|
||||
|
||||
- return mach_absolute_time() * info.numer / info.denom;
|
||||
+ time_func = (uint64_t (*)(void)) dlsym(RTLD_DEFAULT, "mach_continuous_time");
|
||||
+ if (time_func == NULL)
|
||||
+ time_func = mach_absolute_time;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
+ uv_once(&once, uv__hrtime_init_once);
|
||||
+ return time_func() * timebase.numer / timebase.denom;
|
||||
}
|
||||
|
||||
|
||||
409
patches/node/tools_update_certdata_txt.patch
Normal file
409
patches/node/tools_update_certdata_txt.patch
Normal file
@@ -0,0 +1,409 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: AshCripps <Ashley.Cripps@ibm.com>
|
||||
Date: Mon, 1 Jun 2020 13:31:36 +0100
|
||||
Subject: tools: update certdata.txt
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This is the certdata.txt[0] from NSS 3.53, released on 2020-05-29.
|
||||
|
||||
This is the version of NSS that will ship in Firefox 78 on
|
||||
2020-06-30.
|
||||
|
||||
[0] https://hg.mozilla.org/projects/nss/raw-file/NSS_3_53_RTM/lib/ckfw/builtins/certdata.txt
|
||||
|
||||
PR-URL: https://github.com/nodejs/node/pull/33682
|
||||
Reviewed-By: James M Snell <jasnell@gmail.com>
|
||||
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
|
||||
Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com>
|
||||
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
|
||||
|
||||
diff --git a/tools/certdata.txt b/tools/certdata.txt
|
||||
index 3a44db293df268fd3f183f5a297a368ac51d975d..ea14926063b4b5e61a90d0f330d60172317e4346 100644
|
||||
--- a/tools/certdata.txt
|
||||
+++ b/tools/certdata.txt
|
||||
@@ -1810,7 +1810,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\302\005\146\200\241\313\346\063
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Wed Jan 01 00:00:00 2020
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\062\060\060\061\060\061\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "GeoTrust Global CA"
|
||||
@@ -1972,7 +1975,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\244\346\216\330\371\051\110\212\316\163\376\054
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Sun Sep 30 00:00:00 2018
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\061\070\060\071\063\060\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "GeoTrust Universal CA"
|
||||
@@ -2134,7 +2140,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\362\034\054\176\256\002\026\322\126\320\057\127\123\107\350\222
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Wed Jan 01 00:00:00 2020
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\062\060\060\061\060\061\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "GeoTrust Universal CA 2"
|
||||
@@ -4131,7 +4140,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\245\206\054\174\364\022
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Thu Sep 19 00:00:00 2019
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\061\071\060\071\061\071\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "Taiwan GRCA"
|
||||
@@ -5329,7 +5341,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\253\022\350\263\336\132\345\240\174\350\017\042\035\132\351\131
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Tue Apr 30 00:00:00 2019
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\061\071\060\064\063\060\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "GeoTrust Primary Certification Authority"
|
||||
@@ -5486,7 +5501,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\215\126\214\150
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Tue Apr 30 00:00:00 2019
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\061\071\060\064\063\060\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "thawte Primary Root CA"
|
||||
@@ -5663,7 +5681,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\254\021\326\250\355\143\152
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Tue Apr 30 00:00:00 2019
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\061\071\060\064\063\060\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "VeriSign Class 3 Public Primary Certification Authority - G5"
|
||||
@@ -7240,7 +7261,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\021\055
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Tue Apr 30 00:00:00 2019
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\061\071\060\064\063\060\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "GeoTrust Primary Certification Authority - G3"
|
||||
@@ -7371,7 +7395,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\367\130\077\056\162\002\127\243\217\241\024\056
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Sun Sep 30 00:00:00 2018
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\061\070\060\071\063\060\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "thawte Primary Root CA - G2"
|
||||
@@ -7533,7 +7560,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\061\324\100\032\142\064\066\077\065\001\256\254\143\240
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Tue Apr 30 00:00:00 2019
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\061\071\060\064\063\060\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "thawte Primary Root CA - G3"
|
||||
@@ -7671,7 +7701,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\017\212
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Wed Jan 01 00:00:00 2020
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\062\060\060\061\060\061\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "GeoTrust Primary Certification Authority - G2"
|
||||
@@ -7843,7 +7876,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\354\315\202\141\361\070\346\117\227\230\052\132\215
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Tue Apr 30 00:00:00 2019
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\061\071\060\064\063\060\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "VeriSign Universal Root Certification Authority"
|
||||
@@ -8000,7 +8036,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\055\247\330\206\052\335\056\020
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Thu Jan 31 00:00:00 2019
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\061\071\060\061\063\061\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "VeriSign Class 3 Public Primary Certification Authority - G4"
|
||||
@@ -11580,7 +11619,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\371\210\075\176\270\157\156\003\344\102
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Sat Dec 28 00:00:00 2019
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\061\071\061\062\062\070\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for Certificate "EC-ACC"
|
||||
@@ -12734,7 +12776,10 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\307\314\165\301\226\305\235
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
-CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
+# For Server Distrust After: Fri Sep 01 00:00:00 2017
|
||||
+CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
+\061\067\060\071\060\061\060\060\060\060\060\060\132
|
||||
+END
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for "EE Certification Centre Root CA"
|
||||
@@ -23345,3 +23390,203 @@ CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
+
|
||||
+#
|
||||
+# Certificate "Entrust Root Certification Authority - G4"
|
||||
+#
|
||||
+# Issuer: CN=Entrust Root Certification Authority - G4,OU="(c) 2015 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US
|
||||
+# Serial Number:00:d9:b5:43:7f:af:a9:39:0f:00:00:00:00:55:65:ad:58
|
||||
+# Subject: CN=Entrust Root Certification Authority - G4,OU="(c) 2015 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US
|
||||
+# Not Valid Before: Wed May 27 11:11:16 2015
|
||||
+# Not Valid After : Sun Dec 27 11:41:16 2037
|
||||
+# Fingerprint (SHA-256): DB:35:17:D1:F6:73:2A:2D:5A:B9:7C:53:3E:C7:07:79:EE:32:70:A6:2F:B4:AC:42:38:37:24:60:E6:F0:1E:88
|
||||
+# Fingerprint (SHA1): 14:88:4E:86:26:37:B0:26:AF:59:62:5C:40:77:EC:35:29:BA:96:01
|
||||
+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
+CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
+CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
+CKA_LABEL UTF8 "Entrust Root Certification Authority - G4"
|
||||
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
+CKA_SUBJECT MULTILINE_OCTAL
|
||||
+\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123
|
||||
+\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165
|
||||
+\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004
|
||||
+\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165
|
||||
+\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162
|
||||
+\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051
|
||||
+\040\062\060\061\065\040\105\156\164\162\165\163\164\054\040\111
|
||||
+\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162
|
||||
+\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060
|
||||
+\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040
|
||||
+\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151
|
||||
+\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107
|
||||
+\064
|
||||
+END
|
||||
+CKA_ID UTF8 "0"
|
||||
+CKA_ISSUER MULTILINE_OCTAL
|
||||
+\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123
|
||||
+\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165
|
||||
+\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004
|
||||
+\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165
|
||||
+\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162
|
||||
+\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051
|
||||
+\040\062\060\061\065\040\105\156\164\162\165\163\164\054\040\111
|
||||
+\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162
|
||||
+\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060
|
||||
+\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040
|
||||
+\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151
|
||||
+\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107
|
||||
+\064
|
||||
+END
|
||||
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
+\002\021\000\331\265\103\177\257\251\071\017\000\000\000\000\125
|
||||
+\145\255\130
|
||||
+END
|
||||
+CKA_VALUE MULTILINE_OCTAL
|
||||
+\060\202\006\113\060\202\004\063\240\003\002\001\002\002\021\000
|
||||
+\331\265\103\177\257\251\071\017\000\000\000\000\125\145\255\130
|
||||
+\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
|
||||
+\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123\061
|
||||
+\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165\163
|
||||
+\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004\013
|
||||
+\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165\163
|
||||
+\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162\155
|
||||
+\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051\040
|
||||
+\062\060\061\065\040\105\156\164\162\165\163\164\054\040\111\156
|
||||
+\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162\151
|
||||
+\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060\060
|
||||
+\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040\122
|
||||
+\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151\157
|
||||
+\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107\064
|
||||
+\060\036\027\015\061\065\060\065\062\067\061\061\061\061\061\066
|
||||
+\132\027\015\063\067\061\062\062\067\061\061\064\061\061\066\132
|
||||
+\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123
|
||||
+\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165
|
||||
+\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004
|
||||
+\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165
|
||||
+\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162
|
||||
+\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051
|
||||
+\040\062\060\061\065\040\105\156\164\162\165\163\164\054\040\111
|
||||
+\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162
|
||||
+\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060
|
||||
+\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040
|
||||
+\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151
|
||||
+\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107
|
||||
+\064\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001
|
||||
+\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002
|
||||
+\001\000\261\354\054\102\356\342\321\060\377\245\222\107\342\055
|
||||
+\303\272\144\227\155\312\367\015\265\131\301\263\313\250\150\031
|
||||
+\330\257\204\155\060\160\135\176\363\056\322\123\231\341\376\037
|
||||
+\136\331\110\257\135\023\215\333\377\143\063\115\323\000\002\274
|
||||
+\304\370\321\006\010\224\171\130\212\025\336\051\263\375\375\304
|
||||
+\117\350\252\342\240\073\171\315\277\153\103\062\335\331\164\020
|
||||
+\271\367\364\150\324\273\320\207\325\252\113\212\052\157\052\004
|
||||
+\265\262\246\307\240\172\346\110\253\322\321\131\314\326\176\043
|
||||
+\346\227\154\360\102\345\334\121\113\025\101\355\111\112\311\336
|
||||
+\020\227\326\166\301\357\245\265\066\024\227\065\330\170\042\065
|
||||
+\122\357\103\275\333\047\333\141\126\202\064\334\313\210\140\014
|
||||
+\013\132\345\054\001\306\124\257\327\252\301\020\173\322\005\132
|
||||
+\270\100\236\206\247\303\220\206\002\126\122\011\172\234\322\047
|
||||
+\202\123\112\145\122\152\365\074\347\250\362\234\257\213\275\323
|
||||
+\016\324\324\136\156\207\236\152\075\105\035\321\135\033\364\351
|
||||
+\012\254\140\231\373\211\264\377\230\054\317\174\035\351\002\252
|
||||
+\004\232\036\270\334\210\156\045\263\154\146\367\074\220\363\127
|
||||
+\301\263\057\365\155\362\373\312\241\370\051\235\106\213\263\152
|
||||
+\366\346\147\007\276\054\147\012\052\037\132\262\076\127\304\323
|
||||
+\041\041\143\145\122\221\033\261\231\216\171\176\346\353\215\000
|
||||
+\331\132\252\352\163\350\244\202\002\107\226\376\133\216\124\141
|
||||
+\243\353\057\113\060\260\213\043\165\162\174\041\074\310\366\361
|
||||
+\164\324\034\173\243\005\125\356\273\115\073\062\276\232\167\146
|
||||
+\236\254\151\220\042\007\037\141\072\226\276\345\232\117\314\005
|
||||
+\074\050\131\323\301\014\124\250\131\141\275\310\162\114\350\334
|
||||
+\237\207\177\275\234\110\066\136\225\243\016\271\070\044\125\374
|
||||
+\165\146\353\002\343\010\064\051\112\306\343\053\057\063\240\332
|
||||
+\243\206\245\022\227\375\200\053\332\024\102\343\222\275\076\362
|
||||
+\135\136\147\164\056\034\210\107\051\064\137\342\062\250\234\045
|
||||
+\067\214\272\230\000\227\213\111\226\036\375\045\212\254\334\332
|
||||
+\330\135\164\156\146\260\377\104\337\241\030\306\276\110\057\067
|
||||
+\224\170\370\225\112\077\177\023\136\135\131\375\164\206\103\143
|
||||
+\163\111\002\003\001\000\001\243\102\060\100\060\017\006\003\125
|
||||
+\035\023\001\001\377\004\005\060\003\001\001\377\060\016\006\003
|
||||
+\125\035\017\001\001\377\004\004\003\002\001\006\060\035\006\003
|
||||
+\125\035\016\004\026\004\024\237\070\304\126\043\303\071\350\240
|
||||
+\161\154\350\124\114\344\350\072\261\277\147\060\015\006\011\052
|
||||
+\206\110\206\367\015\001\001\013\005\000\003\202\002\001\000\022
|
||||
+\345\102\246\173\213\017\014\344\106\245\266\140\100\207\214\045
|
||||
+\176\255\270\150\056\133\306\100\166\074\003\370\311\131\364\363
|
||||
+\253\142\316\020\215\264\132\144\214\150\300\260\162\103\064\322
|
||||
+\033\013\366\054\123\322\312\220\113\206\146\374\252\203\042\364
|
||||
+\213\032\157\046\110\254\166\167\010\277\305\230\134\364\046\211
|
||||
+\236\173\303\271\144\062\001\177\323\303\335\130\155\354\261\253
|
||||
+\204\125\164\167\204\004\047\122\153\206\114\316\335\271\145\377
|
||||
+\326\306\136\237\232\020\231\113\165\152\376\152\351\227\040\344
|
||||
+\344\166\172\306\320\044\252\220\315\040\220\272\107\144\373\177
|
||||
+\007\263\123\170\265\012\142\362\163\103\316\101\053\201\152\056
|
||||
+\205\026\224\123\324\153\137\162\042\253\121\055\102\325\000\234
|
||||
+\231\277\336\273\224\073\127\375\232\365\206\313\126\073\133\210
|
||||
+\001\345\174\050\113\003\371\111\203\174\262\177\174\343\355\216
|
||||
+\241\177\140\123\216\125\235\120\064\022\017\267\227\173\154\207
|
||||
+\112\104\347\365\155\354\200\067\360\130\031\156\112\150\166\360
|
||||
+\037\222\344\352\265\222\323\141\121\020\013\255\247\331\137\307
|
||||
+\137\334\037\243\134\214\241\176\233\267\236\323\126\157\146\136
|
||||
+\007\226\040\355\013\164\373\146\116\213\021\025\351\201\111\176
|
||||
+\157\260\324\120\177\042\327\137\145\002\015\246\364\205\036\330
|
||||
+\256\006\113\112\247\322\061\146\302\370\316\345\010\246\244\002
|
||||
+\226\104\150\127\304\325\063\317\031\057\024\304\224\034\173\244
|
||||
+\331\360\237\016\261\200\342\321\236\021\144\251\210\021\072\166
|
||||
+\202\345\142\302\200\330\244\203\355\223\357\174\057\220\260\062
|
||||
+\114\226\025\150\110\122\324\231\010\300\044\350\034\343\263\245
|
||||
+\041\016\222\300\220\037\317\040\137\312\073\070\307\267\155\072
|
||||
+\363\346\104\270\016\061\153\210\216\160\353\234\027\122\250\101
|
||||
+\224\056\207\266\347\246\022\305\165\337\133\300\012\156\173\244
|
||||
+\344\136\206\371\066\224\337\167\303\351\015\300\071\361\171\273
|
||||
+\106\216\253\103\131\047\267\040\273\043\351\126\100\041\354\061
|
||||
+\075\145\252\103\362\075\337\160\104\341\272\115\046\020\073\230
|
||||
+\237\363\310\216\033\070\126\041\152\121\223\323\221\312\106\332
|
||||
+\211\267\075\123\203\054\010\037\213\217\123\335\377\254\037
|
||||
+END
|
||||
+CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
+
|
||||
+# Trust for "Entrust Root Certification Authority - G4"
|
||||
+# Issuer: CN=Entrust Root Certification Authority - G4,OU="(c) 2015 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US
|
||||
+# Serial Number:00:d9:b5:43:7f:af:a9:39:0f:00:00:00:00:55:65:ad:58
|
||||
+# Subject: CN=Entrust Root Certification Authority - G4,OU="(c) 2015 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US
|
||||
+# Not Valid Before: Wed May 27 11:11:16 2015
|
||||
+# Not Valid After : Sun Dec 27 11:41:16 2037
|
||||
+# Fingerprint (SHA-256): DB:35:17:D1:F6:73:2A:2D:5A:B9:7C:53:3E:C7:07:79:EE:32:70:A6:2F:B4:AC:42:38:37:24:60:E6:F0:1E:88
|
||||
+# Fingerprint (SHA1): 14:88:4E:86:26:37:B0:26:AF:59:62:5C:40:77:EC:35:29:BA:96:01
|
||||
+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
+CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
+CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
+CKA_LABEL UTF8 "Entrust Root Certification Authority - G4"
|
||||
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
+\024\210\116\206\046\067\260\046\257\131\142\134\100\167\354\065
|
||||
+\051\272\226\001
|
||||
+END
|
||||
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
+\211\123\361\203\043\267\174\216\005\361\214\161\070\116\037\210
|
||||
+END
|
||||
+CKA_ISSUER MULTILINE_OCTAL
|
||||
+\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123
|
||||
+\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165
|
||||
+\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004
|
||||
+\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165
|
||||
+\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162
|
||||
+\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051
|
||||
+\040\062\060\061\065\040\105\156\164\162\165\163\164\054\040\111
|
||||
+\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162
|
||||
+\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060
|
||||
+\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040
|
||||
+\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151
|
||||
+\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107
|
||||
+\064
|
||||
+END
|
||||
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
+\002\021\000\331\265\103\177\257\251\071\017\000\000\000\000\125
|
||||
+\145\255\130
|
||||
+END
|
||||
+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
@@ -0,0 +1,110 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <samuel.r.attard@gmail.com>
|
||||
Date: Tue, 9 Jun 2020 11:23:55 -0700
|
||||
Subject: win: use RtlGenRandom from advapi32.dll directly
|
||||
|
||||
At least two people have reported that `LoadLibrary("advapi32.dll")`
|
||||
fails in some configurations.
|
||||
|
||||
Libuv already links against advapi32.dll so let's sidestep the issue
|
||||
by linking to `RtlGenRandom()` directly instead of looking it up at
|
||||
runtime.
|
||||
|
||||
Fixes: #2759
|
||||
PR-URL: #2762
|
||||
Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
|
||||
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
|
||||
Reviewed-By: Jameson Nash <vtjnash@gmail.com>
|
||||
|
||||
Cherry-Pick: https://github.com/libuv/libuv/commit/335e8a6d128646e5a19d39dfc677f5a5a555f7cc
|
||||
|
||||
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
|
||||
index 4bbeb3154123ddae1bf8c3dc7c684e9de05ad67d..1ba35bf56d4a6906c241a1fddca2e1ba9464909c 100644
|
||||
--- a/deps/uv/src/win/util.c
|
||||
+++ b/deps/uv/src/win/util.c
|
||||
@@ -63,6 +63,9 @@
|
||||
/* Maximum environment variable size, including the terminating null */
|
||||
#define MAX_ENV_VAR_LENGTH 32767
|
||||
|
||||
+/* A RtlGenRandom() by any other name... */
|
||||
+extern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength);
|
||||
+
|
||||
/* Cached copy of the process title, plus a mutex guarding it. */
|
||||
static char *process_title;
|
||||
static CRITICAL_SECTION process_title_lock;
|
||||
@@ -1862,13 +1865,10 @@ int uv_gettimeofday(uv_timeval64_t* tv) {
|
||||
}
|
||||
|
||||
int uv__random_rtlgenrandom(void* buf, size_t buflen) {
|
||||
- if (pRtlGenRandom == NULL)
|
||||
- return UV_ENOSYS;
|
||||
-
|
||||
if (buflen == 0)
|
||||
return 0;
|
||||
|
||||
- if (pRtlGenRandom(buf, buflen) == FALSE)
|
||||
+ if (SystemFunction036(buf, buflen) == FALSE)
|
||||
return UV_EIO;
|
||||
|
||||
return 0;
|
||||
diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c
|
||||
index 85a9de8a2295ec3250f9ae41f5ef6dbe72dc2a8a..bb86ec8ceac8ba3fccd02b292aca7ddfab38e187 100644
|
||||
--- a/deps/uv/src/win/winapi.c
|
||||
+++ b/deps/uv/src/win/winapi.c
|
||||
@@ -36,9 +36,6 @@ sNtQueryDirectoryFile pNtQueryDirectoryFile;
|
||||
sNtQuerySystemInformation pNtQuerySystemInformation;
|
||||
sNtQueryInformationProcess pNtQueryInformationProcess;
|
||||
|
||||
-/* Advapi32 function pointers */
|
||||
-sRtlGenRandom pRtlGenRandom;
|
||||
-
|
||||
/* Kernel32 function pointers */
|
||||
sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
|
||||
|
||||
@@ -54,7 +51,6 @@ void uv_winapi_init(void) {
|
||||
HMODULE powrprof_module;
|
||||
HMODULE user32_module;
|
||||
HMODULE kernel32_module;
|
||||
- HMODULE advapi32_module;
|
||||
|
||||
ntdll_module = GetModuleHandleA("ntdll.dll");
|
||||
if (ntdll_module == NULL) {
|
||||
@@ -138,12 +134,4 @@ void uv_winapi_init(void) {
|
||||
pSetWinEventHook = (sSetWinEventHook)
|
||||
GetProcAddress(user32_module, "SetWinEventHook");
|
||||
}
|
||||
-
|
||||
- advapi32_module = GetModuleHandleA("advapi32.dll");
|
||||
- if (advapi32_module == NULL) {
|
||||
- uv_fatal_error(GetLastError(), "GetModuleHandleA");
|
||||
- }
|
||||
-
|
||||
- pRtlGenRandom =
|
||||
- (sRtlGenRandom) GetProcAddress(advapi32_module, "SystemFunction036");
|
||||
}
|
||||
diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h
|
||||
index fcc70652a9aedb72f92ce78b8ee21cea8933b905..322a212dd73c19378b7abda01c5b60a93cb8e1d5 100644
|
||||
--- a/deps/uv/src/win/winapi.h
|
||||
+++ b/deps/uv/src/win/winapi.h
|
||||
@@ -4589,11 +4589,6 @@ typedef NTSTATUS (NTAPI *sNtQueryInformationProcess)
|
||||
ULONG Length,
|
||||
PULONG ReturnLength);
|
||||
|
||||
-/*
|
||||
- * Advapi32 headers
|
||||
- */
|
||||
-typedef BOOLEAN (WINAPI *sRtlGenRandom)(PVOID Buffer, ULONG BufferLength);
|
||||
-
|
||||
/*
|
||||
* Kernel32 headers
|
||||
*/
|
||||
@@ -4736,9 +4731,6 @@ extern sNtQueryDirectoryFile pNtQueryDirectoryFile;
|
||||
extern sNtQuerySystemInformation pNtQuerySystemInformation;
|
||||
extern sNtQueryInformationProcess pNtQueryInformationProcess;
|
||||
|
||||
-/* Advapi32 function pointers */
|
||||
-extern sRtlGenRandom pRtlGenRandom;
|
||||
-
|
||||
/* Kernel32 function pointers */
|
||||
extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
|
||||
|
||||
1
patches/pdfium/.patches
Normal file
1
patches/pdfium/.patches
Normal file
@@ -0,0 +1 @@
|
||||
backport_1091404.patch
|
||||
79
patches/pdfium/backport_1091404.patch
Normal file
79
patches/pdfium/backport_1091404.patch
Normal file
@@ -0,0 +1,79 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Wed, 23 Oct 2019 12:54:32 -0700
|
||||
Subject: fix: make PDFium JS host object have immutable prototypes
|
||||
|
||||
[1091404] [High] [CVE-2020-6513]: Google Chrome PDFium Javascript Active Document Memory Corruption Vulnerability - TALOS-2020-1092
|
||||
Backport https://pdfium.googlesource.com/pdfium.git/+/bee2261eab794536f236013fa8c9d01728ed326b.
|
||||
|
||||
diff --git a/fxjs/cfxjs_engine.cpp b/fxjs/cfxjs_engine.cpp
|
||||
index 9624feb2dc91b03f9eb32bab772f235b682cf9a1..4a15ebe11ed7a82ded11ca0de031b8818811143b 100644
|
||||
--- a/fxjs/cfxjs_engine.cpp
|
||||
+++ b/fxjs/cfxjs_engine.cpp
|
||||
@@ -145,6 +145,7 @@ class CFXJS_ObjDefinition {
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::FunctionTemplate> fn = v8::FunctionTemplate::New(isolate);
|
||||
fn->InstanceTemplate()->SetInternalFieldCount(2);
|
||||
+ fn->InstanceTemplate()->SetImmutableProto();
|
||||
fn->SetCallHandler(CallHandler, v8::Number::New(isolate, eObjType));
|
||||
if (eObjType == FXJSOBJTYPE_GLOBAL) {
|
||||
fn->InstanceTemplate()->Set(v8::Symbol::GetToStringTag(isolate),
|
||||
diff --git a/testing/resources/javascript/immutable_proto.in b/testing/resources/javascript/immutable_proto.in
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..61885c53758167cae5af47f8736014dcb0933aaf
|
||||
--- /dev/null
|
||||
+++ b/testing/resources/javascript/immutable_proto.in
|
||||
@@ -0,0 +1,43 @@
|
||||
+{{header}}
|
||||
+{{object 1 0}} <<
|
||||
+ /Type /Catalog
|
||||
+ /Pages 2 0 R
|
||||
+ /OpenAction 10 0 R
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 2 0}} <<
|
||||
+ /Type /Pages
|
||||
+ /Count 1
|
||||
+ /Kids [
|
||||
+ 3 0 R
|
||||
+ ]
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 3 0}} <<
|
||||
+ /Type /Page
|
||||
+ /Parent 2 0 R
|
||||
+ /MediaBox [0 0 612 792]
|
||||
+>>
|
||||
+endobj
|
||||
+% OpenAction action
|
||||
+{{object 10 0}} <<
|
||||
+ /Type /Action
|
||||
+ /S /JavaScript
|
||||
+ /JS 11 0 R
|
||||
+>>
|
||||
+endobj
|
||||
+{{object 11 0}} <<
|
||||
+ {{streamlen}}
|
||||
+>>
|
||||
+stream
|
||||
+{{include expect.js}}
|
||||
+expect("this.__proto__", "[object Object]");
|
||||
+expect("app.__proto__", "[object Object]");
|
||||
+expectError("this.__proto__ = {}");
|
||||
+expectError("app.__proto__ = this");
|
||||
+endstream
|
||||
+endobj
|
||||
+{{xref}}
|
||||
+{{trailer}}
|
||||
+{{startxref}}
|
||||
+%%EOF
|
||||
diff --git a/testing/resources/javascript/immutable_proto_expected.txt b/testing/resources/javascript/immutable_proto_expected.txt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7e7c6701e39592ec130ae52fc98f8af903b3152b
|
||||
--- /dev/null
|
||||
+++ b/testing/resources/javascript/immutable_proto_expected.txt
|
||||
@@ -0,0 +1,4 @@
|
||||
+Alert: PASS: this.__proto__ = [object Object]
|
||||
+Alert: PASS: app.__proto__ = [object Object]
|
||||
+Alert: PASS: this.__proto__ = {} threw TypeError: Immutable prototype object '[object global]' cannot have their prototype set
|
||||
+Alert: PASS: app.__proto__ = this threw TypeError: Immutable prototype object '[object Object]' cannot have their prototype set
|
||||
1
patches/skia/.patches
Normal file
1
patches/skia/.patches
Normal file
@@ -0,0 +1 @@
|
||||
backport_1080481.patch
|
||||
88
patches/skia/backport_1080481.patch
Normal file
88
patches/skia/backport_1080481.patch
Normal file
@@ -0,0 +1,88 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: drop SkTextBlobs with > 2M glyphs
|
||||
|
||||
[1080481] [Medium] [CVE-2020-6523]: Security: Skia: Integer Overflow in GrTextBlob::Make
|
||||
Backport https://skia.googlesource.com/skia.git/+/8d2ebfffaf6ece9a7e9839dca2d7907f241c3460
|
||||
|
||||
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
|
||||
index 31dfff18337c260c5905f1e1843a1cc27ebead5b..0e145b998f81be223cc7256ca402cbb8d384f7f5 100644
|
||||
--- a/src/core/SkCanvas.cpp
|
||||
+++ b/src/core/SkCanvas.cpp
|
||||
@@ -2654,6 +2654,19 @@ void SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
TRACE_EVENT0("skia", TRACE_FUNC);
|
||||
RETURN_ON_NULL(blob);
|
||||
RETURN_ON_FALSE(blob->bounds().makeOffset(x, y).isFinite());
|
||||
+
|
||||
+ // Overflow if more than 2^21 glyphs stopping a buffer overflow latter in the stack.
|
||||
+ // See chromium:1080481
|
||||
+ // TODO: can consider unrolling a few at a time if this limit becomes a problem.
|
||||
+ int totalGlyphCount = 0;
|
||||
+ constexpr int kMaxGlyphCount = 1 << 21;
|
||||
+ SkTextBlob::Iter i(*blob);
|
||||
+ SkTextBlob::Iter::Run r;
|
||||
+ while (i.next(&r)) {
|
||||
+ int glyphsLeft = kMaxGlyphCount - totalGlyphCount;
|
||||
+ RETURN_ON_FALSE(r.fGlyphCount <= glyphsLeft);
|
||||
+ totalGlyphCount += r.fGlyphCount;
|
||||
+ }
|
||||
this->onDrawTextBlob(blob, x, y, paint);
|
||||
}
|
||||
|
||||
diff --git a/tests/TextBlobCacheTest.cpp b/tests/TextBlobCacheTest.cpp
|
||||
index 536b2c1273eeef0eac0e2018d5d438687832203d..c0cdcfebdd96d210112835fee0ae63d69312105b 100644
|
||||
--- a/tests/TextBlobCacheTest.cpp
|
||||
+++ b/tests/TextBlobCacheTest.cpp
|
||||
@@ -229,6 +229,51 @@ static sk_sp<SkTextBlob> make_blob() {
|
||||
return builder.make();
|
||||
}
|
||||
|
||||
+// Turned off to pass on android and ios devices, which were running out of memory..
|
||||
+#if 0
|
||||
+static sk_sp<SkTextBlob> make_large_blob() {
|
||||
+ auto tf = SkTypeface::MakeFromName("Roboto2-Regular", SkFontStyle());
|
||||
+ SkFont font;
|
||||
+ font.setTypeface(tf);
|
||||
+ font.setSubpixel(false);
|
||||
+ font.setEdging(SkFont::Edging::kAlias);
|
||||
+ font.setSize(24);
|
||||
+
|
||||
+ const int mallocSize = 0x3c3c3bd; // x86 size
|
||||
+ std::unique_ptr<char[]> text{new char[mallocSize + 1]};
|
||||
+ if (text == nullptr) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ for (int i = 0; i < mallocSize; i++) {
|
||||
+ text[i] = 'x';
|
||||
+ }
|
||||
+ text[mallocSize] = 0;
|
||||
+
|
||||
+ static const int maxGlyphLen = mallocSize;
|
||||
+ std::unique_ptr<SkGlyphID[]> glyphs{new SkGlyphID[maxGlyphLen]};
|
||||
+ int glyphCount =
|
||||
+ font.textToGlyphs(
|
||||
+ text.get(), mallocSize, SkTextEncoding::kUTF8, glyphs.get(), maxGlyphLen);
|
||||
+ SkTextBlobBuilder builder;
|
||||
+ const auto& runBuffer = builder.allocRun(font, glyphCount, 0, 0);
|
||||
+ for (int i = 0; i < glyphCount; i++) {
|
||||
+ runBuffer.glyphs[i] = glyphs[i];
|
||||
+ }
|
||||
+ return builder.make();
|
||||
+}
|
||||
+
|
||||
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(TextBlobIntegerOverflowTest, reporter, ctxInfo) {
|
||||
+ auto grContext = ctxInfo.grContext();
|
||||
+ const SkImageInfo info =
|
||||
+ SkImageInfo::Make(kScreenDim, kScreenDim, kN32_SkColorType, kPremul_SkAlphaType);
|
||||
+ auto surface = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kNo, info);
|
||||
+
|
||||
+ auto blob = make_large_blob();
|
||||
+ int y = 40;
|
||||
+ SkBitmap base = draw_blob(blob.get(), surface.get(), {40, y + 0.0f});
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static const bool kDumpPngs = true;
|
||||
// dump pngs needs a "good" and a "bad" directory to put the results in. This allows the use of the
|
||||
// skdiff tool to visualize the differences.
|
||||
@@ -7,3 +7,5 @@ workaround_an_undefined_symbol_error.patch
|
||||
do_not_export_private_v8_symbols_on_windows.patch
|
||||
revert_cleanup_switch_offset_of_to_offsetof_where_possible.patch
|
||||
fix_build_deprecated_attirbute_for_older_msvc_versions.patch
|
||||
backport_1084820.patch
|
||||
backport_986051.patch
|
||||
|
||||
770
patches/v8/backport_1084820.patch
Normal file
770
patches/v8/backport_1084820.patch
Normal file
@@ -0,0 +1,770 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: object materialization
|
||||
|
||||
[1084820] [High] [CVE-2020-6512]: DCHECK failure in value.IsHeapObject() in objects-debug.cc
|
||||
Backport https://chromium.googlesource.com/v8/v8.git/+/c16f62d6e943756d8b4170a36f61e666ced82e6d
|
||||
|
||||
diff --git a/src/deoptimizer/deoptimizer.cc b/src/deoptimizer/deoptimizer.cc
|
||||
index 9fcccd483c6a10a42a217c61d7ef60f50b3e4f07..44c92f557046dbb4268b218d0753367356ee9cd3 100644
|
||||
--- a/src/deoptimizer/deoptimizer.cc
|
||||
+++ b/src/deoptimizer/deoptimizer.cc
|
||||
@@ -48,7 +48,6 @@ class FrameWriter {
|
||||
|
||||
void PushRawValue(intptr_t value, const char* debug_hint) {
|
||||
PushValue(value);
|
||||
-
|
||||
if (trace_scope_ != nullptr) {
|
||||
DebugPrintOutputValue(value, debug_hint);
|
||||
}
|
||||
@@ -83,13 +82,10 @@ class FrameWriter {
|
||||
void PushTranslatedValue(const TranslatedFrame::iterator& iterator,
|
||||
const char* debug_hint = "") {
|
||||
Object obj = iterator->GetRawValue();
|
||||
-
|
||||
PushRawObject(obj, debug_hint);
|
||||
-
|
||||
if (trace_scope_) {
|
||||
PrintF(trace_scope_->file(), " (input #%d)\n", iterator.input_index());
|
||||
}
|
||||
-
|
||||
deoptimizer_->QueueValueForMaterialization(output_address(top_offset_), obj,
|
||||
iterator);
|
||||
}
|
||||
@@ -2428,6 +2424,11 @@ int TranslatedValue::object_index() const {
|
||||
Object TranslatedValue::GetRawValue() const {
|
||||
// If we have a value, return it.
|
||||
if (materialization_state() == kFinished) {
|
||||
+ int smi;
|
||||
+ if (storage_->IsHeapNumber() &&
|
||||
+ DoubleToSmiInteger(storage_->Number(), &smi)) {
|
||||
+ return Smi::FromInt(smi);
|
||||
+ }
|
||||
return *storage_;
|
||||
}
|
||||
|
||||
@@ -2470,6 +2471,22 @@ Object TranslatedValue::GetRawValue() const {
|
||||
}
|
||||
}
|
||||
|
||||
+ case kFloat: {
|
||||
+ int smi;
|
||||
+ if (DoubleToSmiInteger(float_value().get_scalar(), &smi)) {
|
||||
+ return Smi::FromInt(smi);
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ case kDouble: {
|
||||
+ int smi;
|
||||
+ if (DoubleToSmiInteger(double_value().get_scalar(), &smi)) {
|
||||
+ return Smi::FromInt(smi);
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2479,106 +2496,76 @@ Object TranslatedValue::GetRawValue() const {
|
||||
return ReadOnlyRoots(isolate()).arguments_marker();
|
||||
}
|
||||
|
||||
-void TranslatedValue::set_initialized_storage(Handle<Object> storage) {
|
||||
+void TranslatedValue::set_initialized_storage(Handle<HeapObject> storage) {
|
||||
DCHECK_EQ(kUninitialized, materialization_state());
|
||||
storage_ = storage;
|
||||
materialization_state_ = kFinished;
|
||||
}
|
||||
|
||||
Handle<Object> TranslatedValue::GetValue() {
|
||||
- // If we already have a value, then get it.
|
||||
- if (materialization_state() == kFinished) return storage_;
|
||||
-
|
||||
- // Otherwise we have to materialize.
|
||||
- switch (kind()) {
|
||||
- case TranslatedValue::kTagged:
|
||||
- case TranslatedValue::kInt32:
|
||||
- case TranslatedValue::kInt64:
|
||||
- case TranslatedValue::kUInt32:
|
||||
- case TranslatedValue::kBoolBit:
|
||||
- case TranslatedValue::kFloat:
|
||||
- case TranslatedValue::kDouble: {
|
||||
- MaterializeSimple();
|
||||
- return storage_;
|
||||
- }
|
||||
-
|
||||
- case TranslatedValue::kCapturedObject:
|
||||
- case TranslatedValue::kDuplicatedObject: {
|
||||
- // We need to materialize the object (or possibly even object graphs).
|
||||
- // To make the object verifier happy, we materialize in two steps.
|
||||
-
|
||||
- // 1. Allocate storage for reachable objects. This makes sure that for
|
||||
- // each object we have allocated space on heap. The space will be
|
||||
- // a byte array that will be later initialized, or a fully
|
||||
- // initialized object if it is safe to allocate one that will
|
||||
- // pass the verifier.
|
||||
- container_->EnsureObjectAllocatedAt(this);
|
||||
-
|
||||
- // 2. Initialize the objects. If we have allocated only byte arrays
|
||||
- // for some objects, we now overwrite the byte arrays with the
|
||||
- // correct object fields. Note that this phase does not allocate
|
||||
- // any new objects, so it does not trigger the object verifier.
|
||||
- return container_->InitializeObjectAt(this);
|
||||
- }
|
||||
-
|
||||
- case TranslatedValue::kInvalid:
|
||||
- FATAL("unexpected case");
|
||||
- return Handle<Object>::null();
|
||||
+ Handle<Object> value(GetRawValue(), isolate());
|
||||
+ if (materialization_state() == kFinished) return value;
|
||||
+
|
||||
+ if (value->IsSmi()) {
|
||||
+ // Even though stored as a Smi, this number might instead be needed as a
|
||||
+ // HeapNumber when materializing a JSObject with a field of HeapObject
|
||||
+ // representation. Since we don't have this information available here, we
|
||||
+ // just always allocate a HeapNumber and later extract the Smi again if we
|
||||
+ // don't need a HeapObject.
|
||||
+ set_initialized_storage(
|
||||
+ isolate()->factory()->NewHeapNumber(value->Number()));
|
||||
+ return value;
|
||||
}
|
||||
|
||||
- FATAL("internal error: value missing");
|
||||
- return Handle<Object>::null();
|
||||
-}
|
||||
-
|
||||
-void TranslatedValue::MaterializeSimple() {
|
||||
- // If we already have materialized, return.
|
||||
- if (materialization_state() == kFinished) return;
|
||||
-
|
||||
- Object raw_value = GetRawValue();
|
||||
- if (raw_value != ReadOnlyRoots(isolate()).arguments_marker()) {
|
||||
- // We can get the value without allocation, just return it here.
|
||||
- set_initialized_storage(Handle<Object>(raw_value, isolate()));
|
||||
- return;
|
||||
+ if (*value != ReadOnlyRoots(isolate()).arguments_marker()) {
|
||||
+ set_initialized_storage(Handle<HeapObject>::cast(value));
|
||||
+ return storage_;
|
||||
}
|
||||
|
||||
- switch (kind()) {
|
||||
- case kInt32:
|
||||
- set_initialized_storage(
|
||||
- Handle<Object>(isolate()->factory()->NewNumber(int32_value())));
|
||||
- return;
|
||||
+ // Otherwise we have to materialize.
|
||||
|
||||
- case kInt64:
|
||||
- set_initialized_storage(Handle<Object>(
|
||||
- isolate()->factory()->NewNumber(static_cast<double>(int64_value()))));
|
||||
- return;
|
||||
+ if (kind() == TranslatedValue::kCapturedObject ||
|
||||
+ kind() == TranslatedValue::kDuplicatedObject) {
|
||||
+ // We need to materialize the object (or possibly even object graphs).
|
||||
+ // To make the object verifier happy, we materialize in two steps.
|
||||
|
||||
- case kUInt32:
|
||||
- set_initialized_storage(
|
||||
- Handle<Object>(isolate()->factory()->NewNumber(uint32_value())));
|
||||
- return;
|
||||
+ // 1. Allocate storage for reachable objects. This makes sure that for
|
||||
+ // each object we have allocated space on heap. The space will be
|
||||
+ // a byte array that will be later initialized, or a fully
|
||||
+ // initialized object if it is safe to allocate one that will
|
||||
+ // pass the verifier.
|
||||
+ container_->EnsureObjectAllocatedAt(this);
|
||||
|
||||
- case kFloat: {
|
||||
- double scalar_value = float_value().get_scalar();
|
||||
- set_initialized_storage(
|
||||
- Handle<Object>(isolate()->factory()->NewNumber(scalar_value)));
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- case kDouble: {
|
||||
- double scalar_value = double_value().get_scalar();
|
||||
- set_initialized_storage(
|
||||
- Handle<Object>(isolate()->factory()->NewNumber(scalar_value)));
|
||||
- return;
|
||||
- }
|
||||
+ // 2. Initialize the objects. If we have allocated only byte arrays
|
||||
+ // for some objects, we now overwrite the byte arrays with the
|
||||
+ // correct object fields. Note that this phase does not allocate
|
||||
+ // any new objects, so it does not trigger the object verifier.
|
||||
+ return container_->InitializeObjectAt(this);
|
||||
+ }
|
||||
|
||||
- case kCapturedObject:
|
||||
- case kDuplicatedObject:
|
||||
- case kInvalid:
|
||||
- case kTagged:
|
||||
- case kBoolBit:
|
||||
- FATAL("internal error: unexpected materialization.");
|
||||
+ double number;
|
||||
+ switch (kind()) {
|
||||
+ case TranslatedValue::kInt32:
|
||||
+ number = int32_value();
|
||||
+ break;
|
||||
+ case TranslatedValue::kInt64:
|
||||
+ number = int64_value();
|
||||
+ break;
|
||||
+ case TranslatedValue::kUInt32:
|
||||
+ number = uint32_value();
|
||||
+ break;
|
||||
+ case TranslatedValue::kFloat:
|
||||
+ number = float_value().get_scalar();
|
||||
break;
|
||||
+ case TranslatedValue::kDouble:
|
||||
+ number = double_value().get_scalar();
|
||||
+ break;
|
||||
+ default:
|
||||
+ UNREACHABLE();
|
||||
}
|
||||
+ DCHECK(!IsSmiDouble(number));
|
||||
+ set_initialized_storage(isolate()->factory()->NewHeapNumber(number));
|
||||
+ return storage_;
|
||||
}
|
||||
|
||||
bool TranslatedValue::IsMaterializedObject() const {
|
||||
@@ -2634,8 +2621,9 @@ Float64 TranslatedState::GetDoubleSlot(Address fp, int slot_offset) {
|
||||
}
|
||||
|
||||
void TranslatedValue::Handlify() {
|
||||
- if (kind() == kTagged) {
|
||||
- set_initialized_storage(Handle<Object>(raw_literal(), isolate()));
|
||||
+ if (kind() == kTagged && raw_literal().IsHeapObject()) {
|
||||
+ set_initialized_storage(
|
||||
+ Handle<HeapObject>(HeapObject::cast(raw_literal()), isolate()));
|
||||
raw_literal_ = Object();
|
||||
}
|
||||
}
|
||||
@@ -3386,7 +3374,7 @@ TranslatedValue* TranslatedState::GetValueByObjectIndex(int object_index) {
|
||||
return &(frames_[pos.frame_index_].values_[pos.value_index_]);
|
||||
}
|
||||
|
||||
-Handle<Object> TranslatedState::InitializeObjectAt(TranslatedValue* slot) {
|
||||
+Handle<HeapObject> TranslatedState::InitializeObjectAt(TranslatedValue* slot) {
|
||||
slot = ResolveCapturedObject(slot);
|
||||
|
||||
DisallowHeapAllocation no_allocation;
|
||||
@@ -3401,7 +3389,7 @@ Handle<Object> TranslatedState::InitializeObjectAt(TranslatedValue* slot) {
|
||||
InitializeCapturedObjectAt(index, &worklist, no_allocation);
|
||||
}
|
||||
}
|
||||
- return slot->GetStorage();
|
||||
+ return slot->storage();
|
||||
}
|
||||
|
||||
void TranslatedState::InitializeCapturedObjectAt(
|
||||
@@ -3501,11 +3489,17 @@ void TranslatedState::EnsureObjectAllocatedAt(TranslatedValue* slot) {
|
||||
}
|
||||
}
|
||||
|
||||
+int TranslatedValue::GetSmiValue() const {
|
||||
+ Object value = GetRawValue();
|
||||
+ CHECK(value.IsSmi());
|
||||
+ return Smi::cast(value).value();
|
||||
+}
|
||||
+
|
||||
void TranslatedState::MaterializeFixedDoubleArray(TranslatedFrame* frame,
|
||||
int* value_index,
|
||||
TranslatedValue* slot,
|
||||
Handle<Map> map) {
|
||||
- int length = Smi::cast(frame->values_[*value_index].GetRawValue()).value();
|
||||
+ int length = frame->values_[*value_index].GetSmiValue();
|
||||
(*value_index)++;
|
||||
Handle<FixedDoubleArray> array = Handle<FixedDoubleArray>::cast(
|
||||
isolate()->factory()->NewFixedDoubleArray(length));
|
||||
@@ -3539,10 +3533,10 @@ void TranslatedState::MaterializeHeapNumber(TranslatedFrame* frame,
|
||||
|
||||
namespace {
|
||||
|
||||
-enum DoubleStorageKind : uint8_t {
|
||||
+enum StorageKind : uint8_t {
|
||||
kStoreTagged,
|
||||
kStoreUnboxedDouble,
|
||||
- kStoreMutableHeapNumber,
|
||||
+ kStoreHeapObject
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -3614,9 +3608,7 @@ void TranslatedState::EnsureCapturedObjectAllocatedAt(
|
||||
case SIMPLE_NUMBER_DICTIONARY_TYPE:
|
||||
case STRING_TABLE_TYPE: {
|
||||
// Check we have the right size.
|
||||
- int array_length =
|
||||
- Smi::cast(frame->values_[value_index].GetRawValue()).value();
|
||||
-
|
||||
+ int array_length = frame->values_[value_index].GetSmiValue();
|
||||
int instance_size = FixedArray::SizeFor(array_length);
|
||||
CHECK_EQ(instance_size, slot->GetChildrenCount() * kTaggedSize);
|
||||
|
||||
@@ -3635,13 +3627,13 @@ void TranslatedState::EnsureCapturedObjectAllocatedAt(
|
||||
|
||||
case PROPERTY_ARRAY_TYPE: {
|
||||
// Check we have the right size.
|
||||
- int length_or_hash =
|
||||
- Smi::cast(frame->values_[value_index].GetRawValue()).value();
|
||||
+ int length_or_hash = frame->values_[value_index].GetSmiValue();
|
||||
int array_length = PropertyArray::LengthField::decode(length_or_hash);
|
||||
int instance_size = PropertyArray::SizeFor(array_length);
|
||||
CHECK_EQ(instance_size, slot->GetChildrenCount() * kTaggedSize);
|
||||
|
||||
slot->set_storage(AllocateStorageFor(slot));
|
||||
+
|
||||
// Make sure all the remaining children (after the map) are allocated.
|
||||
return EnsureChildrenAllocated(slot->GetChildrenCount() - 1, frame,
|
||||
&value_index, worklist);
|
||||
@@ -3686,7 +3678,7 @@ void TranslatedState::EnsureChildrenAllocated(int count, TranslatedFrame* frame,
|
||||
} else {
|
||||
// Make sure the simple values (heap numbers, etc.) are properly
|
||||
// initialized.
|
||||
- child_slot->MaterializeSimple();
|
||||
+ child_slot->GetValue();
|
||||
}
|
||||
SkipSlots(1, frame, value_index);
|
||||
}
|
||||
@@ -3701,16 +3693,17 @@ void TranslatedState::EnsurePropertiesAllocatedAndMarked(
|
||||
properties_slot->mark_allocated();
|
||||
properties_slot->set_storage(object_storage);
|
||||
|
||||
- // Set markers for the double properties.
|
||||
+ // Set markers for out-of-object properties.
|
||||
Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate());
|
||||
for (InternalIndex i : map->IterateOwnDescriptors()) {
|
||||
FieldIndex index = FieldIndex::ForDescriptor(*map, i);
|
||||
- if (descriptors->GetDetails(i).representation().IsDouble() &&
|
||||
- !index.is_inobject()) {
|
||||
+ Representation representation = descriptors->GetDetails(i).representation();
|
||||
+ if (!index.is_inobject() &&
|
||||
+ (representation.IsDouble() || representation.IsHeapObject())) {
|
||||
CHECK(!map->IsUnboxedDoubleField(index));
|
||||
int outobject_index = index.outobject_array_index();
|
||||
int array_index = outobject_index * kTaggedSize;
|
||||
- object_storage->set(array_index, kStoreMutableHeapNumber);
|
||||
+ object_storage->set(array_index, kStoreHeapObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3736,31 +3729,44 @@ void TranslatedState::EnsureJSObjectAllocated(TranslatedValue* slot,
|
||||
// Now we handle the interesting (JSObject) case.
|
||||
Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate());
|
||||
|
||||
- // Set markers for the double properties.
|
||||
+ // Set markers for in-object properties.
|
||||
for (InternalIndex i : map->IterateOwnDescriptors()) {
|
||||
FieldIndex index = FieldIndex::ForDescriptor(*map, i);
|
||||
- if (descriptors->GetDetails(i).representation().IsDouble() &&
|
||||
- index.is_inobject()) {
|
||||
+ Representation representation = descriptors->GetDetails(i).representation();
|
||||
+ if (index.is_inobject() &&
|
||||
+ (representation.IsDouble() || representation.IsHeapObject())) {
|
||||
CHECK_GE(index.index(), FixedArray::kHeaderSize / kTaggedSize);
|
||||
int array_index = index.index() * kTaggedSize - FixedArray::kHeaderSize;
|
||||
- uint8_t marker = map->IsUnboxedDoubleField(index)
|
||||
- ? kStoreUnboxedDouble
|
||||
- : kStoreMutableHeapNumber;
|
||||
+ uint8_t marker = map->IsUnboxedDoubleField(index) ? kStoreUnboxedDouble
|
||||
+ : kStoreHeapObject;
|
||||
object_storage->set(array_index, marker);
|
||||
}
|
||||
}
|
||||
slot->set_storage(object_storage);
|
||||
}
|
||||
|
||||
-Handle<Object> TranslatedState::GetValueAndAdvance(TranslatedFrame* frame,
|
||||
- int* value_index) {
|
||||
- TranslatedValue* slot = frame->ValueAt(*value_index);
|
||||
- SkipSlots(1, frame, value_index);
|
||||
+TranslatedValue* TranslatedState::GetResolvedSlot(TranslatedFrame* frame,
|
||||
+ int value_index) {
|
||||
+ TranslatedValue* slot = frame->ValueAt(value_index);
|
||||
if (slot->kind() == TranslatedValue::kDuplicatedObject) {
|
||||
slot = ResolveCapturedObject(slot);
|
||||
}
|
||||
- CHECK_NE(TranslatedValue::kUninitialized, slot->materialization_state());
|
||||
- return slot->GetStorage();
|
||||
+ CHECK_NE(slot->materialization_state(), TranslatedValue::kUninitialized);
|
||||
+ return slot;
|
||||
+}
|
||||
+
|
||||
+TranslatedValue* TranslatedState::GetResolvedSlotAndAdvance(
|
||||
+ TranslatedFrame* frame, int* value_index) {
|
||||
+ TranslatedValue* slot = GetResolvedSlot(frame, *value_index);
|
||||
+ SkipSlots(1, frame, value_index);
|
||||
+ return slot;
|
||||
+}
|
||||
+
|
||||
+Handle<Object> TranslatedState::GetValueAndAdvance(TranslatedFrame* frame,
|
||||
+ int* value_index) {
|
||||
+ TranslatedValue* slot = GetResolvedSlot(frame, *value_index);
|
||||
+ SkipSlots(1, frame, value_index);
|
||||
+ return slot->GetValue();
|
||||
}
|
||||
|
||||
void TranslatedState::InitializeJSObjectAt(
|
||||
@@ -3788,29 +3794,25 @@ void TranslatedState::InitializeJSObjectAt(
|
||||
// marker to see if we store an unboxed double.
|
||||
DCHECK_EQ(kTaggedSize, JSObject::kPropertiesOrHashOffset);
|
||||
for (int i = 2; i < slot->GetChildrenCount(); i++) {
|
||||
- // Initialize and extract the value from its slot.
|
||||
- Handle<Object> field_value = GetValueAndAdvance(frame, value_index);
|
||||
-
|
||||
+ TranslatedValue* slot = GetResolvedSlotAndAdvance(frame, value_index);
|
||||
// Read out the marker and ensure the field is consistent with
|
||||
// what the markers in the storage say (note that all heap numbers
|
||||
// should be fully initialized by now).
|
||||
int offset = i * kTaggedSize;
|
||||
uint8_t marker = object_storage->ReadField<uint8_t>(offset);
|
||||
if (marker == kStoreUnboxedDouble) {
|
||||
- double double_field_value;
|
||||
- if (field_value->IsSmi()) {
|
||||
- double_field_value = Smi::cast(*field_value).value();
|
||||
- } else {
|
||||
- CHECK(field_value->IsHeapNumber());
|
||||
- double_field_value = HeapNumber::cast(*field_value).value();
|
||||
- }
|
||||
- object_storage->WriteField<double>(offset, double_field_value);
|
||||
- } else if (marker == kStoreMutableHeapNumber) {
|
||||
+ Handle<HeapObject> field_value = slot->storage();
|
||||
CHECK(field_value->IsHeapNumber());
|
||||
+ object_storage->WriteField<double>(offset, field_value->Number());
|
||||
+ } else if (marker == kStoreHeapObject) {
|
||||
+ Handle<HeapObject> field_value = slot->storage();
|
||||
WRITE_FIELD(*object_storage, offset, *field_value);
|
||||
WRITE_BARRIER(*object_storage, offset, *field_value);
|
||||
} else {
|
||||
CHECK_EQ(kStoreTagged, marker);
|
||||
+ Handle<Object> field_value = slot->GetValue();
|
||||
+ DCHECK_IMPLIES(field_value->IsHeapNumber(),
|
||||
+ !IsSmiDouble(field_value->Number()));
|
||||
WRITE_FIELD(*object_storage, offset, *field_value);
|
||||
WRITE_BARRIER(*object_storage, offset, *field_value);
|
||||
}
|
||||
@@ -3836,15 +3838,18 @@ void TranslatedState::InitializeObjectWithTaggedFieldsAt(
|
||||
|
||||
// Write the fields to the object.
|
||||
for (int i = 1; i < slot->GetChildrenCount(); i++) {
|
||||
- Handle<Object> field_value = GetValueAndAdvance(frame, value_index);
|
||||
+ TranslatedValue* slot = GetResolvedSlotAndAdvance(frame, value_index);
|
||||
int offset = i * kTaggedSize;
|
||||
uint8_t marker = object_storage->ReadField<uint8_t>(offset);
|
||||
- if (i > 1 && marker == kStoreMutableHeapNumber) {
|
||||
- CHECK(field_value->IsHeapNumber());
|
||||
+ Handle<Object> field_value;
|
||||
+ if (i > 1 && marker == kStoreHeapObject) {
|
||||
+ field_value = slot->storage();
|
||||
} else {
|
||||
CHECK(marker == kStoreTagged || i == 1);
|
||||
+ field_value = slot->GetValue();
|
||||
+ DCHECK_IMPLIES(field_value->IsHeapNumber(),
|
||||
+ !IsSmiDouble(field_value->Number()));
|
||||
}
|
||||
-
|
||||
WRITE_FIELD(*object_storage, offset, *field_value);
|
||||
WRITE_BARRIER(*object_storage, offset, *field_value);
|
||||
}
|
||||
@@ -3911,10 +3916,7 @@ TranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex(
|
||||
// argument (the receiver).
|
||||
static constexpr int kTheContext = 1;
|
||||
const int height = frames_[i].height() + kTheContext;
|
||||
- Object argc_object = frames_[i].ValueAt(height - 1)->GetRawValue();
|
||||
- CHECK(argc_object.IsSmi());
|
||||
- *args_count = Smi::ToInt(argc_object);
|
||||
-
|
||||
+ *args_count = frames_[i].ValueAt(height - 1)->GetSmiValue();
|
||||
DCHECK_EQ(*args_count, 1);
|
||||
} else {
|
||||
*args_count = InternalFormalParameterCountWithReceiver(
|
||||
@@ -3956,21 +3958,30 @@ void TranslatedState::StoreMaterializedValuesAndDeopt(JavaScriptFrame* frame) {
|
||||
|
||||
CHECK(value_info->IsMaterializedObject());
|
||||
|
||||
- // Skip duplicate objects (i.e., those that point to some
|
||||
- // other object id).
|
||||
+ // Skip duplicate objects (i.e., those that point to some other object id).
|
||||
if (value_info->object_index() != i) continue;
|
||||
|
||||
+ Handle<Object> previous_value(previously_materialized_objects->get(i),
|
||||
+ isolate_);
|
||||
Handle<Object> value(value_info->GetRawValue(), isolate_);
|
||||
|
||||
- if (!value.is_identical_to(marker)) {
|
||||
- if (previously_materialized_objects->get(i) == *marker) {
|
||||
+ if (value.is_identical_to(marker)) {
|
||||
+ DCHECK_EQ(*previous_value, *marker);
|
||||
+ } else {
|
||||
+ if (*previous_value == *marker) {
|
||||
+ if (value->IsSmi()) {
|
||||
+ value = isolate()->factory()->NewHeapNumber(value->Number());
|
||||
+ }
|
||||
previously_materialized_objects->set(i, *value);
|
||||
value_changed = true;
|
||||
} else {
|
||||
- CHECK(previously_materialized_objects->get(i) == *value);
|
||||
+ CHECK(*previous_value == *value ||
|
||||
+ (previous_value->IsHeapNumber() && value->IsSmi() &&
|
||||
+ previous_value->Number() == value->Number()));
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
if (new_store && value_changed) {
|
||||
materialized_store->Set(stack_frame_pointer_,
|
||||
previously_materialized_objects);
|
||||
@@ -4004,8 +4015,10 @@ void TranslatedState::UpdateFromPreviouslyMaterializedObjects() {
|
||||
CHECK(value_info->IsMaterializedObject());
|
||||
|
||||
if (value_info->kind() == TranslatedValue::kCapturedObject) {
|
||||
- value_info->set_initialized_storage(
|
||||
- Handle<Object>(previously_materialized_objects->get(i), isolate_));
|
||||
+ Handle<Object> object(previously_materialized_objects->get(i),
|
||||
+ isolate_);
|
||||
+ CHECK(object->IsHeapObject());
|
||||
+ value_info->set_initialized_storage(Handle<HeapObject>::cast(object));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4019,7 +4032,7 @@ void TranslatedState::VerifyMaterializedObjects() {
|
||||
if (slot->kind() == TranslatedValue::kCapturedObject) {
|
||||
CHECK_EQ(slot, GetValueByObjectIndex(slot->object_index()));
|
||||
if (slot->materialization_state() == TranslatedValue::kFinished) {
|
||||
- slot->GetStorage()->ObjectVerify(isolate());
|
||||
+ slot->storage()->ObjectVerify(isolate());
|
||||
} else {
|
||||
CHECK_EQ(slot->materialization_state(),
|
||||
TranslatedValue::kUninitialized);
|
||||
diff --git a/src/deoptimizer/deoptimizer.h b/src/deoptimizer/deoptimizer.h
|
||||
index 2766ed7c6381a279d6161c058ea33fffe9860426..6c68ea1f96f00df51008a14d3ca7c7e672c47f0f 100644
|
||||
--- a/src/deoptimizer/deoptimizer.h
|
||||
+++ b/src/deoptimizer/deoptimizer.h
|
||||
@@ -39,13 +39,17 @@ enum class BuiltinContinuationMode;
|
||||
|
||||
class TranslatedValue {
|
||||
public:
|
||||
- // Allocation-less getter of the value.
|
||||
+ // Allocation-free getter of the value.
|
||||
// Returns ReadOnlyRoots::arguments_marker() if allocation would be necessary
|
||||
- // to get the value.
|
||||
+ // to get the value. In the case of numbers, returns a Smi if possible.
|
||||
Object GetRawValue() const;
|
||||
|
||||
- // Getter for the value, takes care of materializing the subgraph
|
||||
- // reachable from this value.
|
||||
+ // Convenience wrapper around GetRawValue (checked).
|
||||
+ int GetSmiValue() const;
|
||||
+
|
||||
+ // Returns the value, possibly materializing it first (and the whole subgraph
|
||||
+ // reachable from this value). In the case of numbers, returns a Smi if
|
||||
+ // possible.
|
||||
Handle<Object> GetValue();
|
||||
|
||||
bool IsMaterializedObject() const;
|
||||
@@ -102,15 +106,14 @@ class TranslatedValue {
|
||||
static TranslatedValue NewInvalid(TranslatedState* container);
|
||||
|
||||
Isolate* isolate() const;
|
||||
- void MaterializeSimple();
|
||||
|
||||
void set_storage(Handle<HeapObject> storage) { storage_ = storage; }
|
||||
- void set_initialized_storage(Handle<Object> storage);
|
||||
+ void set_initialized_storage(Handle<HeapObject> storage);
|
||||
void mark_finished() { materialization_state_ = kFinished; }
|
||||
void mark_allocated() { materialization_state_ = kAllocated; }
|
||||
|
||||
- Handle<Object> GetStorage() {
|
||||
- DCHECK_NE(kUninitialized, materialization_state());
|
||||
+ Handle<HeapObject> storage() {
|
||||
+ DCHECK_NE(materialization_state(), kUninitialized);
|
||||
return storage_;
|
||||
}
|
||||
|
||||
@@ -120,9 +123,9 @@ class TranslatedValue {
|
||||
// objects and constructing handles (to get
|
||||
// to the isolate).
|
||||
|
||||
- Handle<Object> storage_; // Contains the materialized value or the
|
||||
- // byte-array that will be later morphed into
|
||||
- // the materialized object.
|
||||
+ Handle<HeapObject> storage_; // Contains the materialized value or the
|
||||
+ // byte-array that will be later morphed into
|
||||
+ // the materialized object.
|
||||
|
||||
struct MaterializedObjectInfo {
|
||||
int id_;
|
||||
@@ -376,7 +379,7 @@ class TranslatedState {
|
||||
int* value_index, std::stack<int>* worklist);
|
||||
void EnsureCapturedObjectAllocatedAt(int object_index,
|
||||
std::stack<int>* worklist);
|
||||
- Handle<Object> InitializeObjectAt(TranslatedValue* slot);
|
||||
+ Handle<HeapObject> InitializeObjectAt(TranslatedValue* slot);
|
||||
void InitializeCapturedObjectAt(int object_index, std::stack<int>* worklist,
|
||||
const DisallowHeapAllocation& no_allocation);
|
||||
void InitializeJSObjectAt(TranslatedFrame* frame, int* value_index,
|
||||
@@ -392,6 +395,9 @@ class TranslatedState {
|
||||
TranslatedValue* ResolveCapturedObject(TranslatedValue* slot);
|
||||
TranslatedValue* GetValueByObjectIndex(int object_index);
|
||||
Handle<Object> GetValueAndAdvance(TranslatedFrame* frame, int* value_index);
|
||||
+ TranslatedValue* GetResolvedSlot(TranslatedFrame* frame, int value_index);
|
||||
+ TranslatedValue* GetResolvedSlotAndAdvance(TranslatedFrame* frame,
|
||||
+ int* value_index);
|
||||
|
||||
static uint32_t GetUInt32Slot(Address fp, int slot_index);
|
||||
static uint64_t GetUInt64Slot(Address fp, int slot_index);
|
||||
@@ -773,7 +779,7 @@ class FrameDescription {
|
||||
intptr_t continuation_;
|
||||
|
||||
// This must be at the end of the object as the object is allocated larger
|
||||
- // than it's definition indicate to extend this array.
|
||||
+ // than its definition indicates to extend this array.
|
||||
intptr_t frame_content_[1];
|
||||
|
||||
intptr_t* GetFrameSlotPointer(unsigned offset) {
|
||||
diff --git a/test/mjsunit/compiler/regress-1084820.js b/test/mjsunit/compiler/regress-1084820.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..beb168b413ff045c5aff8e68d2e6da32b27800d6
|
||||
--- /dev/null
|
||||
+++ b/test/mjsunit/compiler/regress-1084820.js
|
||||
@@ -0,0 +1,27 @@
|
||||
+// Copyright 2020 the V8 project authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+// Flags: --allow-natives-syntax
|
||||
+
|
||||
+// Create a map where 'my_property' has HeapObject representation.
|
||||
+const dummy_obj = {};
|
||||
+dummy_obj.my_property = 'some HeapObject';
|
||||
+dummy_obj.my_property = 'some other HeapObject';
|
||||
+
|
||||
+function gaga() {
|
||||
+ const obj = {};
|
||||
+ // Store a HeapNumber and then a Smi.
|
||||
+ // This must happen in a loop, even if it's only 2 iterations:
|
||||
+ for (let j = -3_000_000_000; j <= -1_000_000_000; j += 2_000_000_000) {
|
||||
+ obj.my_property = j;
|
||||
+ }
|
||||
+ // Trigger (soft) deopt.
|
||||
+ if (!%IsBeingInterpreted()) obj + obj;
|
||||
+}
|
||||
+
|
||||
+%PrepareFunctionForOptimization(gaga);
|
||||
+gaga();
|
||||
+gaga();
|
||||
+%OptimizeFunctionOnNextCall(gaga);
|
||||
+gaga();
|
||||
diff --git a/test/mjsunit/compiler/regress-1092650.js b/test/mjsunit/compiler/regress-1092650.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ba94375aeb8262536e28d5d409d69115e385c3b3
|
||||
--- /dev/null
|
||||
+++ b/test/mjsunit/compiler/regress-1092650.js
|
||||
@@ -0,0 +1,23 @@
|
||||
+// Copyright 2020 the V8 project authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+// Flags: --allow-natives-syntax
|
||||
+
|
||||
+// Create map with HeapNumber in field 'a'
|
||||
+({a: 2**30});
|
||||
+
|
||||
+function foo() {
|
||||
+ return foo.arguments[0];
|
||||
+}
|
||||
+
|
||||
+function main() {
|
||||
+ foo({a: 42});
|
||||
+}
|
||||
+
|
||||
+%PrepareFunctionForOptimization(foo);
|
||||
+%PrepareFunctionForOptimization(main);
|
||||
+main();
|
||||
+main();
|
||||
+%OptimizeFunctionOnNextCall(main);
|
||||
+main();
|
||||
diff --git a/test/mjsunit/compiler/regress-1094132.js b/test/mjsunit/compiler/regress-1094132.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..418637d86f8c363b9c0c41c450914e758ff73e9c
|
||||
--- /dev/null
|
||||
+++ b/test/mjsunit/compiler/regress-1094132.js
|
||||
@@ -0,0 +1,78 @@
|
||||
+// Copyright 2020 the V8 project authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+// Flags: --allow-natives-syntax
|
||||
+
|
||||
+function prettyPrinted() {}
|
||||
+
|
||||
+function formatFailureText() {
|
||||
+ if (expectedText.length <= 40 && foundText.length <= 40) {
|
||||
+ message += ": expected <" + expectedText + "> found <" + foundText + ">";
|
||||
+ message += ":\nexpected:\n" + expectedText + "\nfound:\n" + foundText;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+function fail(expectedText, found, name_opt) {
|
||||
+ formatFailureText(expectedText, found, name_opt);
|
||||
+ if (!a[aProps[i]][aProps[i]]) { }
|
||||
+}
|
||||
+
|
||||
+function deepEquals(a, b) {
|
||||
+ if (a === 0) return 1 / a === 1 / b;
|
||||
+ if (typeof a !== typeof a) return false;
|
||||
+ if (typeof a !== "object" && typeof a !== "function") return false;
|
||||
+ if (objectClass !== classOf()) return false;
|
||||
+ if (objectClass === "RegExp") { }
|
||||
+}
|
||||
+
|
||||
+function assertEquals() {
|
||||
+ if (!deepEquals()) {
|
||||
+ fail(prettyPrinted(), undefined, undefined);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+({y: {}, x: 0.42});
|
||||
+
|
||||
+function gaga() {
|
||||
+ return {gx: bar.arguments[0], hx: baz.arguments[0]};
|
||||
+}
|
||||
+
|
||||
+function baz() {
|
||||
+ return gaga();
|
||||
+}
|
||||
+
|
||||
+function bar(obj) {
|
||||
+ return baz(obj.y);
|
||||
+}
|
||||
+
|
||||
+function foo() {
|
||||
+ bar({y: {}, x: 42});
|
||||
+ try { assertEquals() } catch (e) {}
|
||||
+ try { assertEquals() } catch (e) {}
|
||||
+ assertEquals();
|
||||
+}
|
||||
+
|
||||
+%PrepareFunctionForOptimization(prettyPrinted);
|
||||
+%PrepareFunctionForOptimization(formatFailureText);
|
||||
+%PrepareFunctionForOptimization(fail);
|
||||
+%PrepareFunctionForOptimization(deepEquals);
|
||||
+%PrepareFunctionForOptimization(assertEquals);
|
||||
+%PrepareFunctionForOptimization(gaga);
|
||||
+%PrepareFunctionForOptimization(baz);
|
||||
+%PrepareFunctionForOptimization(bar);
|
||||
+%PrepareFunctionForOptimization(foo);
|
||||
+try { foo() } catch (e) {}
|
||||
+%OptimizeFunctionOnNextCall(foo);
|
||||
+try { foo() } catch (e) {}
|
||||
+%PrepareFunctionForOptimization(prettyPrinted);
|
||||
+%PrepareFunctionForOptimization(formatFailureText);
|
||||
+%PrepareFunctionForOptimization(fail);
|
||||
+%PrepareFunctionForOptimization(deepEquals);
|
||||
+%PrepareFunctionForOptimization(assertEquals);
|
||||
+%PrepareFunctionForOptimization(gaga);
|
||||
+%PrepareFunctionForOptimization(baz);
|
||||
+%PrepareFunctionForOptimization(bar);
|
||||
+%PrepareFunctionForOptimization(foo);
|
||||
+%OptimizeFunctionOnNextCall(foo);
|
||||
+try { foo() } catch (e) {}
|
||||
218
patches/v8/backport_986051.patch
Normal file
218
patches/v8/backport_986051.patch
Normal file
@@ -0,0 +1,218 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: guard against missing CommandLineAPIScope
|
||||
|
||||
[986051] [Medium] [CVE-2020-6518]: Security: Use-after-free of CommandLineAPIScope object
|
||||
Backport https://chromium.googlesource.com/v8/v8.git/+/3b60af8669916f3b019745f19144392f6b4f6b12
|
||||
|
||||
diff --git a/src/inspector/v8-console.cc b/src/inspector/v8-console.cc
|
||||
index ec7709f8c690e17d873ce6b2499603b9de635e14..4fd33e346ae90e547997f1f604cb3963d1ba8e89 100644
|
||||
--- a/src/inspector/v8-console.cc
|
||||
+++ b/src/inspector/v8-console.cc
|
||||
@@ -783,15 +783,11 @@ static bool isCommandLineAPIGetter(const String16& name) {
|
||||
|
||||
void V8Console::CommandLineAPIScope::accessorGetterCallback(
|
||||
v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
|
||||
- CommandLineAPIScope* scope = static_cast<CommandLineAPIScope*>(
|
||||
- info.Data().As<v8::External>()->Value());
|
||||
- DCHECK(scope);
|
||||
-
|
||||
+ CommandLineAPIScope* scope = *static_cast<CommandLineAPIScope**>(
|
||||
+ info.Data().As<v8::ArrayBuffer>()->GetBackingStore()->Data());
|
||||
v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
|
||||
- if (scope->m_cleanup) {
|
||||
- bool removed = info.Holder()->Delete(context, name).FromMaybe(false);
|
||||
- DCHECK(removed);
|
||||
- USE(removed);
|
||||
+ if (scope == nullptr) {
|
||||
+ USE(info.Holder()->Delete(context, name).FromMaybe(false));
|
||||
return;
|
||||
}
|
||||
v8::Local<v8::Object> commandLineAPI = scope->m_commandLineAPI;
|
||||
@@ -815,16 +811,14 @@ void V8Console::CommandLineAPIScope::accessorGetterCallback(
|
||||
void V8Console::CommandLineAPIScope::accessorSetterCallback(
|
||||
v8::Local<v8::Name> name, v8::Local<v8::Value> value,
|
||||
const v8::PropertyCallbackInfo<void>& info) {
|
||||
- CommandLineAPIScope* scope = static_cast<CommandLineAPIScope*>(
|
||||
- info.Data().As<v8::External>()->Value());
|
||||
+ CommandLineAPIScope* scope = *static_cast<CommandLineAPIScope**>(
|
||||
+ info.Data().As<v8::ArrayBuffer>()->GetBackingStore()->Data());
|
||||
+ if (scope == nullptr) return;
|
||||
v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
|
||||
if (!info.Holder()->Delete(context, name).FromMaybe(false)) return;
|
||||
if (!info.Holder()->CreateDataProperty(context, name, value).FromMaybe(false))
|
||||
return;
|
||||
- bool removed =
|
||||
- scope->m_installedMethods->Delete(context, name).FromMaybe(false);
|
||||
- DCHECK(removed);
|
||||
- USE(removed);
|
||||
+ USE(scope->m_installedMethods->Delete(context, name).FromMaybe(false));
|
||||
}
|
||||
|
||||
V8Console::CommandLineAPIScope::CommandLineAPIScope(
|
||||
@@ -833,14 +827,15 @@ V8Console::CommandLineAPIScope::CommandLineAPIScope(
|
||||
: m_context(context),
|
||||
m_commandLineAPI(commandLineAPI),
|
||||
m_global(global),
|
||||
- m_installedMethods(v8::Set::New(context->GetIsolate())),
|
||||
- m_cleanup(false) {
|
||||
+ m_installedMethods(v8::Set::New(context->GetIsolate())) {
|
||||
v8::MicrotasksScope microtasksScope(context->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
v8::Local<v8::Array> names;
|
||||
if (!m_commandLineAPI->GetOwnPropertyNames(context).ToLocal(&names)) return;
|
||||
- v8::Local<v8::External> externalThis =
|
||||
- v8::External::New(context->GetIsolate(), this);
|
||||
+ m_thisReference =
|
||||
+ v8::ArrayBuffer::New(context->GetIsolate(), sizeof(CommandLineAPIScope*));
|
||||
+ *static_cast<CommandLineAPIScope**>(
|
||||
+ m_thisReference->GetBackingStore()->Data()) = this;
|
||||
for (uint32_t i = 0; i < names->Length(); ++i) {
|
||||
v8::Local<v8::Value> name;
|
||||
if (!names->Get(context, i).ToLocal(&name) || !name->IsName()) continue;
|
||||
@@ -851,7 +846,7 @@ V8Console::CommandLineAPIScope::CommandLineAPIScope(
|
||||
->SetAccessor(context, v8::Local<v8::Name>::Cast(name),
|
||||
CommandLineAPIScope::accessorGetterCallback,
|
||||
CommandLineAPIScope::accessorSetterCallback,
|
||||
- externalThis, v8::DEFAULT, v8::DontEnum,
|
||||
+ m_thisReference, v8::DEFAULT, v8::DontEnum,
|
||||
v8::SideEffectType::kHasNoSideEffect)
|
||||
.FromMaybe(false)) {
|
||||
bool removed = m_installedMethods->Delete(context, name).FromMaybe(false);
|
||||
@@ -865,7 +860,8 @@ V8Console::CommandLineAPIScope::CommandLineAPIScope(
|
||||
V8Console::CommandLineAPIScope::~CommandLineAPIScope() {
|
||||
v8::MicrotasksScope microtasksScope(m_context->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
- m_cleanup = true;
|
||||
+ *static_cast<CommandLineAPIScope**>(
|
||||
+ m_thisReference->GetBackingStore()->Data()) = nullptr;
|
||||
v8::Local<v8::Array> names = m_installedMethods->AsArray();
|
||||
for (uint32_t i = 0; i < names->Length(); ++i) {
|
||||
v8::Local<v8::Value> name;
|
||||
diff --git a/src/inspector/v8-console.h b/src/inspector/v8-console.h
|
||||
index 4d38c51a2a28d6871ab00b21bde0dfb2c0605357..5875164595f78992d50c23fe90884269178ab986 100644
|
||||
--- a/src/inspector/v8-console.h
|
||||
+++ b/src/inspector/v8-console.h
|
||||
@@ -42,7 +42,7 @@ class V8Console : public v8::debug::ConsoleDelegate {
|
||||
v8::Local<v8::Object> m_commandLineAPI;
|
||||
v8::Local<v8::Object> m_global;
|
||||
v8::Local<v8::Set> m_installedMethods;
|
||||
- bool m_cleanup;
|
||||
+ v8::Local<v8::ArrayBuffer> m_thisReference;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CommandLineAPIScope);
|
||||
};
|
||||
diff --git a/test/inspector/runtime/regress-986051-expected.txt b/test/inspector/runtime/regress-986051-expected.txt
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ad2f3d8209532a03acf39974faca6c36adf4b78c
|
||||
--- /dev/null
|
||||
+++ b/test/inspector/runtime/regress-986051-expected.txt
|
||||
@@ -0,0 +1,76 @@
|
||||
+Regression test for 986051
|
||||
+Regression test
|
||||
+{
|
||||
+ id : <messageId>
|
||||
+ result : {
|
||||
+ result : {
|
||||
+ description : 1
|
||||
+ type : number
|
||||
+ value : 1
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+{
|
||||
+ id : <messageId>
|
||||
+ result : {
|
||||
+ exceptionDetails : {
|
||||
+ columnNumber : 1
|
||||
+ exception : {
|
||||
+ className : ReferenceError
|
||||
+ description : ReferenceError: $0 is not defined at <anonymous>:1:1
|
||||
+ objectId : <objectId>
|
||||
+ subtype : error
|
||||
+ type : object
|
||||
+ }
|
||||
+ exceptionId : <exceptionId>
|
||||
+ lineNumber : 1
|
||||
+ scriptId : <scriptId>
|
||||
+ stackTrace : {
|
||||
+ callFrames : [
|
||||
+ [0] : {
|
||||
+ columnNumber : 0
|
||||
+ functionName :
|
||||
+ lineNumber : 0
|
||||
+ scriptId : <scriptId>
|
||||
+ url :
|
||||
+ }
|
||||
+ ]
|
||||
+ }
|
||||
+ text : Uncaught
|
||||
+ }
|
||||
+ result : {
|
||||
+ className : ReferenceError
|
||||
+ description : ReferenceError: $0 is not defined at <anonymous>:1:1
|
||||
+ objectId : <objectId>
|
||||
+ subtype : error
|
||||
+ type : object
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+{
|
||||
+ id : <messageId>
|
||||
+ result : {
|
||||
+ result : {
|
||||
+ className : global
|
||||
+ description : global
|
||||
+ objectId : <objectId>
|
||||
+ type : object
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+{
|
||||
+ id : <messageId>
|
||||
+ result : {
|
||||
+ result : {
|
||||
+ type : undefined
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+{
|
||||
+ id : <messageId>
|
||||
+ result : {
|
||||
+ result : {
|
||||
+ type : undefined
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/test/inspector/runtime/regress-986051.js b/test/inspector/runtime/regress-986051.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7c6842a36cf23185178ec99d97a488e88ca30910
|
||||
--- /dev/null
|
||||
+++ b/test/inspector/runtime/regress-986051.js
|
||||
@@ -0,0 +1,25 @@
|
||||
+// Copyright 2020 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.
|
||||
+
|
||||
+let {Protocol} = InspectorTest.start(
|
||||
+ "Regression test for 986051");
|
||||
+
|
||||
+Protocol.Runtime.enable();
|
||||
+(async function() {
|
||||
+ InspectorTest.log("Regression test");
|
||||
+ evaluateRepl('1', true);
|
||||
+ evaluateRepl('$0', false);
|
||||
+ evaluateRepl('Object.defineProperty(globalThis, "$0", {configurable: false});', true);
|
||||
+ evaluateRepl('$0', true);
|
||||
+ evaluateRepl('$0', false);
|
||||
+ InspectorTest.completeTest();
|
||||
+})();
|
||||
+
|
||||
+async function evaluateRepl(expression, includeCommandLineAPI) {
|
||||
+ InspectorTest.logMessage(await Protocol.Runtime.evaluate({
|
||||
+ expression,
|
||||
+ includeCommandLineAPI,
|
||||
+ replMode: true,
|
||||
+ }));
|
||||
+}
|
||||
2
patches/webrtc/.patches
Normal file
2
patches/webrtc/.patches
Normal file
@@ -0,0 +1,2 @@
|
||||
backport_1076703.patch
|
||||
backport_978779.patch
|
||||
200
patches/webrtc/backport_1076703.patch
Normal file
200
patches/webrtc/backport_1076703.patch
Normal file
@@ -0,0 +1,200 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Thu, 4 Oct 2018 14:57:02 -0700
|
||||
Subject: fix: prevent pointer from being sent in the clear over SCTP
|
||||
|
||||
[1076703] [High] [CVE-2020-6514]: Security: WebRTC: usrsctp is called with pointer as network address
|
||||
Backport https://webrtc.googlesource.com/src/+/963cc1ef1336b52ca27742beb28bfbc211ed54d0
|
||||
|
||||
diff --git a/media/sctp/sctp_transport.cc b/media/sctp/sctp_transport.cc
|
||||
index 40061a604870b0e7033449d114e3a9b8fa32d028..1a6dc334e1fd1f69a094e763d13f71f4c5292a5e 100644
|
||||
--- a/media/sctp/sctp_transport.cc
|
||||
+++ b/media/sctp/sctp_transport.cc
|
||||
@@ -22,6 +22,7 @@ enum PreservedErrno {
|
||||
#include <stdio.h>
|
||||
|
||||
#include <memory>
|
||||
+#include <unordered_map>
|
||||
|
||||
#include "absl/algorithm/container.h"
|
||||
#include "absl/base/attributes.h"
|
||||
@@ -39,6 +40,7 @@ enum PreservedErrno {
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/numerics/safe_conversions.h"
|
||||
#include "rtc_base/string_utils.h"
|
||||
+#include "rtc_base/thread_annotations.h"
|
||||
#include "rtc_base/thread_checker.h"
|
||||
#include "rtc_base/trace_event.h"
|
||||
#include "usrsctplib/usrsctp.h"
|
||||
@@ -72,6 +74,59 @@ enum PayloadProtocolIdentifier {
|
||||
PPID_TEXT_LAST = 51
|
||||
};
|
||||
|
||||
+// Maps SCTP transport ID to SctpTransport object, necessary in send threshold
|
||||
+// callback and outgoing packet callback.
|
||||
+// TODO(crbug.com/1076703): Remove once the underlying problem is fixed or
|
||||
+// workaround is provided in usrsctp.
|
||||
+class SctpTransportMap {
|
||||
+ public:
|
||||
+ SctpTransportMap() = default;
|
||||
+
|
||||
+ // Assigns a new unused ID to the following transport.
|
||||
+ uintptr_t Register(cricket::SctpTransport* transport) {
|
||||
+ rtc::CritScope cs(&lock_);
|
||||
+ // usrsctp_connect fails with a value of 0...
|
||||
+ if (next_id_ == 0) {
|
||||
+ ++next_id_;
|
||||
+ }
|
||||
+ // In case we've wrapped around and need to find an empty spot from a
|
||||
+ // removed transport. Assumes we'll never be full.
|
||||
+ while (map_.find(next_id_) != map_.end()) {
|
||||
+ ++next_id_;
|
||||
+ if (next_id_ == 0) {
|
||||
+ ++next_id_;
|
||||
+ }
|
||||
+ };
|
||||
+ map_[next_id_] = transport;
|
||||
+ return next_id_++;
|
||||
+ }
|
||||
+
|
||||
+ // Returns true if found.
|
||||
+ bool Deregister(uintptr_t id) {
|
||||
+ rtc::CritScope cs(&lock_);
|
||||
+ return map_.erase(id) > 0;
|
||||
+ }
|
||||
+
|
||||
+ cricket::SctpTransport* Retrieve(uintptr_t id) const {
|
||||
+ rtc::CritScope cs(&lock_);
|
||||
+ auto it = map_.find(id);
|
||||
+ if (it == map_.end()) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ return it->second;
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ rtc::CriticalSection lock_;
|
||||
+
|
||||
+ uintptr_t next_id_ RTC_GUARDED_BY(lock_) = 0;
|
||||
+ std::unordered_map<uintptr_t, cricket::SctpTransport*> map_
|
||||
+ RTC_GUARDED_BY(lock_);
|
||||
+};
|
||||
+
|
||||
+// Should only be modified by UsrSctpWrapper.
|
||||
+ABSL_CONST_INIT SctpTransportMap* g_transport_map_ = nullptr;
|
||||
+
|
||||
// Helper for logging SCTP messages.
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__format__(__printf__, 1, 2)))
|
||||
@@ -242,9 +297,12 @@ class SctpTransport::UsrSctpWrapper {
|
||||
// Set the number of default outgoing streams. This is the number we'll
|
||||
// send in the SCTP INIT message.
|
||||
usrsctp_sysctl_set_sctp_nr_outgoing_streams_default(kMaxSctpStreams);
|
||||
+
|
||||
+ g_transport_map_ = new SctpTransportMap();
|
||||
}
|
||||
|
||||
static void UninitializeUsrSctp() {
|
||||
+ delete g_transport_map_;
|
||||
RTC_LOG(LS_INFO) << __FUNCTION__;
|
||||
// usrsctp_finish() may fail if it's called too soon after the transports
|
||||
// are
|
||||
@@ -282,7 +340,14 @@ class SctpTransport::UsrSctpWrapper {
|
||||
size_t length,
|
||||
uint8_t tos,
|
||||
uint8_t set_df) {
|
||||
- SctpTransport* transport = static_cast<SctpTransport*>(addr);
|
||||
+ SctpTransport* transport =
|
||||
+ g_transport_map_->Retrieve(reinterpret_cast<uintptr_t>(addr));
|
||||
+ if (!transport) {
|
||||
+ RTC_LOG(LS_ERROR)
|
||||
+ << "OnSctpOutboundPacket: Failed to get transport for socket ID "
|
||||
+ << addr;
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
RTC_LOG(LS_VERBOSE) << "global OnSctpOutboundPacket():"
|
||||
"addr: "
|
||||
<< addr << "; length: " << length
|
||||
@@ -392,14 +457,14 @@ class SctpTransport::UsrSctpWrapper {
|
||||
return nullptr;
|
||||
}
|
||||
// usrsctp_getladdrs() returns the addresses bound to this socket, which
|
||||
- // contains the SctpTransport* as sconn_addr. Read the pointer,
|
||||
+ // contains the SctpTransport id as sconn_addr. Read the id,
|
||||
// then free the list of addresses once we have the pointer. We only open
|
||||
// AF_CONN sockets, and they should all have the sconn_addr set to the
|
||||
- // pointer that created them, so [0] is as good as any other.
|
||||
+ // id of the transport that created them, so [0] is as good as any other.
|
||||
struct sockaddr_conn* sconn =
|
||||
reinterpret_cast<struct sockaddr_conn*>(&addrs[0]);
|
||||
- SctpTransport* transport =
|
||||
- reinterpret_cast<SctpTransport*>(sconn->sconn_addr);
|
||||
+ SctpTransport* transport = g_transport_map_->Retrieve(
|
||||
+ reinterpret_cast<uintptr_t>(sconn->sconn_addr));
|
||||
usrsctp_freeladdrs(addrs);
|
||||
|
||||
return transport;
|
||||
@@ -779,9 +844,10 @@ bool SctpTransport::OpenSctpSocket() {
|
||||
UsrSctpWrapper::DecrementUsrSctpUsageCount();
|
||||
return false;
|
||||
}
|
||||
- // Register this class as an address for usrsctp. This is used by SCTP to
|
||||
+ id_ = g_transport_map_->Register(this);
|
||||
+ // Register our id as an address for usrsctp. This is used by SCTP to
|
||||
// direct the packets received (by the created socket) to this class.
|
||||
- usrsctp_register_address(this);
|
||||
+ usrsctp_register_address(reinterpret_cast<void*>(id_));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -872,7 +938,8 @@ void SctpTransport::CloseSctpSocket() {
|
||||
// discarded instead of being sent.
|
||||
usrsctp_close(sock_);
|
||||
sock_ = nullptr;
|
||||
- usrsctp_deregister_address(this);
|
||||
+ usrsctp_deregister_address(reinterpret_cast<void*>(id_));
|
||||
+ RTC_CHECK(g_transport_map_->Deregister(id_));
|
||||
UsrSctpWrapper::DecrementUsrSctpUsageCount();
|
||||
ready_to_send_data_ = false;
|
||||
}
|
||||
@@ -1003,7 +1070,7 @@ void SctpTransport::OnPacketRead(rtc::PacketTransportInternal* transport,
|
||||
// will be will be given to the global OnSctpInboundData, and then,
|
||||
// marshalled by the AsyncInvoker.
|
||||
VerboseLogPacket(data, len, SCTP_DUMP_INBOUND);
|
||||
- usrsctp_conninput(this, data, len, 0);
|
||||
+ usrsctp_conninput(reinterpret_cast<void*>(id_), data, len, 0);
|
||||
} else {
|
||||
// TODO(ldixon): Consider caching the packet for very slightly better
|
||||
// reliability.
|
||||
@@ -1033,7 +1100,7 @@ sockaddr_conn SctpTransport::GetSctpSockAddr(int port) {
|
||||
#endif
|
||||
// Note: conversion from int to uint16_t happens here.
|
||||
sconn.sconn_port = rtc::HostToNetwork16(port);
|
||||
- sconn.sconn_addr = this;
|
||||
+ sconn.sconn_addr = reinterpret_cast<void*>(id_);
|
||||
return sconn;
|
||||
}
|
||||
|
||||
diff --git a/media/sctp/sctp_transport.h b/media/sctp/sctp_transport.h
|
||||
index d346cfc71fa8dc106509543110f0f53bd34e61b1..758503b509430ea87825ee9ac023e04b7556ac6f 100644
|
||||
--- a/media/sctp/sctp_transport.h
|
||||
+++ b/media/sctp/sctp_transport.h
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
+#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
@@ -267,6 +268,10 @@ class SctpTransport : public SctpTransportInternal,
|
||||
absl::optional<int> max_outbound_streams_;
|
||||
absl::optional<int> max_inbound_streams_;
|
||||
|
||||
+ // Used for associating this transport with the underlying sctp socket in
|
||||
+ // various callbacks.
|
||||
+ uintptr_t id_ = 0;
|
||||
+
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(SctpTransport);
|
||||
};
|
||||
|
||||
6314
patches/webrtc/backport_978779.patch
Normal file
6314
patches/webrtc/backport_978779.patch
Normal file
File diff suppressed because it is too large
Load Diff
42
script/check-symlinks.js
Normal file
42
script/check-symlinks.js
Normal file
@@ -0,0 +1,42 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const utils = require('./lib/utils');
|
||||
|
||||
if (process.platform !== 'darwin') {
|
||||
console.log('Not checking symlinks on non-darwin platform');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const appPath = path.resolve(__dirname, '..', '..', 'out', utils.getOutDir(), 'Electron.app');
|
||||
const visited = new Set();
|
||||
const traverse = (p) => {
|
||||
if (visited.has(p)) return;
|
||||
|
||||
visited.add(p);
|
||||
if (!fs.statSync(p).isDirectory()) return;
|
||||
|
||||
for (const child of fs.readdirSync(p)) {
|
||||
const childPath = path.resolve(p, child);
|
||||
let realPath;
|
||||
try {
|
||||
realPath = fs.realpathSync(childPath);
|
||||
} catch (err) {
|
||||
if (err.path) {
|
||||
console.error('Detected an invalid symlink');
|
||||
console.error('Source:', childPath);
|
||||
let link = fs.readlinkSync(childPath);
|
||||
if (!link.startsWith('.')) {
|
||||
link = `../${link}`;
|
||||
}
|
||||
console.error('Target:', path.resolve(childPath, link));
|
||||
process.exit(1);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
traverse(realPath);
|
||||
}
|
||||
};
|
||||
|
||||
traverse(appPath);
|
||||
@@ -99,8 +99,6 @@
|
||||
"parallel/test-module-version",
|
||||
"parallel/test-openssl-ca-options",
|
||||
"parallel/test-policy-integrity",
|
||||
"parallel/test-preload",
|
||||
"parallel/test-preload-print-process-argv",
|
||||
"parallel/test-process-env-allowed-flags-are-documented",
|
||||
"parallel/test-process-env-sideeffects",
|
||||
"parallel/test-process-exception-capture",
|
||||
@@ -125,7 +123,6 @@
|
||||
"parallel/test-signal-handler",
|
||||
"parallel/test-source-map",
|
||||
"parallel/test-stdout-close-catch",
|
||||
"parallel/test-sync-io-option",
|
||||
"parallel/test-tls-cert-chains-concat",
|
||||
"parallel/test-tls-cert-chains-in-ca",
|
||||
"parallel/test-tls-cli-max-version-1.2",
|
||||
@@ -219,22 +216,9 @@
|
||||
"sequential/test-cli-syntax-bad",
|
||||
"sequential/test-cli-syntax-good",
|
||||
"sequential/test-cli-syntax-require",
|
||||
"sequential/test-cpu-prof-default",
|
||||
"sequential/test-cpu-prof-dir-absolute",
|
||||
"sequential/test-cpu-prof-dir-and-name",
|
||||
"sequential/test-cpu-prof-dir-relative",
|
||||
"sequential/test-cpu-prof-dir-worker",
|
||||
"sequential/test-cpu-prof-drained",
|
||||
"sequential/test-cpu-prof-exit",
|
||||
"sequential/test-cpu-prof-invalid-options",
|
||||
"sequential/test-cpu-prof-kill",
|
||||
"sequential/test-cpu-prof-name",
|
||||
"sequential/test-cpu-prof-worker-argv",
|
||||
"sequential/test-deprecation-flags",
|
||||
"sequential/test-fs-watch",
|
||||
"sequential/test-heap-prof",
|
||||
"sequential/test-heapdump",
|
||||
"sequential/test-heapdump-flag",
|
||||
"sequential/test-inspector-contexts",
|
||||
"sequential/test-inspector-port-zero",
|
||||
"sequential/test-inspector-resource-name-to-url",
|
||||
|
||||
@@ -3,7 +3,6 @@ Electron.app/Contents/
|
||||
Electron.app/Contents/Frameworks/
|
||||
Electron.app/Contents/Frameworks/Electron Framework.framework/
|
||||
Electron.app/Contents/Frameworks/Electron Framework.framework/Electron Framework
|
||||
Electron.app/Contents/Frameworks/Electron Framework.framework/Helpers
|
||||
Electron.app/Contents/Frameworks/Electron Framework.framework/Libraries
|
||||
Electron.app/Contents/Frameworks/Electron Framework.framework/Resources
|
||||
Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
#include "base/strings/string_split.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "components/content_settings/core/common/content_settings_pattern.h"
|
||||
#include "components/crash/core/app/crashpad.h"
|
||||
#include "components/crash/core/common/crash_key.h"
|
||||
#include "components/crash/core/common/crash_keys.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "extensions/common/constants.h"
|
||||
@@ -33,13 +30,10 @@
|
||||
#include "services/service_manager/sandbox/switches.h"
|
||||
#include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h"
|
||||
#include "shell/app/electron_content_client.h"
|
||||
#include "shell/app/electron_crash_reporter_client.h"
|
||||
#include "shell/browser/api/electron_api_crash_reporter.h"
|
||||
#include "shell/browser/electron_browser_client.h"
|
||||
#include "shell/browser/electron_gpu_client.h"
|
||||
#include "shell/browser/feature_list.h"
|
||||
#include "shell/browser/relauncher.h"
|
||||
#include "shell/common/crash_keys.h"
|
||||
#include "shell/common/electron_paths.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "shell/renderer/electron_renderer_client.h"
|
||||
@@ -64,6 +58,15 @@
|
||||
#include "v8/include/v8.h"
|
||||
#endif
|
||||
|
||||
#if !defined(MAS_BUILD)
|
||||
#include "components/crash/core/app/crashpad.h" // nogncheck
|
||||
#include "components/crash/core/common/crash_key.h"
|
||||
#include "components/crash/core/common/crash_keys.h"
|
||||
#include "shell/app/electron_crash_reporter_client.h"
|
||||
#include "shell/browser/api/electron_api_crash_reporter.h"
|
||||
#include "shell/common/crash_keys.h"
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -14,19 +14,15 @@
|
||||
#include "base/feature_list.h"
|
||||
#include "base/task/thread_pool/thread_pool_instance.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "components/crash/core/app/crashpad.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "electron/electron_version.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/public/isolate_holder.h"
|
||||
#include "gin/v8_initializer.h"
|
||||
#include "shell/app/electron_crash_reporter_client.h"
|
||||
#include "shell/app/uv_task_runner.h"
|
||||
#include "shell/browser/api/electron_api_crash_reporter.h"
|
||||
#include "shell/browser/javascript_environment.h"
|
||||
#include "shell/browser/node_debugger.h"
|
||||
#include "shell/common/api/electron_bindings.h"
|
||||
#include "shell/common/crash_keys.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/node_bindings.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
@@ -39,6 +35,13 @@
|
||||
#include "chrome/child/v8_crashpad_support_win.h"
|
||||
#endif
|
||||
|
||||
#if !defined(MAS_BUILD)
|
||||
#include "components/crash/core/app/crashpad.h" // nogncheck
|
||||
#include "shell/app/electron_crash_reporter_client.h"
|
||||
#include "shell/browser/api/electron_api_crash_reporter.h"
|
||||
#include "shell/common/crash_keys.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
bool AllowWasmCodeGenerationCallback(v8::Local<v8::Context> context,
|
||||
@@ -48,6 +51,11 @@ bool AllowWasmCodeGenerationCallback(v8::Local<v8::Context> context,
|
||||
return wasm_code_gen->IsUndefined() || wasm_code_gen->IsTrue();
|
||||
}
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
void SetCrashKeyStub(const std::string& key, const std::string& value) {}
|
||||
void ClearCrashKeyStub(const std::string& key) {}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
@@ -175,9 +183,14 @@ int NodeMain(int argc, char* argv[]) {
|
||||
#endif
|
||||
|
||||
reporter.SetMethod("getParameters", &GetParameters);
|
||||
#if defined(MAS_BUILD)
|
||||
reporter.SetMethod("addExtraParameter", &SetCrashKeyStub);
|
||||
reporter.SetMethod("removeExtraParameter", &ClearCrashKeyStub);
|
||||
#else
|
||||
reporter.SetMethod("addExtraParameter", &electron::crash_keys::SetCrashKey);
|
||||
reporter.SetMethod("removeExtraParameter",
|
||||
&electron::crash_keys::ClearCrashKey);
|
||||
#endif
|
||||
|
||||
process.Set("crashReporter", reporter);
|
||||
|
||||
@@ -188,6 +201,8 @@ int NodeMain(int argc, char* argv[]) {
|
||||
|
||||
node::LoadEnvironment(env);
|
||||
|
||||
env->set_trace_sync_io(env->options()->trace_sync_io);
|
||||
|
||||
{
|
||||
v8::SealHandleScope seal(isolate);
|
||||
bool more;
|
||||
@@ -211,6 +226,9 @@ int NodeMain(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
node_debugger.Stop();
|
||||
|
||||
env->set_trace_sync_io(false);
|
||||
|
||||
exit_code = node::EmitExit(env);
|
||||
|
||||
node::ResetStdio();
|
||||
|
||||
@@ -12,5 +12,7 @@
|
||||
<string>APPL</string>
|
||||
<key>LSBackgroundOnly</key>
|
||||
<true/>
|
||||
<key>LSRequiresNativeExecution</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -256,22 +256,14 @@ void BrowserWindow::OnWindowClosed() {
|
||||
|
||||
void BrowserWindow::OnWindowBlur() {
|
||||
web_contents()->StoreFocus();
|
||||
#if defined(OS_MACOSX)
|
||||
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
rwhv->SetActive(false);
|
||||
#endif
|
||||
|
||||
TopLevelWindow::OnWindowBlur();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowFocus() {
|
||||
web_contents()->RestoreFocus();
|
||||
#if defined(OS_MACOSX)
|
||||
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
rwhv->SetActive(true);
|
||||
#else
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
if (!api_web_contents_->IsDevToolsOpened())
|
||||
web_contents()->Focus();
|
||||
#endif
|
||||
@@ -279,6 +271,14 @@ void BrowserWindow::OnWindowFocus() {
|
||||
TopLevelWindow::OnWindowFocus();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowIsKeyChanged(bool is_key) {
|
||||
#if defined(OS_MACOSX)
|
||||
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
rwhv->SetActive(is_key);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowResize() {
|
||||
#if defined(OS_MACOSX)
|
||||
if (!draggable_regions_.empty())
|
||||
|
||||
@@ -61,6 +61,7 @@ class BrowserWindow : public TopLevelWindow,
|
||||
// NativeWindowObserver:
|
||||
void RequestPreferredWidth(int* width) override;
|
||||
void OnCloseButtonClicked(bool* prevent_default) override;
|
||||
void OnWindowIsKeyChanged(bool is_key) override;
|
||||
|
||||
// TopLevelWindow:
|
||||
void OnWindowClosed() override;
|
||||
|
||||
@@ -16,25 +16,28 @@
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "chrome/browser/crash_upload_list/crash_upload_list_crashpad.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "components/crash/core/app/crashpad.h"
|
||||
#include "components/crash/core/common/crash_key.h"
|
||||
#include "components/upload_list/crash_upload_list.h"
|
||||
#include "components/upload_list/text_log_upload_list.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "gin/arguments.h"
|
||||
#include "gin/data_object_builder.h"
|
||||
#include "services/service_manager/embedder/switches.h"
|
||||
#include "shell/app/electron_crash_reporter_client.h"
|
||||
#include "shell/common/crash_keys.h"
|
||||
#include "shell/common/electron_paths.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/file_path_converter.h"
|
||||
#include "shell/common/gin_converters/time_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "third_party/crashpad/crashpad/client/crashpad_info.h"
|
||||
|
||||
#if !defined(MAS_BUILD)
|
||||
#include "chrome/browser/crash_upload_list/crash_upload_list_crashpad.h"
|
||||
#include "components/crash/core/app/crashpad.h" // nogncheck
|
||||
#include "components/crash/core/common/crash_key.h"
|
||||
#include "shell/app/electron_crash_reporter_client.h"
|
||||
#include "shell/common/crash_keys.h"
|
||||
#include "third_party/crashpad/crashpad/client/crashpad_info.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include "components/crash/core/app/breakpad_linux.h"
|
||||
@@ -62,6 +65,14 @@ namespace api {
|
||||
|
||||
namespace crash_reporter {
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
namespace {
|
||||
|
||||
void NoOp() {}
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
bool IsCrashReporterEnabled() {
|
||||
return g_crash_reporter_initialized;
|
||||
}
|
||||
@@ -203,8 +214,13 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
gin_helper::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("start", &electron::api::crash_reporter::Start);
|
||||
#if defined(MAS_BUILD)
|
||||
dict.SetMethod("addExtraParameter", &electron::api::crash_reporter::NoOp);
|
||||
dict.SetMethod("removeExtraParameter", &electron::api::crash_reporter::NoOp);
|
||||
#else
|
||||
dict.SetMethod("addExtraParameter", &electron::crash_keys::SetCrashKey);
|
||||
dict.SetMethod("removeExtraParameter", &electron::crash_keys::ClearCrashKey);
|
||||
#endif
|
||||
dict.SetMethod("getParameters", &GetParameters);
|
||||
dict.SetMethod("getUploadedReports", &GetUploadedReports);
|
||||
dict.SetMethod("setUploadToServer", &SetUploadToServer);
|
||||
|
||||
@@ -58,11 +58,13 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
||||
std::string method;
|
||||
if (!dict->GetString("method", &method))
|
||||
return;
|
||||
std::string session_id;
|
||||
dict->GetString("sessionId", &session_id);
|
||||
base::DictionaryValue* params_value = nullptr;
|
||||
base::DictionaryValue params;
|
||||
if (dict->GetDictionary("params", ¶ms_value))
|
||||
params.Swap(params_value);
|
||||
Emit("message", method, params);
|
||||
Emit("message", method, params, session_id);
|
||||
} else {
|
||||
auto it = pending_requests_.find(id);
|
||||
if (it == pending_requests_.end())
|
||||
@@ -149,14 +151,25 @@ v8::Local<v8::Promise> Debugger::SendCommand(gin_helper::Arguments* args) {
|
||||
base::DictionaryValue command_params;
|
||||
args->GetNext(&command_params);
|
||||
|
||||
std::string session_id;
|
||||
if (args->GetNext(&session_id) && session_id.empty()) {
|
||||
promise.RejectWithErrorMessage("Empty session id is not allowed");
|
||||
return handle;
|
||||
}
|
||||
|
||||
base::DictionaryValue request;
|
||||
int request_id = ++previous_request_id_;
|
||||
pending_requests_.emplace(request_id, std::move(promise));
|
||||
request.SetInteger("id", request_id);
|
||||
request.SetString("method", method);
|
||||
if (!command_params.empty())
|
||||
if (!command_params.empty()) {
|
||||
request.Set("params",
|
||||
base::Value::ToUniquePtrValue(command_params.Clone()));
|
||||
}
|
||||
|
||||
if (!session_id.empty()) {
|
||||
request.SetString("sessionId", session_id);
|
||||
}
|
||||
|
||||
std::string json_args;
|
||||
base::JSONWriter::Write(request, &json_args);
|
||||
|
||||
@@ -32,6 +32,21 @@
|
||||
selector:@selector(onScreenUnlocked:)
|
||||
name:@"com.apple.screenIsUnlocked"
|
||||
object:nil];
|
||||
|
||||
// A notification that the workspace posts before the machine goes to sleep.
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter]
|
||||
addObserver:self
|
||||
selector:@selector(isSuspending:)
|
||||
name:NSWorkspaceWillSleepNotification
|
||||
object:nil];
|
||||
|
||||
// A notification that the workspace posts when the machine wakes from
|
||||
// sleep.
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter]
|
||||
addObserver:self
|
||||
selector:@selector(isResuming:)
|
||||
name:NSWorkspaceDidWakeNotification
|
||||
object:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -45,14 +60,26 @@
|
||||
self->emitters.push_back(monitor_);
|
||||
}
|
||||
|
||||
- (void)isSuspending:(NSNotification*)notify {
|
||||
for (auto* emitter : self->emitters) {
|
||||
emitter->Emit("suspend");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)isResuming:(NSNotification*)notify {
|
||||
for (auto* emitter : self->emitters) {
|
||||
emitter->Emit("resume");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onScreenLocked:(NSNotification*)notification {
|
||||
for (auto*& emitter : self->emitters) {
|
||||
for (auto* emitter : self->emitters) {
|
||||
emitter->Emit("lock-screen");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onScreenUnlocked:(NSNotification*)notification {
|
||||
for (auto*& emitter : self->emitters) {
|
||||
for (auto* emitter : self->emitters) {
|
||||
emitter->Emit("unlock-screen");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,12 @@ LRESULT CALLBACK PowerMonitor::WndProc(HWND hwnd,
|
||||
Emit("unlock-screen");
|
||||
}
|
||||
}
|
||||
} else if (message == WM_POWERBROADCAST) {
|
||||
if (wparam == PBT_APMRESUMEAUTOMATIC) {
|
||||
Emit("resume");
|
||||
} else if (wparam == PBT_APMSUSPEND) {
|
||||
Emit("suspend");
|
||||
}
|
||||
}
|
||||
return ::DefWindowProc(hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "net/http/http_auth_handler_factory.h"
|
||||
#include "net/http/http_auth_preferences.h"
|
||||
#include "net/http/http_cache.h"
|
||||
#include "net/http/http_util.h"
|
||||
#include "services/network/network_service.h"
|
||||
#include "services/network/public/cpp/features.h"
|
||||
#include "shell/browser/api/electron_api_cookies.h"
|
||||
@@ -593,12 +594,14 @@ v8::Local<v8::Promise> Session::ClearAuthCache() {
|
||||
}
|
||||
|
||||
void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
network::mojom::HttpAuthDynamicParamsPtr auth_dynamic_params =
|
||||
network::mojom::HttpAuthDynamicParams::New();
|
||||
auth_dynamic_params->server_allowlist = domains;
|
||||
auth_dynamic_params->enable_negotiate_port =
|
||||
base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
electron::switches::kEnableAuthNegotiatePort);
|
||||
command_line->HasSwitch(electron::switches::kEnableAuthNegotiatePort);
|
||||
auth_dynamic_params->ntlm_v2_enabled =
|
||||
!command_line->HasSwitch(electron::switches::kDisableNTLMv2);
|
||||
content::GetNetworkService()->ConfigureHttpAuthPrefs(
|
||||
std::move(auth_dynamic_params));
|
||||
}
|
||||
@@ -606,9 +609,16 @@ void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
|
||||
void Session::SetUserAgent(const std::string& user_agent,
|
||||
gin_helper::Arguments* args) {
|
||||
browser_context_->SetUserAgent(user_agent);
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
|
||||
->GetNetworkContext()
|
||||
->SetUserAgent(user_agent);
|
||||
auto* network_context = content::BrowserContext::GetDefaultStoragePartition(
|
||||
browser_context_.get())
|
||||
->GetNetworkContext();
|
||||
network_context->SetUserAgent(user_agent);
|
||||
|
||||
std::string accept_lang;
|
||||
if (args->GetNext(&accept_lang)) {
|
||||
network_context->SetAcceptLanguage(
|
||||
net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang));
|
||||
}
|
||||
}
|
||||
|
||||
std::string Session::GetUserAgent() {
|
||||
|
||||
@@ -73,6 +73,8 @@ void SystemPreferences::BuildPrototype(
|
||||
#if defined(OS_WIN) || defined(OS_MACOSX)
|
||||
.SetMethod("getColor", &SystemPreferences::GetColor)
|
||||
.SetMethod("getAccentColor", &SystemPreferences::GetAccentColor)
|
||||
.SetMethod("getMediaAccessStatus",
|
||||
&SystemPreferences::GetMediaAccessStatus)
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@@ -112,8 +114,6 @@ void SystemPreferences::BuildPrototype(
|
||||
.SetMethod("promptTouchID", &SystemPreferences::PromptTouchID)
|
||||
.SetMethod("isTrustedAccessibilityClient",
|
||||
&SystemPreferences::IsTrustedAccessibilityClient)
|
||||
.SetMethod("getMediaAccessStatus",
|
||||
&SystemPreferences::GetMediaAccessStatus)
|
||||
.SetMethod("askForMediaAccess", &SystemPreferences::AskForMediaAccess)
|
||||
#endif
|
||||
.SetMethod("isInvertedColorScheme",
|
||||
|
||||
@@ -49,6 +49,10 @@ class SystemPreferences : public gin_helper::EventEmitter<SystemPreferences>
|
||||
std::string GetAccentColor();
|
||||
std::string GetColor(gin_helper::ErrorThrower thrower,
|
||||
const std::string& color);
|
||||
// TODO(codebytere): Write tests for these methods once we
|
||||
// are running tests on a Mojave machine
|
||||
std::string GetMediaAccessStatus(const std::string& media_type,
|
||||
gin_helper::Arguments* args);
|
||||
#endif
|
||||
#if defined(OS_WIN)
|
||||
bool IsAeroGlassEnabled();
|
||||
@@ -99,10 +103,6 @@ class SystemPreferences : public gin_helper::EventEmitter<SystemPreferences>
|
||||
|
||||
static bool IsTrustedAccessibilityClient(bool prompt);
|
||||
|
||||
// TODO(codebytere): Write tests for these methods once we
|
||||
// are running tests on a Mojave machine
|
||||
std::string GetMediaAccessStatus(const std::string& media_type,
|
||||
gin_helper::Arguments* args);
|
||||
v8::Local<v8::Promise> AskForMediaAccess(v8::Isolate* isolate,
|
||||
const std::string& media_type);
|
||||
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <windows.devices.enumeration.h>
|
||||
#include <wrl/client.h>
|
||||
#include <iomanip>
|
||||
|
||||
#include "shell/browser/api/electron_api_system_preferences.h"
|
||||
|
||||
#include "base/win/core_winrt_util.h"
|
||||
#include "base/win/wrapped_window_proc.h"
|
||||
#include "shell/common/color_util.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
@@ -20,6 +23,51 @@ namespace {
|
||||
const wchar_t kSystemPreferencesWindowClass[] =
|
||||
L"Electron_SystemPreferencesHostWindow";
|
||||
|
||||
using ABI::Windows::Devices::Enumeration::DeviceAccessStatus;
|
||||
using ABI::Windows::Devices::Enumeration::DeviceClass;
|
||||
using ABI::Windows::Devices::Enumeration::IDeviceAccessInformation;
|
||||
using ABI::Windows::Devices::Enumeration::IDeviceAccessInformationStatics;
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
DeviceAccessStatus GetDeviceAccessStatus(DeviceClass device_class) {
|
||||
ComPtr<IDeviceAccessInformationStatics> dev_access_info_statics;
|
||||
HRESULT hr = base::win::GetActivationFactory<
|
||||
IDeviceAccessInformationStatics,
|
||||
RuntimeClass_Windows_Devices_Enumeration_DeviceAccessInformation>(
|
||||
&dev_access_info_statics);
|
||||
if (FAILED(hr)) {
|
||||
VLOG(1) << "IDeviceAccessInformationStatics failed: " << hr;
|
||||
return DeviceAccessStatus::DeviceAccessStatus_Allowed;
|
||||
}
|
||||
|
||||
ComPtr<IDeviceAccessInformation> dev_access_info;
|
||||
hr = dev_access_info_statics->CreateFromDeviceClass(device_class,
|
||||
&dev_access_info);
|
||||
if (FAILED(hr)) {
|
||||
VLOG(1) << "IDeviceAccessInformation failed: " << hr;
|
||||
return DeviceAccessStatus::DeviceAccessStatus_Allowed;
|
||||
}
|
||||
|
||||
auto status = DeviceAccessStatus::DeviceAccessStatus_Unspecified;
|
||||
dev_access_info->get_CurrentStatus(&status);
|
||||
return status;
|
||||
}
|
||||
|
||||
std::string ConvertDeviceAccessStatus(DeviceAccessStatus value) {
|
||||
switch (value) {
|
||||
case DeviceAccessStatus::DeviceAccessStatus_Unspecified:
|
||||
return "not-determined";
|
||||
case DeviceAccessStatus::DeviceAccessStatus_Allowed:
|
||||
return "granted";
|
||||
case DeviceAccessStatus::DeviceAccessStatus_DeniedBySystem:
|
||||
return "restricted";
|
||||
case DeviceAccessStatus::DeviceAccessStatus_DeniedByUser:
|
||||
return "denied";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace api {
|
||||
@@ -117,6 +165,24 @@ std::string SystemPreferences::GetColor(gin_helper::ErrorThrower thrower,
|
||||
return ToRGBHex(color_utils::GetSysSkColor(id));
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetMediaAccessStatus(
|
||||
const std::string& media_type,
|
||||
gin_helper::Arguments* args) {
|
||||
if (media_type == "camera") {
|
||||
return ConvertDeviceAccessStatus(
|
||||
GetDeviceAccessStatus(DeviceClass::DeviceClass_VideoCapture));
|
||||
} else if (media_type == "microphone") {
|
||||
return ConvertDeviceAccessStatus(
|
||||
GetDeviceAccessStatus(DeviceClass::DeviceClass_AudioCapture));
|
||||
} else if (media_type == "screen") {
|
||||
return ConvertDeviceAccessStatus(
|
||||
DeviceAccessStatus::DeviceAccessStatus_Allowed);
|
||||
} else {
|
||||
args->ThrowError("Invalid media type");
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
void SystemPreferences::InitializeWindow() {
|
||||
invertered_color_scheme_ = IsInvertedColorScheme();
|
||||
high_contrast_color_scheme_ = IsHighContrastColorScheme();
|
||||
|
||||
@@ -134,8 +134,6 @@ class JSChunkedDataPipeGetter : public gin::Wrappable<JSChunkedDataPipeGetter>,
|
||||
data_producer_ = std::make_unique<mojo::DataPipeProducer>(std::move(pipe));
|
||||
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
v8::MicrotasksScope script_scope(isolate_,
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
auto maybe_wrapper = GetWrapper(isolate_);
|
||||
v8::Local<v8::Value> wrapper;
|
||||
if (!maybe_wrapper.ToLocal(&wrapper)) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -45,12 +46,17 @@
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "electron/shell/common/api/api.mojom.h"
|
||||
#include "gin/data_object_builder.h"
|
||||
#include "gin/handle.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "gin/wrappable.h"
|
||||
#include "mojo/public/cpp/bindings/associated_remote.h"
|
||||
#include "mojo/public/cpp/system/platform_handle.h"
|
||||
#include "ppapi/buildflags/buildflags.h"
|
||||
#include "shell/browser/api/electron_api_browser_window.h"
|
||||
#include "shell/browser/api/electron_api_debugger.h"
|
||||
#include "shell/browser/api/electron_api_session.h"
|
||||
#include "shell/browser/api/message_port.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/child_web_contents_tracker.h"
|
||||
#include "shell/browser/electron_autofill_driver_factory.h"
|
||||
@@ -86,8 +92,10 @@
|
||||
#include "shell/common/mouse_util.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "shell/common/v8_value_serializer.h"
|
||||
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
|
||||
#include "third_party/blink/public/common/input/web_input_event.h"
|
||||
#include "third_party/blink/public/common/messaging/transferable_message_mojom_traits.h"
|
||||
#include "third_party/blink/public/common/page/page_zoom.h"
|
||||
#include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h"
|
||||
#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
|
||||
@@ -385,6 +393,9 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
: content::WebContentsObserver(web_contents),
|
||||
type_(Type::REMOTE),
|
||||
weak_factory_(this) {
|
||||
auto session = Session::CreateFrom(isolate, GetBrowserContext());
|
||||
session_.Reset(isolate, session.ToV8());
|
||||
|
||||
web_contents->SetUserAgentOverride(blink::UserAgentOverride::UserAgentOnly(
|
||||
GetBrowserContext()->GetUserAgent()),
|
||||
false);
|
||||
@@ -988,6 +999,11 @@ void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
|
||||
|
||||
void WebContents::RenderProcessGone(base::TerminationStatus status) {
|
||||
Emit("crashed", status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
gin_helper::Dictionary details =
|
||||
gin_helper::Dictionary::CreateEmpty(isolate());
|
||||
details.Set("reason", status);
|
||||
Emit("render-process-gone", details);
|
||||
}
|
||||
|
||||
void WebContents::PluginCrashed(const base::FilePath& plugin_path,
|
||||
@@ -1131,6 +1147,49 @@ void WebContents::Invoke(bool internal,
|
||||
std::move(callback), internal, channel, std::move(arguments));
|
||||
}
|
||||
|
||||
void WebContents::ReceivePostMessage(const std::string& channel,
|
||||
blink::TransferableMessage message) {
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto wrapped_ports =
|
||||
MessagePort::EntanglePorts(isolate(), std::move(message.ports));
|
||||
v8::Local<v8::Value> message_value =
|
||||
electron::DeserializeV8Value(isolate(), message);
|
||||
EmitWithSender("-ipc-ports", bindings_.dispatch_context(), InvokeCallback(),
|
||||
false, channel, message_value, std::move(wrapped_ports));
|
||||
}
|
||||
|
||||
void WebContents::PostMessage(const std::string& channel,
|
||||
v8::Local<v8::Value> message_value,
|
||||
base::Optional<v8::Local<v8::Value>> transfer) {
|
||||
blink::TransferableMessage transferable_message;
|
||||
if (!electron::SerializeV8Value(isolate(), message_value,
|
||||
&transferable_message)) {
|
||||
// SerializeV8Value sets an exception.
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<gin::Handle<MessagePort>> wrapped_ports;
|
||||
if (transfer) {
|
||||
if (!gin::ConvertFromV8(isolate(), *transfer, &wrapped_ports)) {
|
||||
isolate()->ThrowException(v8::Exception::Error(
|
||||
gin::StringToV8(isolate(), "Invalid value for transfer")));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool threw_exception = false;
|
||||
transferable_message.ports =
|
||||
MessagePort::DisentanglePorts(isolate(), wrapped_ports, &threw_exception);
|
||||
if (threw_exception)
|
||||
return;
|
||||
|
||||
content::RenderFrameHost* frame_host = web_contents()->GetMainFrame();
|
||||
mojo::AssociatedRemote<mojom::ElectronRenderer> electron_renderer;
|
||||
frame_host->GetRemoteAssociatedInterfaces()->GetInterface(&electron_renderer);
|
||||
electron_renderer->ReceivePostMessage(channel,
|
||||
std::move(transferable_message));
|
||||
}
|
||||
|
||||
void WebContents::MessageSync(bool internal,
|
||||
const std::string& channel,
|
||||
blink::CloneableMessage arguments,
|
||||
@@ -1961,7 +2020,7 @@ void WebContents::Print(gin_helper::Arguments* args) {
|
||||
}
|
||||
|
||||
// Duplex type user wants to use.
|
||||
printing::DuplexMode duplex_mode;
|
||||
printing::DuplexMode duplex_mode = printing::SIMPLEX;
|
||||
options.Get("duplexMode", &duplex_mode);
|
||||
settings.SetIntKey(printing::kSettingDuplexMode, duplex_mode);
|
||||
|
||||
@@ -2697,6 +2756,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("isFocused", &WebContents::IsFocused)
|
||||
.SetMethod("tabTraverse", &WebContents::TabTraverse)
|
||||
.SetMethod("_send", &WebContents::SendIPCMessage)
|
||||
.SetMethod("_postMessage", &WebContents::PostMessage)
|
||||
.SetMethod("_sendToFrame", &WebContents::SendIPCMessageToFrame)
|
||||
.SetMethod("sendInputEvent", &WebContents::SendInputEvent)
|
||||
.SetMethod("beginFrameSubscription", &WebContents::BeginFrameSubscription)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user