mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
89 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
952603d9ae | ||
|
|
32b45e7783 | ||
|
|
514c1e6d4b | ||
|
|
67b04b4040 | ||
|
|
415387cc2c | ||
|
|
0826770b20 | ||
|
|
c2e22abf08 | ||
|
|
9c28c8f637 | ||
|
|
478d405d42 | ||
|
|
0b616b3e2e | ||
|
|
49711d12f8 | ||
|
|
fe56f1dda6 | ||
|
|
f10c8e6dd5 | ||
|
|
27c1fc87e3 | ||
|
|
be08ff1665 | ||
|
|
547e50c699 | ||
|
|
a06170648c | ||
|
|
88fdf8ccf5 | ||
|
|
d12be5d392 | ||
|
|
e62cd6a5fa | ||
|
|
c412f7ddf1 | ||
|
|
0afec38c81 | ||
|
|
38f0a8e85b | ||
|
|
0aa7b7f712 | ||
|
|
23bd9166d7 | ||
|
|
c374f20fd1 | ||
|
|
b5839f42a2 | ||
|
|
2dcfefa577 | ||
|
|
b045ee77af | ||
|
|
32c2736c07 | ||
|
|
91d1bd651e | ||
|
|
c8177f8418 | ||
|
|
b8c086613f | ||
|
|
2e80a2e447 | ||
|
|
936a1659f6 | ||
|
|
d7289cbb55 | ||
|
|
aab0c66817 | ||
|
|
e671c2c053 | ||
|
|
c7778a8f2f | ||
|
|
c35803aee1 | ||
|
|
9f2fc5d72c | ||
|
|
a65fe57342 | ||
|
|
473219bfbe | ||
|
|
a8196fbc18 | ||
|
|
6b8ca86459 | ||
|
|
7290d77cdc | ||
|
|
426d45cd85 | ||
|
|
79298d37cd | ||
|
|
2a44b1a20f | ||
|
|
6f331e4f6a | ||
|
|
dc71541641 | ||
|
|
a4de4793dd | ||
|
|
f7509d590c | ||
|
|
42ab97f905 | ||
|
|
faf2871efe | ||
|
|
ea4e92f64d | ||
|
|
15d792aded | ||
|
|
70f05a1579 | ||
|
|
2d40fad79e | ||
|
|
edabc96e75 | ||
|
|
4a45196ff1 | ||
|
|
0bd661bd99 | ||
|
|
b9e709039e | ||
|
|
c63430c5d0 | ||
|
|
60bcf42edf | ||
|
|
d5f9654c12 | ||
|
|
d2fb214a54 | ||
|
|
6294f811a7 | ||
|
|
30ae6f45a4 | ||
|
|
60ef8ac58d | ||
|
|
6c42564337 | ||
|
|
479fc57cef | ||
|
|
b2fb14fd48 | ||
|
|
d8f90444aa | ||
|
|
045331666c | ||
|
|
0ac42125d2 | ||
|
|
ce04014739 | ||
|
|
19bd97d80c | ||
|
|
ea2e34c4c3 | ||
|
|
5f6498d13a | ||
|
|
e3c1292548 | ||
|
|
b3e53839a4 | ||
|
|
f3e9f10cad | ||
|
|
2c8927a9a2 | ||
|
|
c6786aed26 | ||
|
|
5b3b09fb7f | ||
|
|
9f5924c5ea | ||
|
|
25f5d764ac | ||
|
|
941c72fcfe |
@@ -605,8 +605,10 @@ step-mksnapshot-build: &step-mksnapshot-build
|
||||
if [ "`uname`" != "Darwin" ]; then
|
||||
if [ "$TARGET_ARCH" == "arm" ]; then
|
||||
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x86_v8_arm/mksnapshot
|
||||
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x86_v8_arm/v8_context_snapshot_generator
|
||||
elif [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x64_v8_arm64/mksnapshot
|
||||
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x64_v8_arm64/v8_context_snapshot_generator
|
||||
else
|
||||
electron/script/strip-binaries.py --file $PWD/out/Default/mksnapshot
|
||||
electron/script/strip-binaries.py --file $PWD/out/Default/v8_context_snapshot_generator
|
||||
|
||||
13
BUILD.gn
13
BUILD.gn
@@ -358,6 +358,7 @@ 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",
|
||||
@@ -549,6 +550,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",
|
||||
]
|
||||
@@ -1355,7 +1366,7 @@ dist_zip("electron_chromedriver_zip") {
|
||||
|
||||
mksnapshot_deps = [
|
||||
":licenses",
|
||||
"//tools/v8_context_snapshot:v8_context_snapshot_generator",
|
||||
"//tools/v8_context_snapshot:v8_context_snapshot_generator($v8_snapshot_toolchain)",
|
||||
"//v8:mksnapshot($v8_snapshot_toolchain)",
|
||||
]
|
||||
|
||||
|
||||
2
DEPS
2
DEPS
@@ -11,7 +11,7 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'80.0.3987.163',
|
||||
'80.0.3987.165',
|
||||
'node_version':
|
||||
'v12.13.0',
|
||||
'nan_version':
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.2.3
|
||||
8.3.2
|
||||
@@ -88,5 +88,6 @@ steps:
|
||||
- powershell: |
|
||||
Get-Process | Where Name –Like "electron*" | Stop-Process
|
||||
Get-Process | Where Name –Like "MicrosoftEdge*" | Stop-Process
|
||||
Get-Process | Where Name –Like "msedge*" | Stop-Process
|
||||
displayName: 'Kill processes left running from last test run'
|
||||
condition: always()
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -24,7 +24,8 @@ module.exports = ({
|
||||
alwaysHasNode,
|
||||
loadElectronFromAlternateTarget,
|
||||
targetDeletesNodeGlobals,
|
||||
target
|
||||
target,
|
||||
wrapInitWithProfilingTimeout
|
||||
}) => {
|
||||
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts')
|
||||
if (!fs.existsSync(entry)) {
|
||||
@@ -39,6 +40,7 @@ module.exports = ({
|
||||
output: {
|
||||
filename: `${target}.bundle.js`
|
||||
},
|
||||
wrapInitWithProfilingTimeout,
|
||||
resolve: {
|
||||
alias: {
|
||||
'@electron/internal': path.resolve(electronRoot, 'lib'),
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -564,11 +564,17 @@ Returns `Promise<void>` - fulfilled when Electron is initialized.
|
||||
May be used as a convenient alternative to checking `app.isReady()`
|
||||
and subscribing to the `ready` event if the app is not ready yet.
|
||||
|
||||
### `app.focus()`
|
||||
### `app.focus([options])`
|
||||
|
||||
* `options` Object (optional)
|
||||
* `steal` Boolean _macOS_ - Make the receiver the active app even if another app is
|
||||
currently active.
|
||||
|
||||
On Linux, focuses on the first visible window. On macOS, makes the application
|
||||
the active app. On Windows, focuses on the application's first window.
|
||||
|
||||
You should seek to use the `steal` option as sparingly as possible.
|
||||
|
||||
### `app.hide()` _macOS_
|
||||
|
||||
Hides all application windows without minimizing them.
|
||||
@@ -669,8 +675,6 @@ to the npm modules spec. You should usually also specify a `productName`
|
||||
field, which is your application's full capitalized name, and which will be
|
||||
preferred over `name` by Electron.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
### `app.setName(name)`
|
||||
|
||||
* `name` String
|
||||
@@ -679,8 +683,6 @@ Overrides the current application's name.
|
||||
|
||||
**Note:** This function overrides the name used internally by Electron; it does not affect the name that the OS uses.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
### `app.getLocale()`
|
||||
|
||||
Returns `String` - The current application locale. Possible return values are documented [here](locales.md).
|
||||
@@ -1088,14 +1090,10 @@ On macOS, it shows on the dock icon. On Linux, it only works for Unity launcher.
|
||||
**Note:** Unity launcher requires the existence of a `.desktop` file to work,
|
||||
for more information please read [Desktop Environment Integration][unity-requirement].
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
### `app.getBadgeCount()` _Linux_ _macOS_
|
||||
|
||||
Returns `Integer` - The current value displayed in the counter badge.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
### `app.isUnityRunning()` _Linux_
|
||||
|
||||
Returns `Boolean` - Whether the current desktop environment is Unity launcher.
|
||||
@@ -1170,8 +1168,6 @@ technologies, such as screen readers, has been detected. See
|
||||
https://www.chromium.org/developers/design-documents/accessibility for more
|
||||
details.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
### `app.setAccessibilitySupportEnabled(enabled)` _macOS_ _Windows_
|
||||
|
||||
* `enabled` Boolean - Enable or disable [accessibility tree](https://developers.google.com/web/fundamentals/accessibility/semantics-builtin/the-accessibility-tree) rendering
|
||||
@@ -1183,8 +1179,6 @@ This API must be called after the `ready` event is emitted.
|
||||
|
||||
**Note:** Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
### `app.showAboutPanel()`
|
||||
|
||||
Show the app's about panel options. These options can be overridden with `app.setAboutPanelOptions(options)`.
|
||||
|
||||
@@ -388,6 +388,15 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
visible to users.
|
||||
* `spellcheck` Boolean (optional) - Whether to enable the builtin spellchecker.
|
||||
Default is `false`.
|
||||
* `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
|
||||
@@ -1104,15 +1113,11 @@ Returns `Integer[]` - Contains the window's maximum width and height.
|
||||
|
||||
* `resizable` Boolean
|
||||
|
||||
Sets whether the window can be manually resized by user.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
Sets whether the window can be manually resized by the user.
|
||||
|
||||
#### `win.isResizable()`
|
||||
|
||||
Returns `Boolean` - Whether the window can be manually resized by user.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
Returns `Boolean` - Whether the window can be manually resized by the user.
|
||||
|
||||
#### `win.setMovable(movable)` _macOS_ _Windows_
|
||||
|
||||
@@ -1120,41 +1125,29 @@ Returns `Boolean` - Whether the window can be manually resized by user.
|
||||
|
||||
Sets whether the window can be moved by user. On Linux does nothing.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `win.isMovable()` _macOS_ _Windows_
|
||||
|
||||
Returns `Boolean` - Whether the window can be moved by user.
|
||||
|
||||
On Linux always returns `true`.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `win.setMinimizable(minimizable)` _macOS_ _Windows_
|
||||
|
||||
* `minimizable` Boolean
|
||||
|
||||
Sets whether the window can be manually minimized by user. On Linux does
|
||||
nothing.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
Sets whether the window can be manually minimized by user. On Linux does nothing.
|
||||
|
||||
#### `win.isMinimizable()` _macOS_ _Windows_
|
||||
|
||||
Returns `Boolean` - Whether the window can be manually minimized by user
|
||||
Returns `Boolean` - Whether the window can be manually minimized by the user.
|
||||
|
||||
On Linux always returns `true`.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `win.setMaximizable(maximizable)` _macOS_ _Windows_
|
||||
|
||||
* `maximizable` Boolean
|
||||
|
||||
Sets whether the window can be manually maximized by user. On Linux does
|
||||
nothing.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
Sets whether the window can be manually maximized by user. On Linux does nothing.
|
||||
|
||||
#### `win.isMaximizable()` _macOS_ _Windows_
|
||||
|
||||
@@ -1162,23 +1155,15 @@ Returns `Boolean` - Whether the window can be manually maximized by user.
|
||||
|
||||
On Linux always returns `true`.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `win.setFullScreenable(fullscreenable)`
|
||||
|
||||
* `fullscreenable` Boolean
|
||||
|
||||
Sets whether the maximize/zoom window button toggles fullscreen mode or
|
||||
maximizes the window.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
Sets whether the maximize/zoom window button toggles fullscreen mode or maximizes the window.
|
||||
|
||||
#### `win.isFullScreenable()`
|
||||
|
||||
Returns `Boolean` - Whether the maximize/zoom window button toggles fullscreen mode or
|
||||
maximizes the window.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
Returns `Boolean` - Whether the maximize/zoom window button toggles fullscreen mode or maximizes the window.
|
||||
|
||||
#### `win.setClosable(closable)` _macOS_ _Windows_
|
||||
|
||||
@@ -1186,16 +1171,12 @@ maximizes the window.
|
||||
|
||||
Sets whether the window can be manually closed by user. On Linux does nothing.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `win.isClosable()` _macOS_ _Windows_
|
||||
|
||||
Returns `Boolean` - Whether the window can be manually closed by user.
|
||||
|
||||
On Linux always returns `true`.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `win.setAlwaysOnTop(flag[, level][, relativeLevel])`
|
||||
|
||||
* `flag` Boolean
|
||||
@@ -1607,23 +1588,17 @@ This cannot be called when `titleBarStyle` is set to `customButtonsOnHover`.
|
||||
Sets whether the window menu bar should hide itself automatically. Once set the
|
||||
menu bar will only show when users press the single `Alt` key.
|
||||
|
||||
If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't
|
||||
hide it immediately.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't hide it immediately.
|
||||
|
||||
#### `win.isMenuBarAutoHide()`
|
||||
|
||||
Returns `Boolean` - Whether menu bar automatically hides itself.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `win.setMenuBarVisibility(visible)` _Windows_ _Linux_
|
||||
|
||||
* `visible` Boolean
|
||||
|
||||
Sets whether the menu bar should be visible. If the menu bar is auto-hide, users
|
||||
can still bring up the menu bar by pressing the single `Alt` key.
|
||||
Sets whether the menu bar should be visible. If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single `Alt` key.
|
||||
|
||||
#### `win.isMenuBarVisible()`
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -82,16 +82,12 @@ The API is only available in session's `will-download` callback function.
|
||||
If user doesn't set the save path via the API, Electron will use the original
|
||||
routine to determine the save path; this usually prompts a save dialog.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md): use the `savePath` property instead.**
|
||||
|
||||
#### `downloadItem.getSavePath()`
|
||||
|
||||
Returns `String` - The save path of the download item. This will be either the path
|
||||
set via `downloadItem.setSavePath(path)` or the path selected from the shown
|
||||
save dialog.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md): use the `savePath` property instead.**
|
||||
|
||||
#### `downloadItem.setSaveDialogOptions(options)`
|
||||
|
||||
* `options` SaveDialogOptions - Set the save file dialog options. This object has the same
|
||||
|
||||
@@ -128,3 +128,14 @@ the one downloaded by `npm install`. Usage:
|
||||
```sh
|
||||
export ELECTRON_OVERRIDE_DIST_PATH=/Users/username/projects/electron/out/Debug
|
||||
```
|
||||
|
||||
## Set By Electron
|
||||
|
||||
Electron sets some variables in your environment at runtime.
|
||||
|
||||
### `ORIGINAL_XDG_CURRENT_DESKTOP`
|
||||
|
||||
This variable is set to the value of `XDG_CURRENT_DESKTOP` that your application
|
||||
originally launched with. Electron sometimes modifies the value of `XDG_CURRENT_DESKTOP`
|
||||
to affect other logic within Chromium so if you want access to the _original_ value
|
||||
you should look up this environment variable instead.
|
||||
|
||||
@@ -69,6 +69,7 @@ a `type`.
|
||||
The `role` property can have following values:
|
||||
|
||||
* `undo`
|
||||
* `about` - Trigger a native about panel (custom message box on Window, which does not provide its own).
|
||||
* `redo`
|
||||
* `cut`
|
||||
* `copy`
|
||||
@@ -94,7 +95,6 @@ The `role` property can have following values:
|
||||
The following additional roles are available on _macOS_:
|
||||
|
||||
* `appMenu` - Whole default "App" menu (About, Services, etc.)
|
||||
* `about` - Map to the `orderFrontStandardAboutPanel` action.
|
||||
* `hide` - Map to the `hide` action.
|
||||
* `hideOthers` - Map to the `hideOtherApplications` action.
|
||||
* `unhide` - Map to the `unhideAllApplications` action.
|
||||
|
||||
@@ -45,9 +45,3 @@ The Electron team is currently undergoing an initiative to convert separate gett
|
||||
* `isMacTemplateImage`
|
||||
* `SystemPreferences` module
|
||||
* `appLevelAppearance`
|
||||
* `webContents` module
|
||||
* `audioMuted`
|
||||
* `frameRate`
|
||||
* `userAgent`
|
||||
* `zoomFactor`
|
||||
* `zoomLevel`
|
||||
|
||||
@@ -276,14 +276,10 @@ Returns [`Size`](structures/size.md)
|
||||
|
||||
Marks the image as a template image.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `image.isTemplateImage()`
|
||||
|
||||
Returns `Boolean` - Whether the image is a template image.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `image.crop(rect)`
|
||||
|
||||
* `rect` [Rectangle](structures/rectangle.md) - The area of the image to crop.
|
||||
|
||||
4
docs/api/structures/new-window-event.md
Normal file
4
docs/api/structures/new-window-event.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# NewWindowEvent Object extends `Event`
|
||||
|
||||
* `newGuest` BrowserWindow (optional)
|
||||
|
||||
@@ -360,7 +360,7 @@ Returns `Boolean` - `true` if an inverted color scheme (a high contrast color sc
|
||||
|
||||
Returns `Boolean` - `true` if a high contrast theme is active, `false` otherwise.
|
||||
|
||||
**Depreacted:** Should use the new [`nativeTheme.shouldUseHighContrastColors`](native-theme.md#nativethemeshouldusehighcontrastcolors-macos-windows-readonly) API.
|
||||
**Deprecated:** Should use the new [`nativeTheme.shouldUseHighContrastColors`](native-theme.md#nativethemeshouldusehighcontrastcolors-macos-windows-readonly) API.
|
||||
|
||||
### `systemPreferences.getEffectiveAppearance()` _macOS_
|
||||
|
||||
@@ -369,8 +369,6 @@ Returns `String` - Can be `dark`, `light` or `unknown`.
|
||||
Gets the macOS appearance setting that is currently applied to your application,
|
||||
maps to [NSApplication.effectiveAppearance](https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance?language=objc)
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
### `systemPreferences.getAppLevelAppearance()` _macOS_ _Deprecated_
|
||||
|
||||
Returns `String` | `null` - Can be `dark`, `light` or `unknown`.
|
||||
@@ -379,8 +377,6 @@ Gets the macOS appearance setting that you have declared you want for
|
||||
your application, maps to [NSApplication.appearance](https://developer.apple.com/documentation/appkit/nsapplication/2967170-appearance?language=objc).
|
||||
You can use the `setAppLevelAppearance` API to set this value.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
### `systemPreferences.setAppLevelAppearance(appearance)` _macOS_ _Deprecated_
|
||||
|
||||
* `appearance` String | null - Can be `dark` or `light`
|
||||
@@ -388,8 +384,6 @@ You can use the `setAppLevelAppearance` API to set this value.
|
||||
Sets the appearance setting for your application, this should override the
|
||||
system default and override the value of `getEffectiveAppearance`.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
### `systemPreferences.canPromptTouchID()` _macOS_
|
||||
|
||||
Returns `Boolean` - whether or not this device has the ability to use Touch ID.
|
||||
|
||||
@@ -138,7 +138,7 @@ Emitted when page receives favicon urls.
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `event` NewWindowEvent
|
||||
* `url` String
|
||||
* `frameName` String
|
||||
* `disposition` String - Can be `default`, `foreground-tab`, `background-tab`,
|
||||
@@ -366,6 +366,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].
|
||||
@@ -882,10 +883,10 @@ Returns `String` - The URL of the current web page.
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow({ width: 800, height: 600 })
|
||||
win.loadURL('http://github.com')
|
||||
|
||||
let currentURL = win.webContents.getURL()
|
||||
console.log(currentURL)
|
||||
win.loadURL('http://github.com').then(() => {
|
||||
const currentURL = win.webContents.getURL()
|
||||
console.log(currentURL)
|
||||
})
|
||||
```
|
||||
|
||||
#### `contents.getTitle()`
|
||||
@@ -978,14 +979,10 @@ Returns `Boolean` - Whether the renderer process has crashed.
|
||||
|
||||
Overrides the user agent for this web page.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `contents.getUserAgent()`
|
||||
|
||||
Returns `String` - The user agent for this web page.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `contents.insertCSS(css[, options])`
|
||||
|
||||
* `css` String
|
||||
@@ -1065,14 +1062,10 @@ Ignore application menu shortcuts while this web contents is focused.
|
||||
|
||||
Mute the audio on the current web page.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `contents.isAudioMuted()`
|
||||
|
||||
Returns `Boolean` - Whether this page has been muted.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `contents.isCurrentlyAudible()`
|
||||
|
||||
Returns `Boolean` - Whether audio is currently playing.
|
||||
@@ -1086,14 +1079,10 @@ zoom percent divided by 100, so 300% = 3.0.
|
||||
|
||||
The factor must be greater than 0.0.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `contents.getZoomFactor()`
|
||||
|
||||
Returns `Number` - the current zoom factor.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `contents.setZoomLevel(level)`
|
||||
|
||||
* `level` Number - Zoom level.
|
||||
@@ -1103,14 +1092,10 @@ increment above or below represents zooming 20% larger or smaller to default
|
||||
limits of 300% and 50% of original size, respectively. The formula for this is
|
||||
`scale := 1.2 ^ level`.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `contents.getZoomLevel()`
|
||||
|
||||
Returns `Number` - the current zoom level.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `contents.setVisualZoomLevelLimits(minimumLevel, maximumLevel)`
|
||||
|
||||
* `minimumLevel` Number
|
||||
@@ -1713,14 +1698,10 @@ Returns `Boolean` - If *offscreen rendering* is enabled returns whether it is cu
|
||||
If *offscreen rendering* is enabled sets the frame rate to the specified number.
|
||||
Only values between 1 and 60 are accepted.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `contents.getFrameRate()`
|
||||
|
||||
Returns `Integer` - If *offscreen rendering* is enabled returns the current frame rate.
|
||||
|
||||
**[Deprecated](modernization/property-updates.md)**
|
||||
|
||||
#### `contents.invalidate()`
|
||||
|
||||
Schedules a full repaint of the window this web contents is in.
|
||||
@@ -1826,7 +1807,7 @@ A [`WebContents`](web-contents.md) instance that might own this `WebContents`.
|
||||
|
||||
#### `contents.devToolsWebContents` _Readonly_
|
||||
|
||||
A `WebContents` of DevTools for this `WebContents`.
|
||||
A `WebContents | null` property that represents the of DevTools `WebContents` associated with a given `WebContents`.
|
||||
|
||||
**Note:** Users should never store this object because it may become `null`
|
||||
when the DevTools has been closed.
|
||||
|
||||
@@ -154,10 +154,14 @@ this limitation.
|
||||
* `userGesture` Boolean (optional) - Default is `false`.
|
||||
|
||||
Returns `Promise<any>` - A promise that resolves with the result of the executed code
|
||||
or is rejected if the result of the code is a rejected promise.
|
||||
or is rejected if execution could not start.
|
||||
|
||||
Works like `executeJavaScript` but evaluates `scripts` in an isolated context.
|
||||
|
||||
Note that when the execution of script fails, the returned promise will not
|
||||
reject and the `result` would be `undefined`. This is because Chromium does not
|
||||
dispatch errors of isolated worlds to foreign worlds.
|
||||
|
||||
### `webFrame.setIsolatedWorldInfo(worldId, info)`
|
||||
* `worldId` Integer - The ID of the world to run the javascript in, `0` is the default world, `999` is the world used by Electrons `contextIsolation` feature. Chrome extensions reserve the range of IDs in `[1 << 20, 1 << 29)`. You can provide any integer here.
|
||||
* `info` Object
|
||||
|
||||
@@ -54,7 +54,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/mojo/public/js/mojo_bindings_resources.pak",
|
||||
"$root_gen_dir/net/net_resources.pak",
|
||||
@@ -65,7 +67,9 @@ template("electron_extra_paks") {
|
||||
deps = [
|
||||
"//components/resources",
|
||||
"//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",
|
||||
|
||||
@@ -96,6 +96,7 @@ auto_filenames = {
|
||||
"docs/api/structures/mime-typed-buffer.md",
|
||||
"docs/api/structures/mouse-input-event.md",
|
||||
"docs/api/structures/mouse-wheel-input-event.md",
|
||||
"docs/api/structures/new-window-event.md",
|
||||
"docs/api/structures/notification-action.md",
|
||||
"docs/api/structures/point.md",
|
||||
"docs/api/structures/printer-info.md",
|
||||
@@ -177,11 +178,8 @@ auto_filenames = {
|
||||
isolated_bundle_deps = [
|
||||
"lib/common/electron-binding-setup.ts",
|
||||
"lib/isolated_renderer/init.js",
|
||||
"lib/renderer/ipc-renderer-internal-utils.ts",
|
||||
"lib/renderer/ipc-renderer-internal.ts",
|
||||
"lib/renderer/web-view/web-view-constants.ts",
|
||||
"lib/renderer/web-view/web-view-element.ts",
|
||||
"lib/renderer/window-setup.ts",
|
||||
"package.json",
|
||||
"tsconfig.electron.json",
|
||||
"tsconfig.json",
|
||||
@@ -191,6 +189,7 @@ auto_filenames = {
|
||||
"lib/common/electron-binding-setup.ts",
|
||||
"lib/common/webpack-globals-provider.ts",
|
||||
"lib/content_script/init.js",
|
||||
"lib/renderer/api/context-bridge.ts",
|
||||
"lib/renderer/chrome-api.ts",
|
||||
"lib/renderer/extensions/event.ts",
|
||||
"lib/renderer/extensions/i18n.ts",
|
||||
|
||||
@@ -389,6 +389,8 @@ filenames = {
|
||||
"shell/browser/ui/views/submenu_button.h",
|
||||
"shell/browser/ui/views/win_frame_view.cc",
|
||||
"shell/browser/ui/views/win_frame_view.h",
|
||||
"shell/browser/ui/win/dialog_thread.cc",
|
||||
"shell/browser/ui/win/dialog_thread.h",
|
||||
"shell/browser/ui/win/electron_desktop_native_widget_aura.cc",
|
||||
"shell/browser/ui/win/electron_desktop_native_widget_aura.h",
|
||||
"shell/browser/ui/win/electron_desktop_window_tree_host_win.cc",
|
||||
@@ -518,6 +520,10 @@ filenames = {
|
||||
"shell/common/key_weak_map.h",
|
||||
"shell/common/keyboard_util.cc",
|
||||
"shell/common/keyboard_util.h",
|
||||
"shell/common/language_util.h",
|
||||
"shell/common/language_util_linux.cc",
|
||||
"shell/common/language_util_mac.mm",
|
||||
"shell/common/language_util_win.cc",
|
||||
"shell/common/mac/main_application_bundle.h",
|
||||
"shell/common/mac/main_application_bundle.mm",
|
||||
"shell/common/mouse_util.cc",
|
||||
@@ -568,8 +574,6 @@ filenames = {
|
||||
"shell/common/skia_util.h",
|
||||
"shell/renderer/api/context_bridge/object_cache.cc",
|
||||
"shell/renderer/api/context_bridge/object_cache.h",
|
||||
"shell/renderer/api/context_bridge/render_frame_function_store.cc",
|
||||
"shell/renderer/api/context_bridge/render_frame_function_store.h",
|
||||
"shell/renderer/api/electron_api_context_bridge.cc",
|
||||
"shell/renderer/api/electron_api_context_bridge.h",
|
||||
"shell/renderer/api/electron_api_renderer_ipc.cc",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
import { deprecate, Menu } from 'electron';
|
||||
import { Menu } from 'electron';
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
const bindings = process.electronBinding('app');
|
||||
@@ -17,6 +17,29 @@ let dockMenu: Electron.Menu | null = null;
|
||||
Object.setPrototypeOf(App.prototype, EventEmitter.prototype);
|
||||
EventEmitter.call(app as any);
|
||||
|
||||
// Properties.
|
||||
|
||||
const nativeASGetter = app.isAccessibilitySupportEnabled;
|
||||
const nativeASSetter = app.setAccessibilitySupportEnabled;
|
||||
Object.defineProperty(App.prototype, 'accessibilitySupportEnabled', {
|
||||
get: () => nativeASGetter.call(app),
|
||||
set: (enabled) => nativeASSetter.call(app, enabled)
|
||||
});
|
||||
|
||||
const nativeBCGetter = app.getBadgeCount;
|
||||
const nativeBCSetter = app.setBadgeCount;
|
||||
Object.defineProperty(App.prototype, 'badgeCount', {
|
||||
get: () => nativeBCGetter.call(app),
|
||||
set: (count) => nativeBCSetter.call(app, count)
|
||||
});
|
||||
|
||||
const nativeNGetter = app.getName;
|
||||
const nativeNSetter = app.setName;
|
||||
Object.defineProperty(App.prototype, 'name', {
|
||||
get: () => nativeNGetter.call(app),
|
||||
set: (name) => nativeNSetter.call(app, name)
|
||||
});
|
||||
|
||||
Object.assign(app, {
|
||||
commandLine: {
|
||||
hasSwitch: (theSwitch: string) => commandLine.hasSwitch(String(theSwitch)),
|
||||
@@ -112,11 +135,6 @@ for (const name of events) {
|
||||
});
|
||||
}
|
||||
|
||||
// Property Deprecations
|
||||
deprecate.fnToProperty(App.prototype, 'accessibilitySupportEnabled', '_isAccessibilitySupportEnabled', '_setAccessibilitySupportEnabled');
|
||||
deprecate.fnToProperty(App.prototype, 'badgeCount', '_getBadgeCount', '_setBadgeCount');
|
||||
deprecate.fnToProperty(App.prototype, 'name', '_getName', '_setName');
|
||||
|
||||
// Wrappers for native classes.
|
||||
const { DownloadItem } = process.electronBinding('download_item');
|
||||
Object.setPrototypeOf(DownloadItem.prototype, EventEmitter.prototype);
|
||||
|
||||
@@ -92,6 +92,43 @@ BrowserWindow.prototype._init = function () {
|
||||
return this.webContents.devToolsWebContents;
|
||||
}
|
||||
});
|
||||
|
||||
// Properties
|
||||
|
||||
Object.defineProperty(this, 'autoHideMenuBar', {
|
||||
get: () => this.isMenuBarAutoHide(),
|
||||
set: (autoHide) => this.setAutoHideMenuBar(autoHide)
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'minimizable', {
|
||||
get: () => this.isMinimizable(),
|
||||
set: (min) => this.setMinimizable(min)
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'maximizable', {
|
||||
get: () => this.isMaximizable(),
|
||||
set: (max) => this.setMaximizable(max)
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'resizable', {
|
||||
get: () => this.isResizable(),
|
||||
set: (res) => this.setResizable(res)
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'fullScreenable', {
|
||||
get: () => this.isFullScreenable(),
|
||||
set: (full) => this.setFullScreenable(full)
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'closable', {
|
||||
get: () => this.isClosable(),
|
||||
set: (close) => this.setClosable(close)
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'movable', {
|
||||
get: () => this.isMovable(),
|
||||
set: (move) => this.setMovable(move)
|
||||
});
|
||||
};
|
||||
|
||||
const isBrowserWindow = (win) => {
|
||||
@@ -185,13 +222,4 @@ Object.assign(BrowserWindow.prototype, {
|
||||
}
|
||||
});
|
||||
|
||||
// Deprecations
|
||||
deprecate.fnToProperty(BrowserWindow.prototype, 'autoHideMenuBar', '_isMenuBarAutoHide', '_setAutoHideMenuBar');
|
||||
deprecate.fnToProperty(BrowserWindow.prototype, 'minimizable', '_isMinimizable', '_setMinimizable');
|
||||
deprecate.fnToProperty(BrowserWindow.prototype, 'maximizable', '_isMaximizable', '_setMaximizable');
|
||||
deprecate.fnToProperty(BrowserWindow.prototype, 'resizable', '_isResizable', '_setResizable');
|
||||
deprecate.fnToProperty(BrowserWindow.prototype, 'fullScreenable', '_isFullScreenable', '_setFullScreenable');
|
||||
deprecate.fnToProperty(BrowserWindow.prototype, 'closable', '_isClosable', '_setClosable');
|
||||
deprecate.fnToProperty(BrowserWindow.prototype, 'movable', '_isMovable', '_setMovable');
|
||||
|
||||
module.exports = BrowserWindow;
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ const roles = {
|
||||
about: {
|
||||
get label () {
|
||||
return isLinux ? 'About' : `About ${app.name}`;
|
||||
}
|
||||
},
|
||||
...(isWindows && { appMethod: 'showAboutPanel' })
|
||||
},
|
||||
close: {
|
||||
label: isMac ? 'Close Window' : 'Close',
|
||||
|
||||
@@ -371,6 +371,7 @@ class ClientRequest extends Writable {
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
this._urlLoaderOptions.referrer = this._urlLoaderOptions.extraHeaders.referer || '';
|
||||
const opts = { ...this._urlLoaderOptions, extraHeaders: stringifyValues(this._urlLoaderOptions.extraHeaders) };
|
||||
this._urlLoader = new URLLoader(opts);
|
||||
this._urlLoader.on('response-started', (event, finalUrl, responseHead) => {
|
||||
|
||||
@@ -6,21 +6,20 @@ const { systemPreferences, SystemPreferences } = process.electronBinding('system
|
||||
Object.setPrototypeOf(SystemPreferences.prototype, EventEmitter.prototype);
|
||||
EventEmitter.call(systemPreferences);
|
||||
|
||||
if ('appLevelAppearance' in systemPreferences) {
|
||||
deprecate.fnToProperty(
|
||||
SystemPreferences.prototype,
|
||||
'appLevelAppearance',
|
||||
'_getAppLevelAppearance',
|
||||
'_setAppLevelAppearance'
|
||||
);
|
||||
if ('getAppLevelAppearance' in systemPreferences) {
|
||||
const nativeALAGetter = systemPreferences.getAppLevelAppearance;
|
||||
const nativeALASetter = systemPreferences.setAppLevelAppearance;
|
||||
Object.defineProperty(SystemPreferences.prototype, 'appLevelAppearance', {
|
||||
get: () => nativeALAGetter.call(systemPreferences),
|
||||
set: (appearance) => nativeALASetter.call(systemPreferences, appearance)
|
||||
});
|
||||
}
|
||||
|
||||
if ('effectiveAppearance' in systemPreferences) {
|
||||
deprecate.fnToProperty(
|
||||
SystemPreferences.prototype,
|
||||
'effectiveAppearance',
|
||||
'_getEffectiveAppearance'
|
||||
);
|
||||
if ('getEffectiveAppearance' in systemPreferences) {
|
||||
const nativeEAGetter = systemPreferences.getAppLevelAppearance;
|
||||
Object.defineProperty(SystemPreferences.prototype, 'effectiveAppearance', {
|
||||
get: () => nativeEAGetter.call(systemPreferences)
|
||||
});
|
||||
}
|
||||
|
||||
SystemPreferences.prototype.isDarkMode = deprecate.moveAPI(
|
||||
|
||||
@@ -429,6 +429,11 @@ WebContents.prototype._init = function () {
|
||||
const referrer = { url: '', policy: 'default' };
|
||||
internalWindowOpen(event, url, referrer, frameName, disposition, options);
|
||||
});
|
||||
|
||||
const prefs = this.getWebPreferences() || {};
|
||||
if (prefs.webviewTag && prefs.contextIsolation) {
|
||||
electron.deprecate.log('Security Warning: A WebContents was just created with both webviewTag and contextIsolation enabled. This combination is fundamentally less secure and effectively bypasses the protections of contextIsolation. We strongly recommend you move away from webviews to OOPIF or BrowserView in order for your app to be more secure');
|
||||
}
|
||||
}
|
||||
|
||||
this.on('login', (event, ...args) => {
|
||||
@@ -437,14 +442,34 @@ WebContents.prototype._init = function () {
|
||||
|
||||
const event = process.electronBinding('event').createEmpty();
|
||||
app.emit('web-contents-created', event, this);
|
||||
};
|
||||
|
||||
// Deprecations
|
||||
deprecate.fnToProperty(WebContents.prototype, 'audioMuted', '_isAudioMuted', '_setAudioMuted');
|
||||
deprecate.fnToProperty(WebContents.prototype, 'userAgent', '_getUserAgent', '_setUserAgent');
|
||||
deprecate.fnToProperty(WebContents.prototype, 'zoomLevel', '_getZoomLevel', '_setZoomLevel');
|
||||
deprecate.fnToProperty(WebContents.prototype, 'zoomFactor', '_getZoomFactor', '_setZoomFactor');
|
||||
deprecate.fnToProperty(WebContents.prototype, 'frameRate', '_getFrameRate', '_setFrameRate');
|
||||
// Properties
|
||||
|
||||
Object.defineProperty(this, 'audioMuted', {
|
||||
get: () => this.isAudioMuted(),
|
||||
set: (muted) => this.setAudioMuted(muted)
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'userAgent', {
|
||||
get: () => this.getUserAgent(),
|
||||
set: (agent) => this.setUserAgent(agent)
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'zoomLevel', {
|
||||
get: () => this.getZoomLevel(),
|
||||
set: (level) => this.setZoomLevel(level)
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'zoomFactor', {
|
||||
get: () => this.getZoomFactor(),
|
||||
set: (factor) => this.setZoomFactor(factor)
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'frameRate', {
|
||||
get: () => this.getFrameRate(),
|
||||
set: (rate) => this.setFrameRate(rate)
|
||||
});
|
||||
};
|
||||
|
||||
// JavaScript wrapper of Debugger.
|
||||
const { Debugger } = process.electronBinding('debugger');
|
||||
|
||||
@@ -232,7 +232,8 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn
|
||||
['nodeIntegration', false],
|
||||
['enableRemoteModule', false],
|
||||
['sandbox', true],
|
||||
['nodeIntegrationInSubFrames', false]
|
||||
['nodeIntegrationInSubFrames', false],
|
||||
['enableWebSQL', false]
|
||||
]);
|
||||
|
||||
// Inherit certain option values from embedder
|
||||
@@ -266,6 +267,9 @@ const attachGuest = function (event, embedderFrameId, elementInstanceId, guestIn
|
||||
// Remove an guest-embedder relationship.
|
||||
const detachGuest = function (embedder, guestInstanceId) {
|
||||
const guestInstance = guestInstances[guestInstanceId];
|
||||
|
||||
if (!guestInstance) return;
|
||||
|
||||
if (embedder !== guestInstance.embedder) {
|
||||
return;
|
||||
}
|
||||
@@ -360,6 +364,10 @@ handleMessage('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, embed
|
||||
}
|
||||
});
|
||||
|
||||
handleMessageSync('ELECTRON_GUEST_VIEW_MANAGER_DETACH_GUEST', function (event, guestInstanceId) {
|
||||
return detachGuest(event.sender, guestInstanceId);
|
||||
});
|
||||
|
||||
// this message is sent by the actual <webview>
|
||||
ipcMainInternal.on('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', function (event, focus, guestInstanceId) {
|
||||
const guest = getGuest(guestInstanceId);
|
||||
|
||||
@@ -19,7 +19,8 @@ const inheritedWebPreferences = new Map([
|
||||
['enableRemoteModule', false],
|
||||
['sandbox', true],
|
||||
['webviewTag', false],
|
||||
['nodeIntegrationInSubFrames', false]
|
||||
['nodeIntegrationInSubFrames', false],
|
||||
['enableWebSQL', false]
|
||||
]);
|
||||
|
||||
// Copy attribute of |parent| to |child| if it is not defined in |child|.
|
||||
@@ -188,6 +189,14 @@ const canAccessWindow = function (sender, target) {
|
||||
|
||||
// Routed window.open messages with raw options
|
||||
ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, frameName, features) => {
|
||||
// This should only be allowed for senders that have nativeWindowOpen: false
|
||||
{
|
||||
const webPreferences = event.sender.getLastWebPreferences();
|
||||
if (webPreferences.nativeWindowOpen || webPreferences.sandbox) {
|
||||
event.returnValue = null;
|
||||
throw new Error('GUEST_WINDOW_MANAGER_WINDOW_OPEN denied: expected native window.open');
|
||||
}
|
||||
}
|
||||
if (url == null || url === '') url = 'about:blank';
|
||||
if (frameName == null) frameName = '';
|
||||
if (features == null) features = '';
|
||||
@@ -195,7 +204,7 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, fra
|
||||
const options = {};
|
||||
|
||||
const ints = ['x', 'y', 'width', 'height', 'minWidth', 'maxWidth', 'minHeight', 'maxHeight', 'zoomFactor'];
|
||||
const webPreferences = ['zoomFactor', 'nodeIntegration', 'enableRemoteModule', 'preload', 'javascript', 'contextIsolation', 'webviewTag'];
|
||||
const webPreferences = ['zoomFactor', 'nodeIntegration', 'enableRemoteModule', 'javascript', 'contextIsolation', 'webviewTag'];
|
||||
const disposition = 'new-window';
|
||||
|
||||
// Used to store additional features
|
||||
|
||||
@@ -186,6 +186,7 @@ function currentPlatformSupportsAppIndicator () {
|
||||
}
|
||||
|
||||
// Workaround for electron/electron#5050 and electron/electron#9046
|
||||
process.env.ORIGINAL_XDG_CURRENT_DESKTOP = process.env.XDG_CURRENT_DESKTOP;
|
||||
if (currentPlatformSupportsAppIndicator()) {
|
||||
process.env.XDG_CURRENT_DESKTOP = 'Unity';
|
||||
}
|
||||
|
||||
@@ -5,11 +5,12 @@ import { EventEmitter } from 'events';
|
||||
import objectsRegistry from './objects-registry';
|
||||
import { ipcMainInternal } from '../ipc-main-internal';
|
||||
import * as guestViewManager from '@electron/internal/browser/guest-view-manager';
|
||||
import { isPromise, isSerializableObject } from '@electron/internal/common/type-utils';
|
||||
import { isPromise, isSerializableObject, deserialize, serialize } from '@electron/internal/common/type-utils';
|
||||
|
||||
const v8Util = process.electronBinding('v8_util');
|
||||
const eventBinding = process.electronBinding('event');
|
||||
const features = process.electronBinding('features');
|
||||
const { NativeImage } = process.electronBinding('native_image');
|
||||
|
||||
if (!features.isRemoteModuleEnabled()) {
|
||||
throw new Error('remote module is disabled');
|
||||
@@ -114,6 +115,9 @@ type MetaType = {
|
||||
} | {
|
||||
type: 'promise',
|
||||
then: MetaType
|
||||
} | {
|
||||
type: 'nativeimage'
|
||||
value: electron.NativeImage
|
||||
}
|
||||
|
||||
// Convert a real value into meta data.
|
||||
@@ -124,6 +128,8 @@ const valueToMeta = function (sender: electron.WebContents, contextId: string, v
|
||||
// Recognize certain types of objects.
|
||||
if (value instanceof Buffer) {
|
||||
type = 'buffer';
|
||||
} else if (value instanceof NativeImage) {
|
||||
type = 'nativeimage';
|
||||
} else if (Array.isArray(value)) {
|
||||
type = 'array';
|
||||
} else if (value instanceof Error) {
|
||||
@@ -147,6 +153,8 @@ const valueToMeta = function (sender: electron.WebContents, contextId: string, v
|
||||
type,
|
||||
members: value.map((el: any) => valueToMeta(sender, contextId, el, optimizeSimpleObject))
|
||||
};
|
||||
} else if (type === 'nativeimage') {
|
||||
return { type, value: serialize(value) };
|
||||
} else if (type === 'object' || type === 'function') {
|
||||
return {
|
||||
type,
|
||||
@@ -234,7 +242,10 @@ type MetaTypeFromRenderer = {
|
||||
} | {
|
||||
type: 'object',
|
||||
name: string,
|
||||
members: { name: string, value: MetaTypeFromRenderer }[]
|
||||
members: {
|
||||
name: string,
|
||||
value: MetaTypeFromRenderer
|
||||
}[]
|
||||
} | {
|
||||
type: 'function-with-return-value',
|
||||
value: MetaTypeFromRenderer
|
||||
@@ -243,6 +254,14 @@ type MetaTypeFromRenderer = {
|
||||
id: number,
|
||||
location: string,
|
||||
length: number
|
||||
} | {
|
||||
type: 'nativeimage',
|
||||
value: {
|
||||
size: electron.Size,
|
||||
buffer: Buffer,
|
||||
scaleFactor: number,
|
||||
dataURL: string
|
||||
}[]
|
||||
}
|
||||
|
||||
const fakeConstructor = (constructor: Function, name: string) =>
|
||||
@@ -260,6 +279,8 @@ const fakeConstructor = (constructor: Function, name: string) =>
|
||||
const unwrapArgs = function (sender: electron.WebContents, frameId: number, contextId: string, args: any[]) {
|
||||
const metaToValue = function (meta: MetaTypeFromRenderer): any {
|
||||
switch (meta.type) {
|
||||
case 'nativeimage':
|
||||
return deserialize(meta.value);
|
||||
case 'value':
|
||||
return meta.value;
|
||||
case 'remote-object':
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const { deprecate } = require('electron');
|
||||
const { NativeImage, nativeImage } = process.electronBinding('native_image');
|
||||
|
||||
deprecate.fnToProperty(NativeImage.prototype, 'isMacTemplateImage', '_isTemplateImage', '_setTemplateImage');
|
||||
const { nativeImage } = process.electronBinding('native_image');
|
||||
|
||||
module.exports = nativeImage;
|
||||
|
||||
@@ -23,6 +23,7 @@ const serializableTypes = [
|
||||
ArrayBuffer
|
||||
];
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#Supported_types
|
||||
export function isSerializableObject (value: any) {
|
||||
return value === null || ArrayBuffer.isView(value) || serializableTypes.some(type => value instanceof type);
|
||||
}
|
||||
@@ -33,14 +34,55 @@ const objectMap = function (source: Object, mapper: (value: any) => any) {
|
||||
return Object.fromEntries(targetEntries);
|
||||
};
|
||||
|
||||
function serializeNativeImage (image: any) {
|
||||
const representations = [];
|
||||
const scaleFactors = image.getScaleFactors();
|
||||
|
||||
// Use Buffer when there's only one representation for better perf.
|
||||
// This avoids compressing to/from PNG where it's not necessary to
|
||||
// ensure uniqueness of dataURLs (since there's only one).
|
||||
if (scaleFactors.length === 1) {
|
||||
const scaleFactor = scaleFactors[0];
|
||||
const size = image.getSize(scaleFactor);
|
||||
const buffer = image.toBitmap({ scaleFactor });
|
||||
representations.push({ scaleFactor, size, buffer });
|
||||
} else {
|
||||
// Construct from dataURLs to ensure that they are not lost in creation.
|
||||
for (const scaleFactor of scaleFactors) {
|
||||
const size = image.getSize(scaleFactor);
|
||||
const dataURL = image.toDataURL({ scaleFactor });
|
||||
representations.push({ scaleFactor, size, dataURL });
|
||||
}
|
||||
}
|
||||
return { __ELECTRON_SERIALIZED_NativeImage__: true, representations };
|
||||
}
|
||||
|
||||
function deserializeNativeImage (value: any) {
|
||||
const image = nativeImage.createEmpty();
|
||||
|
||||
// Use Buffer when there's only one representation for better perf.
|
||||
// This avoids compressing to/from PNG where it's not necessary to
|
||||
// ensure uniqueness of dataURLs (since there's only one).
|
||||
if (value.representations.length === 1) {
|
||||
const { buffer, size, scaleFactor } = value.representations[0];
|
||||
const { width, height } = size;
|
||||
image.addRepresentation({ buffer, scaleFactor, width, height });
|
||||
} else {
|
||||
// Construct from dataURLs to ensure that they are not lost in creation.
|
||||
for (const rep of value.representations) {
|
||||
const { dataURL, size, scaleFactor } = rep;
|
||||
const { width, height } = size;
|
||||
image.addRepresentation({ dataURL, scaleFactor, width, height });
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
export function serialize (value: any): any {
|
||||
if (value instanceof NativeImage) {
|
||||
return {
|
||||
buffer: value.toBitmap(),
|
||||
size: value.getSize(),
|
||||
__ELECTRON_SERIALIZED_NativeImage__: true
|
||||
};
|
||||
} else if (Array.isArray(value)) {
|
||||
return serializeNativeImage(value);
|
||||
} if (Array.isArray(value)) {
|
||||
return value.map(serialize);
|
||||
} else if (isSerializableObject(value)) {
|
||||
return value;
|
||||
@@ -53,7 +95,7 @@ export function serialize (value: any): any {
|
||||
|
||||
export function deserialize (value: any): any {
|
||||
if (value && value.__ELECTRON_SERIALIZED_NativeImage__) {
|
||||
return nativeImage.createFromBitmap(value.buffer, value.size);
|
||||
return deserializeNativeImage(value);
|
||||
} else if (Array.isArray(value)) {
|
||||
return value.map(deserialize);
|
||||
} else if (isSerializableObject(value)) {
|
||||
|
||||
@@ -6,10 +6,6 @@ process.electronBinding = require('@electron/internal/common/electron-binding-se
|
||||
|
||||
const v8Util = process.electronBinding('v8_util');
|
||||
|
||||
// The `lib/renderer/ipc-renderer-internal.js` module looks for the ipc object in the
|
||||
// "ipc-internal" hidden value
|
||||
v8Util.setHiddenValue(global, 'ipc-internal', v8Util.getHiddenValue(isolatedWorld, 'ipc-internal'));
|
||||
|
||||
const webViewImpl = v8Util.getHiddenValue(isolatedWorld, 'web-view-impl');
|
||||
|
||||
if (webViewImpl) {
|
||||
@@ -17,11 +13,3 @@ if (webViewImpl) {
|
||||
const { setupWebView } = require('@electron/internal/renderer/web-view/web-view-element');
|
||||
setupWebView(v8Util, webViewImpl);
|
||||
}
|
||||
|
||||
const isolatedWorldArgs = v8Util.getHiddenValue(isolatedWorld, 'isolated-world-args');
|
||||
|
||||
if (isolatedWorldArgs) {
|
||||
const { guestInstanceId, isHiddenPage, openerId, usesNativeWindowOpen } = isolatedWorldArgs;
|
||||
const { windowSetup } = require('@electron/internal/renderer/window-setup');
|
||||
windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen);
|
||||
}
|
||||
|
||||
@@ -11,10 +11,22 @@ const contextBridge = {
|
||||
exposeInMainWorld: (key: string, api: Record<string, any>) => {
|
||||
checkContextIsolationEnabled();
|
||||
return binding.exposeAPIInMainWorld(key, api);
|
||||
},
|
||||
debugGC: () => binding._debugGCMaps({})
|
||||
}
|
||||
};
|
||||
|
||||
if (!binding._debugGCMaps) delete contextBridge.debugGC;
|
||||
|
||||
export default contextBridge;
|
||||
|
||||
export const internalContextBridge = {
|
||||
contextIsolationEnabled,
|
||||
overrideGlobalValueFromIsolatedWorld: (keys: string[], value: any) => {
|
||||
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, false);
|
||||
},
|
||||
overrideGlobalValueWithDynamicPropsFromIsolatedWorld: (keys: string[], value: any) => {
|
||||
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, true);
|
||||
},
|
||||
overrideGlobalPropertyFromIsolatedWorld: (keys: string[], getter: Function, setter?: Function) => {
|
||||
return binding._overrideGlobalPropertyFromIsolatedWorld(keys, getter, setter || null);
|
||||
},
|
||||
isInMainWorld: () => binding._isCalledFromMainWorld() as boolean,
|
||||
isInIsolatedWorld: () => binding._isCalledFromIsolatedWorld() as boolean
|
||||
};
|
||||
|
||||
@@ -5,28 +5,30 @@ const v8Util = process.electronBinding('v8_util');
|
||||
const ipcRenderer = v8Util.getHiddenValue<Electron.IpcRenderer>(global, 'ipc');
|
||||
const internal = false;
|
||||
|
||||
ipcRenderer.send = function (channel, ...args) {
|
||||
return ipc.send(internal, channel, args);
|
||||
};
|
||||
if (!ipcRenderer.send) {
|
||||
ipcRenderer.send = function (channel, ...args) {
|
||||
return ipc.send(internal, channel, args);
|
||||
};
|
||||
|
||||
ipcRenderer.sendSync = function (channel, ...args) {
|
||||
return ipc.sendSync(internal, channel, args)[0];
|
||||
};
|
||||
ipcRenderer.sendSync = function (channel, ...args) {
|
||||
return ipc.sendSync(internal, channel, args)[0];
|
||||
};
|
||||
|
||||
ipcRenderer.sendToHost = function (channel, ...args) {
|
||||
return ipc.sendToHost(channel, args);
|
||||
};
|
||||
ipcRenderer.sendToHost = function (channel, ...args) {
|
||||
return ipc.sendToHost(channel, args);
|
||||
};
|
||||
|
||||
ipcRenderer.sendTo = function (webContentsId, channel, ...args) {
|
||||
return ipc.sendTo(internal, false, webContentsId, channel, args);
|
||||
};
|
||||
ipcRenderer.sendTo = function (webContentsId, channel, ...args) {
|
||||
return ipc.sendTo(internal, false, webContentsId, channel, args);
|
||||
};
|
||||
|
||||
ipcRenderer.invoke = async function (channel, ...args) {
|
||||
const { error, result } = await ipc.invoke(internal, channel, args);
|
||||
if (error) {
|
||||
throw new Error(`Error invoking remote method '${channel}': ${error}`);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
ipcRenderer.invoke = async function (channel, ...args) {
|
||||
const { error, result } = await ipc.invoke(internal, channel, args);
|
||||
if (error) {
|
||||
throw new Error(`Error invoking remote method '${channel}': ${error}`);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
export default ipcRenderer;
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
const v8Util = process.electronBinding('v8_util');
|
||||
const { hasSwitch } = process.electronBinding('command_line');
|
||||
const { NativeImage } = process.electronBinding('native_image');
|
||||
|
||||
const { CallbacksRegistry } = require('@electron/internal/renderer/remote/callbacks-registry');
|
||||
const { isPromise, isSerializableObject } = require('@electron/internal/common/type-utils');
|
||||
const { isPromise, isSerializableObject, serialize, deserialize } = require('@electron/internal/common/type-utils');
|
||||
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal');
|
||||
|
||||
const callbacksRegistry = new CallbacksRegistry();
|
||||
@@ -33,7 +34,9 @@ function wrapArgs (args, visited = new Set()) {
|
||||
};
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
if (value instanceof NativeImage) {
|
||||
return { type: 'nativeimage', value: serialize(value) };
|
||||
} else if (Array.isArray(value)) {
|
||||
visited.add(value);
|
||||
const meta = {
|
||||
type: 'array',
|
||||
@@ -213,6 +216,7 @@ function metaToValue (meta) {
|
||||
const types = {
|
||||
value: () => meta.value,
|
||||
array: () => meta.members.map((member) => metaToValue(member)),
|
||||
nativeimage: () => deserialize(meta.value),
|
||||
buffer: () => Buffer.from(meta.value.buffer, meta.value.byteOffset, meta.value.byteLength),
|
||||
promise: () => Promise.resolve({ then: metaToValue(meta.then) }),
|
||||
error: () => metaToError(meta),
|
||||
|
||||
@@ -5,26 +5,28 @@ const v8Util = process.electronBinding('v8_util');
|
||||
export const ipcRendererInternal = v8Util.getHiddenValue<Electron.IpcRendererInternal>(global, 'ipc-internal');
|
||||
const internal = true;
|
||||
|
||||
ipcRendererInternal.send = function (channel, ...args) {
|
||||
return ipc.send(internal, channel, args);
|
||||
};
|
||||
if (!ipcRendererInternal.send) {
|
||||
ipcRendererInternal.send = function (channel, ...args) {
|
||||
return ipc.send(internal, channel, args);
|
||||
};
|
||||
|
||||
ipcRendererInternal.sendSync = function (channel, ...args) {
|
||||
return ipc.sendSync(internal, channel, args)[0];
|
||||
};
|
||||
ipcRendererInternal.sendSync = function (channel, ...args) {
|
||||
return ipc.sendSync(internal, channel, args)[0];
|
||||
};
|
||||
|
||||
ipcRendererInternal.sendTo = function (webContentsId, channel, ...args) {
|
||||
return ipc.sendTo(internal, false, webContentsId, channel, args);
|
||||
};
|
||||
ipcRendererInternal.sendTo = function (webContentsId, channel, ...args) {
|
||||
return ipc.sendTo(internal, false, webContentsId, channel, args);
|
||||
};
|
||||
|
||||
ipcRendererInternal.sendToAll = function (webContentsId, channel, ...args) {
|
||||
return ipc.sendTo(internal, true, webContentsId, channel, args);
|
||||
};
|
||||
ipcRendererInternal.sendToAll = function (webContentsId, channel, ...args) {
|
||||
return ipc.sendTo(internal, true, webContentsId, channel, args);
|
||||
};
|
||||
|
||||
ipcRendererInternal.invoke = async function<T> (channel: string, ...args: any[]) {
|
||||
const { error, result } = await ipc.invoke<T>(internal, channel, args);
|
||||
if (error) {
|
||||
throw new Error(`Error invoking remote method '${channel}': ${error}`);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
ipcRendererInternal.invoke = async function<T> (channel: string, ...args: any[]) {
|
||||
const { error, result } = await ipc.invoke<T>(internal, channel, args);
|
||||
if (error) {
|
||||
throw new Error(`Error invoking remote method '${channel}': ${error}`);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -110,9 +110,14 @@ export function attachGuest (
|
||||
ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', embedderFrameId, elementInstanceId, guestInstanceId, params);
|
||||
}
|
||||
|
||||
export function detachGuest (guestInstanceId: number) {
|
||||
return ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_DETACH_GUEST', guestInstanceId);
|
||||
}
|
||||
|
||||
export const guestViewInternalModule = {
|
||||
deregisterEvents,
|
||||
createGuest,
|
||||
createGuestSync,
|
||||
attachGuest
|
||||
attachGuest,
|
||||
detachGuest
|
||||
};
|
||||
|
||||
@@ -66,6 +66,9 @@ const defineWebViewElement = (v8Util: NodeJS.V8UtilBinding, webViewImpl: typeof
|
||||
return;
|
||||
}
|
||||
guestViewInternal.deregisterEvents(internal.viewInstanceId);
|
||||
if (internal.guestInstanceId) {
|
||||
guestViewInternal.detachGuest(internal.guestInstanceId);
|
||||
}
|
||||
internal.elementAttached = false;
|
||||
this.internalInstanceId = 0;
|
||||
internal.reset();
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
|
||||
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
|
||||
import { internalContextBridge } from '@electron/internal/renderer/api/context-bridge';
|
||||
|
||||
// This file implements the following APIs:
|
||||
// - window.history.back()
|
||||
// - window.history.forward()
|
||||
// - window.history.go()
|
||||
// - window.history.length
|
||||
const { contextIsolationEnabled, isInIsolatedWorld } = internalContextBridge;
|
||||
const shouldUseContextBridge = contextIsolationEnabled && isInIsolatedWorld();
|
||||
|
||||
// This file implements the following APIs over the ctx bridge:
|
||||
// - window.open()
|
||||
// - window.opener.blur()
|
||||
// - window.opener.close()
|
||||
@@ -13,7 +13,12 @@ import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-inte
|
||||
// - window.opener.focus()
|
||||
// - window.opener.location
|
||||
// - window.opener.print()
|
||||
// - window.opener.closed
|
||||
// - window.opener.postMessage()
|
||||
// - window.history.back()
|
||||
// - window.history.forward()
|
||||
// - window.history.go()
|
||||
// - window.history.length
|
||||
// - window.prompt()
|
||||
// - document.hidden
|
||||
// - document.visibilityState
|
||||
@@ -30,13 +35,13 @@ const toString = (value: any) => {
|
||||
|
||||
const windowProxies = new Map<number, BrowserWindowProxy>();
|
||||
|
||||
const getOrCreateProxy = (guestId: number) => {
|
||||
const getOrCreateProxy = (guestId: number): SafelyBoundBrowserWindowProxy => {
|
||||
let proxy = windowProxies.get(guestId);
|
||||
if (proxy == null) {
|
||||
proxy = new BrowserWindowProxy(guestId);
|
||||
windowProxies.set(guestId, proxy);
|
||||
}
|
||||
return proxy;
|
||||
return proxy.getSafe();
|
||||
};
|
||||
|
||||
const removeProxy = (guestId: number) => {
|
||||
@@ -64,6 +69,8 @@ class LocationProxy {
|
||||
*/
|
||||
private static ProxyProperty<T> (target: LocationProxy, propertyKey: LocationProperties) {
|
||||
Object.defineProperty(target, propertyKey, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: function (this: LocationProxy): T | string {
|
||||
const guestURL = this.getGuestURL();
|
||||
const value = guestURL ? guestURL[propertyKey] : '';
|
||||
@@ -82,6 +89,30 @@ class LocationProxy {
|
||||
});
|
||||
}
|
||||
|
||||
public getSafe = () => {
|
||||
const that = this;
|
||||
return {
|
||||
get href () { return that.href; },
|
||||
set href (newValue) { that.href = newValue; },
|
||||
get hash () { return that.hash; },
|
||||
set hash (newValue) { that.hash = newValue; },
|
||||
get host () { return that.host; },
|
||||
set host (newValue) { that.host = newValue; },
|
||||
get hostname () { return that.hostname; },
|
||||
set hostname (newValue) { that.hostname = newValue; },
|
||||
get origin () { return that.origin; },
|
||||
set origin (newValue) { that.origin = newValue; },
|
||||
get pathname () { return that.pathname; },
|
||||
set pathname (newValue) { that.pathname = newValue; },
|
||||
get port () { return that.port; },
|
||||
set port (newValue) { that.port = newValue; },
|
||||
get protocol () { return that.protocol; },
|
||||
set protocol (newValue) { that.protocol = newValue; },
|
||||
get search () { return that.search; },
|
||||
set search (newValue) { that.search = newValue; }
|
||||
};
|
||||
}
|
||||
|
||||
constructor (guestId: number) {
|
||||
// eslint will consider the constructor "useless"
|
||||
// unless we assign them in the body. It's fine, that's what
|
||||
@@ -95,7 +126,11 @@ class LocationProxy {
|
||||
}
|
||||
|
||||
private getGuestURL (): URL | null {
|
||||
const urlString = this._invokeWebContentsMethodSync('getURL') as string;
|
||||
const maybeURL = this._invokeWebContentsMethodSync('getURL') as string;
|
||||
|
||||
// When there's no previous frame the url will be blank, so accountfor that here
|
||||
// to prevent url parsing errors on an empty string.
|
||||
const urlString = maybeURL !== '' ? maybeURL : 'about:blank';
|
||||
try {
|
||||
return new URL(urlString);
|
||||
} catch (e) {
|
||||
@@ -114,6 +149,17 @@ class LocationProxy {
|
||||
}
|
||||
}
|
||||
|
||||
interface SafelyBoundBrowserWindowProxy {
|
||||
location: WindowProxy['location'];
|
||||
blur: WindowProxy['blur'];
|
||||
close: WindowProxy['close'];
|
||||
eval: typeof eval; // eslint-disable-line no-eval
|
||||
focus: WindowProxy['focus'];
|
||||
print: WindowProxy['print'];
|
||||
postMessage: WindowProxy['postMessage'];
|
||||
closed: boolean;
|
||||
}
|
||||
|
||||
class BrowserWindowProxy {
|
||||
public closed: boolean = false
|
||||
|
||||
@@ -124,7 +170,7 @@ class BrowserWindowProxy {
|
||||
// so for now, we'll have to make do with an "any" in the mix.
|
||||
// https://github.com/Microsoft/TypeScript/issues/2521
|
||||
public get location (): LocationProxy | any {
|
||||
return this._location;
|
||||
return this._location.getSafe();
|
||||
}
|
||||
public set location (url: string | any) {
|
||||
url = resolveURL(url, this.location.href);
|
||||
@@ -141,27 +187,48 @@ class BrowserWindowProxy {
|
||||
});
|
||||
}
|
||||
|
||||
public close () {
|
||||
public getSafe = (): SafelyBoundBrowserWindowProxy => {
|
||||
const that = this;
|
||||
return {
|
||||
postMessage: this.postMessage,
|
||||
blur: this.blur,
|
||||
close: this.close,
|
||||
focus: this.focus,
|
||||
print: this.print,
|
||||
eval: this.eval,
|
||||
get location () {
|
||||
return that.location;
|
||||
},
|
||||
set location (url: string | any) {
|
||||
that.location = url;
|
||||
},
|
||||
get closed () {
|
||||
return that.closed;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public close = () => {
|
||||
this._invokeWindowMethod('destroy');
|
||||
}
|
||||
|
||||
public focus () {
|
||||
public focus = () => {
|
||||
this._invokeWindowMethod('focus');
|
||||
}
|
||||
|
||||
public blur () {
|
||||
public blur = () => {
|
||||
this._invokeWindowMethod('blur');
|
||||
}
|
||||
|
||||
public print () {
|
||||
public print = () => {
|
||||
this._invokeWebContentsMethod('print');
|
||||
}
|
||||
|
||||
public postMessage (message: any, targetOrigin: string) {
|
||||
public postMessage = (message: any, targetOrigin: string) => {
|
||||
ipcRendererInternal.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, toString(targetOrigin), window.location.origin);
|
||||
}
|
||||
|
||||
public eval (code: string) {
|
||||
public eval = (code: string) => {
|
||||
this._invokeWebContentsMethod('executeJavaScript', code);
|
||||
}
|
||||
|
||||
@@ -182,9 +249,11 @@ export const windowSetup = (
|
||||
window.close = function () {
|
||||
ipcRendererInternal.sendSync('ELECTRON_BROWSER_WINDOW_CLOSE');
|
||||
};
|
||||
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['close'], window.close);
|
||||
}
|
||||
|
||||
if (!usesNativeWindowOpen) {
|
||||
// TODO(MarshallOfSound): Make compatible with ctx isolation without hole-punch
|
||||
// Make the browser window or guest view emit "new-window" event.
|
||||
(window as any).open = function (url?: string, frameName?: string, features?: string) {
|
||||
if (url != null && url !== '') {
|
||||
@@ -197,16 +266,19 @@ export const windowSetup = (
|
||||
return null;
|
||||
}
|
||||
};
|
||||
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['open'], window.open);
|
||||
}
|
||||
|
||||
if (openerId != null) {
|
||||
window.opener = getOrCreateProxy(openerId);
|
||||
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['opener'], window.opener);
|
||||
}
|
||||
|
||||
// But we do not support prompt().
|
||||
window.prompt = function () {
|
||||
throw new Error('prompt() is and will not be supported.');
|
||||
};
|
||||
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['prompt'], window.prompt);
|
||||
|
||||
if (!usesNativeWindowOpen || openerId != null) {
|
||||
ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
|
||||
@@ -233,20 +305,25 @@ export const windowSetup = (
|
||||
window.history.back = function () {
|
||||
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK');
|
||||
};
|
||||
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['history', 'back'], window.history.back);
|
||||
|
||||
window.history.forward = function () {
|
||||
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD');
|
||||
};
|
||||
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['history', 'forward'], window.history.forward);
|
||||
|
||||
window.history.go = function (offset: number) {
|
||||
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset);
|
||||
};
|
||||
if (shouldUseContextBridge) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['history', 'go'], window.history.go);
|
||||
|
||||
const getHistoryLength = () => ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH');
|
||||
Object.defineProperty(window.history, 'length', {
|
||||
get: function () {
|
||||
return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH');
|
||||
}
|
||||
get: getHistoryLength,
|
||||
set () {}
|
||||
});
|
||||
// TODO(MarshallOfSound): Fix so that the internal context bridge can override a non-configurable property
|
||||
// if (shouldUseContextBridge) internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['history', 'length'], getHistoryLength);
|
||||
}
|
||||
|
||||
if (guestInstanceId != null) {
|
||||
@@ -268,16 +345,16 @@ export const windowSetup = (
|
||||
});
|
||||
|
||||
// Make document.hidden and document.visibilityState return the correct value.
|
||||
const getDocumentHidden = () => cachedVisibilityState !== 'visible';
|
||||
Object.defineProperty(document, 'hidden', {
|
||||
get: function () {
|
||||
return cachedVisibilityState !== 'visible';
|
||||
}
|
||||
get: getDocumentHidden
|
||||
});
|
||||
if (shouldUseContextBridge) internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['document', 'hidden'], getDocumentHidden);
|
||||
|
||||
const getDocumentVisibilityState = () => cachedVisibilityState;
|
||||
Object.defineProperty(document, 'visibilityState', {
|
||||
get: function () {
|
||||
return cachedVisibilityState;
|
||||
}
|
||||
get: getDocumentVisibilityState
|
||||
});
|
||||
if (shouldUseContextBridge) internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['document', 'visibilityState'], getDocumentVisibilityState);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -114,6 +114,12 @@ function preloadRequire (module) {
|
||||
// Process command line arguments.
|
||||
const { hasSwitch } = process.electronBinding('command_line');
|
||||
|
||||
// Similar to nodes --expose-internals flag, this exposes electronBinding so
|
||||
// that tests can call it to get access to some test only bindings
|
||||
if (hasSwitch('unsafely-expose-electron-internals-for-testing')) {
|
||||
preloadProcess.electronBinding = process.electronBinding;
|
||||
}
|
||||
|
||||
const contextIsolation = hasSwitch('context-isolation');
|
||||
const isHiddenPage = hasSwitch('hidden-page');
|
||||
const usesNativeWindowOpen = true;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "8.2.3",
|
||||
"version": "8.3.2",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
|
||||
1
patches/angle/.patches
Normal file
1
patches/angle/.patches
Normal file
@@ -0,0 +1 @@
|
||||
update_the_active_texture_cache_before_changing_the_texture_binding.patch
|
||||
@@ -0,0 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Lang <geofflang@chromium.org>
|
||||
Date: Fri, 27 Mar 2020 12:24:52 -0400
|
||||
Subject: Update the active texture cache before changing the texture binding.
|
||||
|
||||
When a new texture is bound, the texture binding state is updated before
|
||||
updating the active texture cache. With this ordering, it is possible to delete
|
||||
the currently bound texture when the binding changes and then use-after-free it
|
||||
when updating the active texture cache.
|
||||
|
||||
BUG=angleproject:1065186
|
||||
|
||||
Change-Id: Id6d56b6c6db423755b195cda1e5cf1bcb1ee7aee
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2124588
|
||||
Commit-Queue: Geoff Lang <geofflang@chromium.org>
|
||||
Reviewed-by: Jamie Madill <jmadill@chromium.org>
|
||||
|
||||
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
|
||||
index 3fab8404046846e5b8ed6253139537360e83c409..c6c6ee75ebf554ce47cfcef218dca6a22075a4aa 100644
|
||||
--- a/src/libANGLE/State.cpp
|
||||
+++ b/src/libANGLE/State.cpp
|
||||
@@ -1138,14 +1138,14 @@ void State::setActiveSampler(unsigned int active)
|
||||
|
||||
void State::setSamplerTexture(const Context *context, TextureType type, Texture *texture)
|
||||
{
|
||||
- mSamplerTextures[type][mActiveSampler].set(context, texture);
|
||||
-
|
||||
if (mProgram && mProgram->getActiveSamplersMask()[mActiveSampler] &&
|
||||
mProgram->getActiveSamplerTypes()[mActiveSampler] == type)
|
||||
{
|
||||
updateActiveTexture(context, mActiveSampler, texture);
|
||||
}
|
||||
|
||||
+ mSamplerTextures[type][mActiveSampler].set(context, texture);
|
||||
+
|
||||
mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
|
||||
}
|
||||
|
||||
@@ -93,3 +93,16 @@ feat_allow_embedders_to_add_observers_on_created_hunspell.patch
|
||||
feat_enable_offscreen_rendering_with_viz_compositor.patch
|
||||
when_suspending_context_don_t_clear_handlers.patch
|
||||
use_keepselfalive_on_audiocontext_to_keep_it_alive_until_rendering.patch
|
||||
never_let_a_non-zero-size_pixel_snap_to_zero_size.patch
|
||||
cherry-pick-826a4af58b3d.patch
|
||||
cherry-pick-686d1bfbcb8f.patch
|
||||
cherry-pick-7101418f85a0.patch
|
||||
cherry-pick-38990b7d56e6.patch
|
||||
cherry-pick-67864c214770.patch
|
||||
cherry-pick-86c02c5dcd37.patch
|
||||
fix_hunspell_crash.patch
|
||||
avoid_nullptr_dereference_in_rtcpeerconnectionhandler.patch
|
||||
reland_onstate_handler_is_allowed_to_close_a_peerconnection.patch
|
||||
fix_swap_global_proxies_before_initializing_the_windows_proxies.patch
|
||||
fix_default_to_ntlm_v2_in_network_service.patch
|
||||
a11y_allows_klistboxoption_as_an_item_to_kgroup.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 df021746aab26a61096922e902815931af4621dc..d4451bbb638b42164fe8ec9f4c37a0d93efd8aa3 100644
|
||||
--- a/ui/accessibility/ax_node.cc
|
||||
+++ b/ui/accessibility/ax_node.cc
|
||||
@@ -778,6 +778,7 @@ bool AXNode::SetRoleMatchesItemRole(const AXNode* ordered_set) const {
|
||||
return 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 84952172938446254e53c2ee11cba37433d0e991..91a7be0f349116dc48cbe543104a6e7828ddf2e8 100644
|
||||
--- a/ui/accessibility/ax_tree_unittest.cc
|
||||
+++ b/ui/accessibility/ax_tree_unittest.cc
|
||||
@@ -3549,6 +3549,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,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel McArdle <dmcardle@chromium.org>
|
||||
Date: Thu, 16 Apr 2020 20:18:47 +0000
|
||||
Subject: Avoid nullptr dereference in RTCPeerConnectionHandler
|
||||
|
||||
Bug: 1071327
|
||||
Change-Id: Icf4189905dc5c95854b5af4b3e5e25e0607dd39e
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2153325
|
||||
Reviewed-by: Harald Alvestrand <hta@chromium.org>
|
||||
Commit-Queue: Dan McArdle <dmcardle@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#759775}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
|
||||
index 9457fb951fed176c54f9e792ea5f71cb73f5bbba..6745fc1ae9746a3f9949f856b1501c48e85b5260 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
|
||||
@@ -2304,7 +2304,8 @@ void RTCPeerConnectionHandler::OnRemoveReceiverPlanB(uintptr_t receiver_id) {
|
||||
|
||||
void RTCPeerConnectionHandler::OnModifySctpTransport(
|
||||
blink::WebRTCSctpTransportSnapshot state) {
|
||||
- client_->DidModifySctpTransport(state);
|
||||
+ if (client_)
|
||||
+ client_->DidModifySctpTransport(state);
|
||||
}
|
||||
|
||||
void RTCPeerConnectionHandler::OnModifyTransceivers(
|
||||
@@ -2431,7 +2432,8 @@ void RTCPeerConnectionHandler::OnIceCandidateError(const String& host_candidate,
|
||||
}
|
||||
|
||||
void RTCPeerConnectionHandler::OnInterestingUsage(int usage_pattern) {
|
||||
- client_->DidNoteInterestingUsage(usage_pattern);
|
||||
+ if (client_)
|
||||
+ client_->DidNoteInterestingUsage(usage_pattern);
|
||||
}
|
||||
|
||||
webrtc::SessionDescriptionInterface*
|
||||
77
patches/chromium/cherry-pick-38990b7d56e6.patch
Normal file
77
patches/chromium/cherry-pick-38990b7d56e6.patch
Normal file
@@ -0,0 +1,77 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Date: Tue, 21 Apr 2020 23:51:25 +0000
|
||||
Subject: Fix bug when BytesProvider replies with invalid data.
|
||||
|
||||
Bug: 1072983
|
||||
Change-Id: Ideaa0a67680375e770995880a4b8d2014b51d642
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2159583
|
||||
Reviewed-by: enne <enne@chromium.org>
|
||||
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#761203}
|
||||
|
||||
diff --git a/storage/browser/blob/blob_registry_impl.cc b/storage/browser/blob/blob_registry_impl.cc
|
||||
index 1cc34f91e01530754635a27cd6481e367b0a4d4e..b6a12a5c43d0129f6c1dcfe93fbd684ba4f5dc2e 100644
|
||||
--- a/storage/browser/blob/blob_registry_impl.cc
|
||||
+++ b/storage/browser/blob/blob_registry_impl.cc
|
||||
@@ -432,6 +432,10 @@ void BlobRegistryImpl::BlobUnderConstruction::TransportComplete(
|
||||
// try to delete |this| again afterwards.
|
||||
auto weak_this = weak_ptr_factory_.GetWeakPtr();
|
||||
|
||||
+ // Store the bad_message_callback_, so we can invoke it if needed, after
|
||||
+ // notifying about the blob being finished.
|
||||
+ auto bad_message_callback = std::move(bad_message_callback_);
|
||||
+
|
||||
// The blob might no longer have any references, in which case it may no
|
||||
// longer exist. If that happens just skip calling Complete.
|
||||
// TODO(mek): Stop building sooner if a blob is no longer referenced.
|
||||
@@ -445,7 +449,7 @@ void BlobRegistryImpl::BlobUnderConstruction::TransportComplete(
|
||||
// BlobTransportStrategy might have already reported a BadMessage on the
|
||||
// BytesProvider binding, but just to be safe, also report one on the
|
||||
// BlobRegistry binding itself.
|
||||
- std::move(bad_message_callback_)
|
||||
+ std::move(bad_message_callback)
|
||||
.Run("Received invalid data while transporting blob");
|
||||
}
|
||||
if (weak_this)
|
||||
diff --git a/storage/browser/blob/blob_registry_impl_unittest.cc b/storage/browser/blob/blob_registry_impl_unittest.cc
|
||||
index 8cbcc69ec6dc6bd368fdb59a3797e412b286e342..2060676987e267a0d55878a27f6a1b53fe6790b1 100644
|
||||
--- a/storage/browser/blob/blob_registry_impl_unittest.cc
|
||||
+++ b/storage/browser/blob/blob_registry_impl_unittest.cc
|
||||
@@ -770,6 +770,36 @@ TEST_F(BlobRegistryImplTest, Register_ValidBytesAsReply) {
|
||||
EXPECT_EQ(0u, BlobsUnderConstruction());
|
||||
}
|
||||
|
||||
+TEST_F(BlobRegistryImplTest, Register_InvalidBytesAsReply) {
|
||||
+ const std::string kId = "id";
|
||||
+ const std::string kData = "hello";
|
||||
+
|
||||
+ std::vector<blink::mojom::DataElementPtr> elements;
|
||||
+ elements.push_back(
|
||||
+ blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
|
||||
+ kData.size(), base::nullopt, CreateBytesProvider(""))));
|
||||
+
|
||||
+ mojo::PendingRemote<blink::mojom::Blob> blob;
|
||||
+ EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
|
||||
+ "", "", std::move(elements)));
|
||||
+
|
||||
+ std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId);
|
||||
+ WaitForBlobCompletion(handle.get());
|
||||
+
|
||||
+ EXPECT_TRUE(handle->IsBroken());
|
||||
+ ASSERT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS,
|
||||
+ handle->GetBlobStatus());
|
||||
+
|
||||
+ EXPECT_EQ(1u, reply_request_count_);
|
||||
+ EXPECT_EQ(0u, stream_request_count_);
|
||||
+ EXPECT_EQ(0u, file_request_count_);
|
||||
+ EXPECT_EQ(0u, BlobsUnderConstruction());
|
||||
+
|
||||
+ // Expect 2 bad messages, one for the bad reply by the bytes provider, and one
|
||||
+ // for the original register call.
|
||||
+ EXPECT_EQ(2u, bad_messages_.size());
|
||||
+}
|
||||
+
|
||||
TEST_F(BlobRegistryImplTest, Register_ValidBytesAsStream) {
|
||||
const std::string kId = "id";
|
||||
const std::string kData =
|
||||
82
patches/chromium/cherry-pick-67864c214770.patch
Normal file
82
patches/chromium/cherry-pick-67864c214770.patch
Normal file
@@ -0,0 +1,82 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Cheng <dcheng@chromium.org>
|
||||
Date: Fri, 10 Apr 2020 00:43:45 +0000
|
||||
Subject: Use std::deque to store the stack of currently executing tasks
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The stack of currently executing stacks includes a PendingTask field. A
|
||||
pointer to this field is stored in TLS. However, std::vector does not
|
||||
guarantee pointer stability on resize.
|
||||
|
||||
(cherry picked from commit c34431a597aba8f4374975217d97a73eaf7d1f18)
|
||||
|
||||
Bug: 1064891
|
||||
Change-Id: I04eb06c9521722f08fd72826f552cedaffe61b53
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2146349
|
||||
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
|
||||
Reviewed-by: Sami Kyöstilä <skyostil@chromium.org>
|
||||
Reviewed-by: François Doray <fdoray@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#759017}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2158048
|
||||
Cr-Commit-Position: refs/branch-heads/4044@{#970}
|
||||
Cr-Branched-From: a6d9daf149a473ceea37f629c41d4527bf2055bd-refs/heads/master@{#737173}
|
||||
|
||||
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc
|
||||
index f719a33fff0c98dc7113b4b094bc46809dc66c00..ed951d323a1c7025d99a04d4481abc1f68dfb017 100644
|
||||
--- a/base/task/sequence_manager/sequence_manager_impl.cc
|
||||
+++ b/base/task/sequence_manager/sequence_manager_impl.cc
|
||||
@@ -50,13 +50,6 @@ const scoped_refptr<SequencedTaskRunner>& GetNullTaskRunner() {
|
||||
|
||||
} // namespace
|
||||
|
||||
-// This controls how big the the initial for
|
||||
-// |MainThreadOnly::task_execution_stack| should be. We don't expect to see
|
||||
-// depths of more than 2 unless cooperative scheduling is used on Blink, where
|
||||
-// we might get up to 6. Anyway 10 was chosen because it's a round number
|
||||
-// greater than current anticipated usage.
|
||||
-static constexpr const size_t kInitialTaskExecutionStackReserveCount = 10;
|
||||
-
|
||||
std::unique_ptr<SequenceManager> CreateSequenceManagerOnCurrentThread(
|
||||
SequenceManager::Settings settings) {
|
||||
return internal::SequenceManagerImpl::CreateOnCurrentThread(
|
||||
@@ -267,7 +260,6 @@ SequenceManagerImpl::MainThreadOnly::MainThreadOnly(
|
||||
random_generator = std::mt19937_64(RandUint64());
|
||||
uniform_distribution = std::uniform_real_distribution<double>(0.0, 1.0);
|
||||
}
|
||||
- task_execution_stack.reserve(kInitialTaskExecutionStackReserveCount);
|
||||
}
|
||||
|
||||
SequenceManagerImpl::MainThreadOnly::~MainThreadOnly() = default;
|
||||
diff --git a/base/task/sequence_manager/sequence_manager_impl.h b/base/task/sequence_manager/sequence_manager_impl.h
|
||||
index ddd0a580eb71300f6ec68903ff1467808707ec82..e2819c68fd2f3c19940e0f26248835abd1e55fda 100644
|
||||
--- a/base/task/sequence_manager/sequence_manager_impl.h
|
||||
+++ b/base/task/sequence_manager/sequence_manager_impl.h
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef BASE_TASK_SEQUENCE_MANAGER_SEQUENCE_MANAGER_IMPL_H_
|
||||
#define BASE_TASK_SEQUENCE_MANAGER_SEQUENCE_MANAGER_IMPL_H_
|
||||
|
||||
+#include <deque>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -12,7 +13,6 @@
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
-#include <vector>
|
||||
|
||||
#include "base/atomic_sequence_num.h"
|
||||
#include "base/cancelable_callback.h"
|
||||
@@ -308,7 +308,9 @@ class BASE_EXPORT SequenceManagerImpl
|
||||
bool nesting_observer_registered_ = false;
|
||||
|
||||
// Due to nested runloops more than one task can be executing concurrently.
|
||||
- std::vector<ExecutingTask> task_execution_stack;
|
||||
+ // Note that this uses std::deque for pointer stability, since pointers to
|
||||
+ // objects in this container are stored in TLS.
|
||||
+ std::deque<ExecutingTask> task_execution_stack;
|
||||
|
||||
Observer* observer = nullptr; // NOT OWNED
|
||||
|
||||
144
patches/chromium/cherry-pick-686d1bfbcb8f.patch
Normal file
144
patches/chromium/cherry-pick-686d1bfbcb8f.patch
Normal file
@@ -0,0 +1,144 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Rouslan Solomakhin <rouslan@chromium.org>
|
||||
Date: Wed, 15 Apr 2020 23:03:07 +0000
|
||||
Subject: Browser context owned callback.
|
||||
|
||||
Before this patch, an unowned function pointer would be invoked
|
||||
asynchronously with a reference to the possibly freed reference to the
|
||||
browser context, which could cause use after free in certain
|
||||
circumstances.
|
||||
|
||||
This patch makes the browser context own the callback and binds the
|
||||
function with a weak pointer, so freeing the browser context invalidates
|
||||
the weak pointer, which cancels the callback execution.
|
||||
|
||||
After this patch, freeing the browser context aborts the asynchronous
|
||||
callback that dereferences the browser context, so the use after free
|
||||
is prevented.
|
||||
|
||||
TBR=rouslan@chromium.org
|
||||
|
||||
(cherry picked from commit 2d0aad1e7602a7076d86772cc159b891cf2cf03b)
|
||||
|
||||
Bug: 1065298
|
||||
Change-Id: Id6de3099a55c4505e94a8a6d21fb25d6d2b34c6c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2144311
|
||||
Reviewed-by: Danyao Wang <danyao@chromium.org>
|
||||
Commit-Queue: Rouslan Solomakhin <rouslan@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#758404}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2151474
|
||||
Reviewed-by: Rouslan Solomakhin <rouslan@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4044@{#942}
|
||||
Cr-Branched-From: a6d9daf149a473ceea37f629c41d4527bf2055bd-refs/heads/master@{#737173}
|
||||
|
||||
diff --git a/content/browser/payments/payment_app_provider_impl.cc b/content/browser/payments/payment_app_provider_impl.cc
|
||||
index 3b813cb22c15e85c9e0da1b0060a4514e6522db5..83c26a3e1801dc780d83ee34136ca1513e343339 100644
|
||||
--- a/content/browser/payments/payment_app_provider_impl.cc
|
||||
+++ b/content/browser/payments/payment_app_provider_impl.cc
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "base/metrics/histogram_macros.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
+#include "base/supports_user_data.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "base/token.h"
|
||||
#include "content/browser/payments/payment_app_context_impl.h"
|
||||
@@ -432,28 +433,65 @@ void OnInstallPaymentApp(
|
||||
}
|
||||
}
|
||||
|
||||
-void CheckPermissionForPaymentApps(
|
||||
- BrowserContext* browser_context,
|
||||
- PaymentAppProvider::GetAllPaymentAppsCallback callback,
|
||||
- PaymentAppProvider::PaymentApps apps) {
|
||||
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
+// Callbacks for checking permissions asynchronously. Owned by the browser
|
||||
+// context to avoid using the browser context after it has been freed. Deleted
|
||||
+// after the callback is invoked.
|
||||
+// Sample usage:
|
||||
+// PostTask(&PermissionChecker::CheckPermissionForPaymentApps,
|
||||
+// PermissionChecker::Create(browser_context), std::move(callback));
|
||||
+class PermissionChecker : public base::SupportsUserData::Data {
|
||||
+ public:
|
||||
+ static base::WeakPtr<PermissionChecker> Create(
|
||||
+ BrowserContext* browser_context) {
|
||||
+ auto owned = std::make_unique<PermissionChecker>(browser_context);
|
||||
+ auto weak_pointer_result = owned->weak_ptr_factory_.GetWeakPtr();
|
||||
+ void* key = owned.get();
|
||||
+ browser_context->SetUserData(key, std::move(owned));
|
||||
+ return weak_pointer_result;
|
||||
+ }
|
||||
+
|
||||
+ // Do not use this method directly! Use the static PermissionChecker::Create()
|
||||
+ // method instead. (The constructor must be public for std::make_unique<> in
|
||||
+ // the Create() method.)
|
||||
+ explicit PermissionChecker(BrowserContext* browser_context)
|
||||
+ : browser_context_(browser_context) {}
|
||||
+ ~PermissionChecker() override = default;
|
||||
+
|
||||
+ // Disallow copy and assign.
|
||||
+ PermissionChecker(const PermissionChecker& other) = delete;
|
||||
+ PermissionChecker& operator=(const PermissionChecker& other) = delete;
|
||||
+
|
||||
+ void CheckPermissionForPaymentApps(
|
||||
+ PaymentAppProvider::GetAllPaymentAppsCallback callback,
|
||||
+ PaymentAppProvider::PaymentApps apps) {
|
||||
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
- PermissionController* permission_controller =
|
||||
- BrowserContext::GetPermissionController(browser_context);
|
||||
- DCHECK(permission_controller);
|
||||
-
|
||||
- PaymentAppProvider::PaymentApps permitted_apps;
|
||||
- for (auto& app : apps) {
|
||||
- GURL origin = app.second->scope.GetOrigin();
|
||||
- if (permission_controller->GetPermissionStatus(
|
||||
- PermissionType::PAYMENT_HANDLER, origin, origin) ==
|
||||
- blink::mojom::PermissionStatus::GRANTED) {
|
||||
- permitted_apps[app.first] = std::move(app.second);
|
||||
+ PermissionController* permission_controller =
|
||||
+ BrowserContext::GetPermissionController(browser_context_);
|
||||
+ DCHECK(permission_controller);
|
||||
+
|
||||
+ PaymentAppProvider::PaymentApps permitted_apps;
|
||||
+ for (auto& app : apps) {
|
||||
+ GURL origin = app.second->scope.GetOrigin();
|
||||
+ if (permission_controller->GetPermissionStatus(
|
||||
+ PermissionType::PAYMENT_HANDLER, origin, origin) ==
|
||||
+ blink::mojom::PermissionStatus::GRANTED) {
|
||||
+ permitted_apps[app.first] = std::move(app.second);
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ std::move(callback).Run(std::move(permitted_apps));
|
||||
+
|
||||
+ // Deletes this PermissionChecker object.
|
||||
+ browser_context_->RemoveUserData(/*key=*/this);
|
||||
}
|
||||
|
||||
- std::move(callback).Run(std::move(permitted_apps));
|
||||
-}
|
||||
+ private:
|
||||
+ // Owns this PermissionChecker object, so it's always valid.
|
||||
+ BrowserContext* browser_context_;
|
||||
+
|
||||
+ base::WeakPtrFactory<PermissionChecker> weak_ptr_factory_{this};
|
||||
+};
|
||||
|
||||
void AbortInvokePaymentApp(BrowserContext* browser_context,
|
||||
PaymentEventResponseType reason) {
|
||||
@@ -606,9 +644,11 @@ void PaymentAppProviderImpl::GetAllPaymentApps(
|
||||
|
||||
RunOrPostTaskOnThread(
|
||||
FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
|
||||
- base::BindOnce(&GetAllPaymentAppsOnCoreThread, payment_app_context,
|
||||
- base::BindOnce(&CheckPermissionForPaymentApps,
|
||||
- browser_context, std::move(callback))));
|
||||
+ base::BindOnce(
|
||||
+ &GetAllPaymentAppsOnCoreThread, payment_app_context,
|
||||
+ base::BindOnce(&PermissionChecker::CheckPermissionForPaymentApps,
|
||||
+ PermissionChecker::Create(browser_context),
|
||||
+ std::move(callback))));
|
||||
}
|
||||
|
||||
void PaymentAppProviderImpl::InvokePaymentApp(
|
||||
191
patches/chromium/cherry-pick-7101418f85a0.patch
Normal file
191
patches/chromium/cherry-pick-7101418f85a0.patch
Normal file
@@ -0,0 +1,191 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mason Freed <masonfreed@chromium.org>
|
||||
Date: Mon, 20 Apr 2020 21:57:52 +0000
|
||||
Subject: Fix customized built-in element constructor behavior
|
||||
|
||||
This CL implements two changes:
|
||||
1. It fixes the implementation to better match the spec for the
|
||||
"create an element for the token" [1] algorithm. Prior to this CL,
|
||||
step 7 of that algorithm was skipping directly to step 6 of the
|
||||
"create an element" [2] algorithm, skipping over step 5 for
|
||||
customized built-in elements. This is now fixed. This case is
|
||||
illustrated by the issue and example at [3] and [4]. This becomes
|
||||
the first test in customized-built-in-constructor-exceptions.html.
|
||||
|
||||
2. It updates the comments to match the new behavior discussed in [3]
|
||||
and the [5] spec PR, which changes the return value in the case
|
||||
that a customized built-in element constructor throws an exception.
|
||||
With the change above, that is actually already the behavior. So
|
||||
this is just a comment change. Two new tests are added to
|
||||
customized-built-in-constructor-exceptions.html.
|
||||
|
||||
[1] https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token
|
||||
[2] https://dom.spec.whatwg.org/#concept-create-element
|
||||
[3] https://github.com/whatwg/html/issues/5084
|
||||
[4] https://crbug.com/1024866
|
||||
[5] https://github.com/whatwg/dom/pull/797
|
||||
|
||||
Bug: 1071059, 1024866
|
||||
Change-Id: I814c81991eb5e83501304bcb3d2da476743aef52
|
||||
Cq-Do-Not-Cancel-Tryjobs: true
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2152986
|
||||
Commit-Queue: Mason Freed <masonfreed@chromium.org>
|
||||
Auto-Submit: Mason Freed <masonfreed@chromium.org>
|
||||
Reviewed-by: Kent Tamura <tkent@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#760705}
|
||||
|
||||
diff --git a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
|
||||
index 075b20837c75f736d4580e2b17b0568e0c36e48c..363ccb5f7c919ee1990b27684bc89c1cd4a805af 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
|
||||
@@ -137,6 +137,7 @@ HTMLElement* ScriptCustomElementDefinition::HandleCreateElementSyncException(
|
||||
HTMLElement* ScriptCustomElementDefinition::CreateAutonomousCustomElementSync(
|
||||
Document& document,
|
||||
const QualifiedName& tag_name) {
|
||||
+ DCHECK(CustomElement::ShouldCreateCustomElement(tag_name)) << tag_name;
|
||||
if (!script_state_->ContextIsValid())
|
||||
return CustomElement::CreateFailedElement(document, tag_name);
|
||||
ScriptState::Scope scope(script_state_);
|
||||
diff --git a/third_party/blink/renderer/core/html/custom/custom_element.cc b/third_party/blink/renderer/core/html/custom/custom_element.cc
|
||||
index d21c582052cbf861b792ec6f44e418cc25f3a8cc..1edcd4e60009c9f994c0711a8d373d771b4e8965 100644
|
||||
--- a/third_party/blink/renderer/core/html/custom/custom_element.cc
|
||||
+++ b/third_party/blink/renderer/core/html/custom/custom_element.cc
|
||||
@@ -205,7 +205,8 @@ Element* CustomElement::CreateUncustomizedOrUndefinedElement(
|
||||
|
||||
HTMLElement* CustomElement::CreateFailedElement(Document& document,
|
||||
const QualifiedName& tag_name) {
|
||||
- DCHECK(ShouldCreateCustomElement(tag_name));
|
||||
+ CHECK(ShouldCreateCustomElement(tag_name))
|
||||
+ << "HTMLUnknownElement with built-in tag name: " << tag_name;
|
||||
|
||||
// "create an element for a token":
|
||||
// https://html.spec.whatwg.org/C/#create-an-element-for-the-token
|
||||
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_definition.cc b/third_party/blink/renderer/core/html/custom/custom_element_definition.cc
|
||||
index 6126e0d04c48e8f7cebe8dbf39418599fcfcb84e..3341f49f48de367cbe4f736c4acac09c5d59ddbd 100644
|
||||
--- a/third_party/blink/renderer/core/html/custom/custom_element_definition.cc
|
||||
+++ b/third_party/blink/renderer/core/html/custom/custom_element_definition.cc
|
||||
@@ -142,14 +142,19 @@ HTMLElement* CustomElementDefinition::CreateElement(
|
||||
result->SetCustomElementState(CustomElementState::kUndefined);
|
||||
result->SetIsValue(Descriptor().GetName());
|
||||
|
||||
- // 5.3. If the synchronous custom elements flag is set, upgrade
|
||||
- // element using definition.
|
||||
- // 5.4. Otherwise, enqueue a custom element upgrade reaction given
|
||||
- // result and definition.
|
||||
- if (!flags.IsAsyncCustomElements())
|
||||
+ if (!flags.IsAsyncCustomElements()) {
|
||||
+ // 5.3 If the synchronous custom elements flag is set, then run this step
|
||||
+ // while catching any exceptions:
|
||||
+ // 1. Upgrade element using definition.
|
||||
+ // If this step threw an exception, then:
|
||||
+ // 1. Report the exception.
|
||||
+ // 2. Set result's custom element state to "failed".
|
||||
Upgrade(*result);
|
||||
- else
|
||||
+ } else {
|
||||
+ // 5.4. Otherwise, enqueue a custom element upgrade reaction given
|
||||
+ // result and definition.
|
||||
EnqueueUpgradeReaction(*result);
|
||||
+ }
|
||||
return To<HTMLElement>(result);
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/html/parser/html_construction_site.cc b/third_party/blink/renderer/core/html/parser/html_construction_site.cc
|
||||
index e5b8596cb60c8baf9c6d1a18d0c788985f8790b8..e98bb816eaa6f63b672a69425ea338e9521713d0 100644
|
||||
--- a/third_party/blink/renderer/core/html/parser/html_construction_site.cc
|
||||
+++ b/third_party/blink/renderer/core/html/parser/html_construction_site.cc
|
||||
@@ -919,8 +919,11 @@ Element* HTMLConstructionSite::CreateElement(
|
||||
// reactions stack."
|
||||
CEReactionsScope reactions;
|
||||
|
||||
- // 7.
|
||||
- element = definition->CreateAutonomousCustomElementSync(document, tag_name);
|
||||
+ // 7. Let element be the result of creating an element given document,
|
||||
+ // localName, given namespace, null, and is. If will execute script is true,
|
||||
+ // set the synchronous custom elements flag; otherwise, leave it unset.
|
||||
+ element =
|
||||
+ definition->CreateElement(document, tag_name, GetCreateElementFlags());
|
||||
|
||||
// "8. Append each attribute in the given token to element." We don't use
|
||||
// setAttributes here because the custom element constructor may have
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/customized-built-in-constructor-exceptions.html b/third_party/blink/web_tests/external/wpt/custom-elements/customized-built-in-constructor-exceptions.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..32729bdb6bb2c82f54c074c7609ff5c79883a37a
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/customized-built-in-constructor-exceptions.html
|
||||
@@ -0,0 +1,75 @@
|
||||
+<!DOCTYPE html>
|
||||
+<title>Customized built-in element constructor behavior</title>
|
||||
+<meta name='author' title='Mason Freed' href='mailto:masonfreed@chromium.org'>
|
||||
+<link rel='help' href='https://dom.spec.whatwg.org/#concept-create-element'>
|
||||
+<script src='/resources/testharness.js'></script>
|
||||
+<script src='/resources/testharnessreport.js'></script>
|
||||
+
|
||||
+<script>
|
||||
+setup({allow_uncaught_exception : true});
|
||||
+
|
||||
+class MyCustomParagraph extends HTMLParagraphElement {
|
||||
+ constructor() {
|
||||
+ super();
|
||||
+ this.textContent = 'PASS';
|
||||
+ }
|
||||
+}
|
||||
+customElements.define('custom-p', MyCustomParagraph, { extends: 'p' });
|
||||
+</script>
|
||||
+<p id=targetp is='custom-p'></p>
|
||||
+<script>
|
||||
+test(t => {
|
||||
+ let target = document.getElementById('targetp');
|
||||
+ assert_true(!!target);
|
||||
+ assert_equals(target.localName, 'p');
|
||||
+ assert_true(target instanceof MyCustomParagraph);
|
||||
+ assert_true(target instanceof HTMLParagraphElement);
|
||||
+ assert_equals(target.childNodes.length, 1);
|
||||
+ assert_equals(target.textContent, 'PASS');
|
||||
+}, 'Appending children in customized built-in constructor should work');
|
||||
+</script>
|
||||
+
|
||||
+
|
||||
+<script>
|
||||
+class MyCustomVideo extends HTMLVideoElement {
|
||||
+ constructor() {
|
||||
+ super();
|
||||
+ throw new Error();
|
||||
+ }
|
||||
+}
|
||||
+customElements.define('custom-video', MyCustomVideo, { extends: 'video' });
|
||||
+</script>
|
||||
+<video id=targetvideo is='custom-video'> <source></source> </video>
|
||||
+<script>
|
||||
+test(t => {
|
||||
+ let target = document.getElementById('targetvideo');
|
||||
+ assert_true(!!target);
|
||||
+ assert_equals(target.localName, 'video');
|
||||
+ assert_true(target instanceof MyCustomVideo);
|
||||
+ assert_true(target instanceof HTMLVideoElement);
|
||||
+ assert_equals(target.children.length, 1);
|
||||
+}, 'Throwing exception in customized built-in constructor should not crash and should return correct element type (video)');
|
||||
+</script>
|
||||
+
|
||||
+
|
||||
+<script>
|
||||
+class MyCustomForm extends HTMLFormElement {
|
||||
+ constructor() {
|
||||
+ super();
|
||||
+ throw new Error();
|
||||
+ }
|
||||
+}
|
||||
+customElements.define('custom-form', MyCustomForm, { extends: 'form' });
|
||||
+</script>
|
||||
+<form id=targetform is='custom-form'> <label></label><input> </form>
|
||||
+<script>
|
||||
+test(t => {
|
||||
+ let target = document.getElementById('targetform');
|
||||
+ assert_true(!!target);
|
||||
+ assert_equals(target.localName, 'form');
|
||||
+ assert_true(target instanceof MyCustomForm);
|
||||
+ assert_true(target instanceof HTMLFormElement);
|
||||
+ assert_equals(target.children.length, 2);
|
||||
+}, 'Throwing exception in customized built-in constructor should not crash and should return correct element type (form)');
|
||||
+</script>
|
||||
+
|
||||
50
patches/chromium/cherry-pick-826a4af58b3d.patch
Normal file
50
patches/chromium/cherry-pick-826a4af58b3d.patch
Normal file
@@ -0,0 +1,50 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mustafa Emre Acer <meacer@chromium.org>
|
||||
Date: Fri, 10 Apr 2020 00:43:45 +0000
|
||||
Subject: Don't decode invalid punycode in URL formatter
|
||||
|
||||
TBR=meacer@chromium.org
|
||||
|
||||
(cherry picked from commit 50c6e900fc4170a14154cbfea57ade2aa50990b5)
|
||||
|
||||
Bug: 1063566
|
||||
Change-Id: I631ba68718cf69c5972555d7826b089e27fa5150
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2137872
|
||||
Reviewed-by: Peter Kasting <pkasting@chromium.org>
|
||||
Commit-Queue: Peter Kasting <pkasting@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#756819}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2144830
|
||||
Reviewed-by: Mustafa Emre Acer <meacer@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4103@{#62}
|
||||
Cr-Branched-From: 8ad47e8d21f6866e4a37f47d83a860d41debf514-refs/heads/master@{#756066}
|
||||
|
||||
diff --git a/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc b/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc
|
||||
index f695e5c403cbcb020b2ef8016fb513ba1b8d97d1..ffd06415c9afd54c008d86f817cb0e704de87601 100644
|
||||
--- a/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc
|
||||
+++ b/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc
|
||||
@@ -55,6 +55,8 @@ const IDNTestCase kIdnCases[] = {
|
||||
{"www.google.com.", L"www.google.com.", true},
|
||||
{".", L".", true},
|
||||
{"", L"", true},
|
||||
+ // Invalid IDN
|
||||
+ {"xn--example-.com", L"xn--example-.com", false},
|
||||
// IDN
|
||||
// Hanzi (Traditional Chinese)
|
||||
{"xn--1lq90ic7f1rc.cn", L"\x5317\x4eac\x5927\x5b78.cn", true},
|
||||
diff --git a/components/url_formatter/url_formatter.cc b/components/url_formatter/url_formatter.cc
|
||||
index 58cadb980bb877c933e37457b1ab0883357ece47..d7cc2ea441c916fb77a520f8fe440cff042b6aab 100644
|
||||
--- a/components/url_formatter/url_formatter.cc
|
||||
+++ b/components/url_formatter/url_formatter.cc
|
||||
@@ -408,9 +408,11 @@ bool IDNToUnicodeOneComponent(const base::char16* comp,
|
||||
return false;
|
||||
|
||||
// Early return if the input cannot be an IDN component.
|
||||
+ // Valid punycode must not end with a dash.
|
||||
static const base::char16 kIdnPrefix[] = {'x', 'n', '-', '-'};
|
||||
if (comp_len <= base::size(kIdnPrefix) ||
|
||||
- memcmp(comp, kIdnPrefix, sizeof(kIdnPrefix)) != 0) {
|
||||
+ memcmp(comp, kIdnPrefix, sizeof(kIdnPrefix)) != 0 ||
|
||||
+ comp[comp_len - 1] == '-') {
|
||||
out->append(comp, comp_len);
|
||||
return false;
|
||||
}
|
||||
237
patches/chromium/cherry-pick-86c02c5dcd37.patch
Normal file
237
patches/chromium/cherry-pick-86c02c5dcd37.patch
Normal file
@@ -0,0 +1,237 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Matthias=20K=C3=B6rber?= <koerber@google.com>
|
||||
Date: Tue, 14 Apr 2020 16:55:14 +0000
|
||||
Subject: Fixed requesting invalid country codes from CountryData.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Change-Id: Id0ce647400bdce2eb4cdd358432b7c647f880570
|
||||
Bug: 1062861
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2122057
|
||||
Reviewed-by: Matthias Körber <koerber@google.com>
|
||||
Reviewed-by: Dominic Battré <battre@chromium.org>
|
||||
Reviewed-by: Vadym Doroshenko <dvadym@chromium.org>
|
||||
Commit-Queue: Matthias Körber <koerber@google.com>
|
||||
Cr-Commit-Position: refs/heads/master@{#758887}
|
||||
|
||||
diff --git a/components/autofill/core/browser/geo/autofill_country.cc b/components/autofill/core/browser/geo/autofill_country.cc
|
||||
index 4eb8f2b1a609deb314efd9b37578be9fa803ac67..961b1dc7a19f23c6f2cf9f831f5d544cc19cd211 100644
|
||||
--- a/components/autofill/core/browser/geo/autofill_country.cc
|
||||
+++ b/components/autofill/core/browser/geo/autofill_country.cc
|
||||
@@ -25,13 +25,28 @@ const size_t kLocaleCapacity =
|
||||
|
||||
AutofillCountry::AutofillCountry(const std::string& country_code,
|
||||
const std::string& locale) {
|
||||
- auto result =
|
||||
- CountryDataMap::GetInstance()->country_data().find(country_code);
|
||||
- DCHECK(result != CountryDataMap::GetInstance()->country_data().end());
|
||||
- const CountryData& data = result->second;
|
||||
+ CountryDataMap* country_data_map = CountryDataMap::GetInstance();
|
||||
|
||||
- country_code_ = country_code;
|
||||
- name_ = l10n_util::GetDisplayNameForCountry(country_code, locale);
|
||||
+ // If the country code is an alias (e.g. "GB" for "UK") expand the country
|
||||
+ // code.
|
||||
+ country_code_ = country_data_map->HasCountryCodeAlias(country_code)
|
||||
+ ? country_data_map->GetCountryCodeForAlias(country_code)
|
||||
+ : country_code;
|
||||
+
|
||||
+ // If there is no entry in the |CountryDataMap| for the
|
||||
+ // |country_code_for_country_data| use the country code derived from the
|
||||
+ // locale. This reverts to US.
|
||||
+ country_data_map->HasCountryData(country_code_)
|
||||
+ ? country_code_
|
||||
+ : CountryCodeForLocale(locale);
|
||||
+
|
||||
+ // Acquire the country address data.
|
||||
+ const CountryData& data = country_data_map->GetCountryData(country_code_);
|
||||
+
|
||||
+ // Translate the country name by the supplied local.
|
||||
+ name_ = l10n_util::GetDisplayNameForCountry(country_code_, locale);
|
||||
+
|
||||
+ // Get the localized strings associate with the address fields.
|
||||
postal_code_label_ = l10n_util::GetStringUTF16(data.postal_code_label_id);
|
||||
state_label_ = l10n_util::GetStringUTF16(data.state_label_id);
|
||||
address_required_fields_ = data.address_required_fields;
|
||||
diff --git a/components/autofill/core/browser/geo/autofill_country_unittest.cc b/components/autofill/core/browser/geo/autofill_country_unittest.cc
|
||||
index 8f3994de4f5d8b924cc47a989d86676ed01bd760..94315c13967f1ce640bba01a555f8b418af97ad3 100644
|
||||
--- a/components/autofill/core/browser/geo/autofill_country_unittest.cc
|
||||
+++ b/components/autofill/core/browser/geo/autofill_country_unittest.cc
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "base/android/build_info.h"
|
||||
#endif
|
||||
|
||||
+using autofill::CountryDataMap;
|
||||
using base::ASCIIToUTF16;
|
||||
|
||||
namespace autofill {
|
||||
@@ -30,6 +31,11 @@ TEST(AutofillCountryTest, AutofillCountry) {
|
||||
EXPECT_EQ("US", united_states_es.country_code());
|
||||
EXPECT_EQ(ASCIIToUTF16("Estados Unidos"), united_states_es.name());
|
||||
|
||||
+ AutofillCountry great_britain_uk_alias("UK", "en_GB");
|
||||
+ EXPECT_EQ("GB", great_britain_uk_alias.country_code());
|
||||
+ EXPECT_EQ("GB", great_britain_uk_alias.country_code());
|
||||
+ EXPECT_EQ(ASCIIToUTF16("United Kingdom"), great_britain_uk_alias.name());
|
||||
+
|
||||
AutofillCountry canada_en("CA", "en_US");
|
||||
EXPECT_EQ("CA", canada_en.country_code());
|
||||
EXPECT_EQ(ASCIIToUTF16("Canada"), canada_en.name());
|
||||
@@ -74,4 +80,27 @@ TEST(AutofillCountryTest, AllCountryCodesHaveCountryName) {
|
||||
}
|
||||
}
|
||||
|
||||
+// Test alias mappings for falsely existing country codes.
|
||||
+TEST(AutofillCountryTest, AliasMappingsForCountryData) {
|
||||
+ CountryDataMap* country_data_map = CountryDataMap::GetInstance();
|
||||
+
|
||||
+ // There should be country data for the "GB".
|
||||
+ EXPECT_TRUE(country_data_map->HasCountryData("GB"));
|
||||
+
|
||||
+ // Check the correctness of the alias definitions.
|
||||
+ EXPECT_TRUE(country_data_map->HasCountryCodeAlias("UK"));
|
||||
+ EXPECT_FALSE(country_data_map->HasCountryCodeAlias("does_not_exist"));
|
||||
+
|
||||
+ // Query not existing mapping.
|
||||
+ auto expected_country_code = std::string();
|
||||
+ auto actual_country_code =
|
||||
+ country_data_map->GetCountryCodeForAlias("does_not_exist");
|
||||
+ EXPECT_EQ(expected_country_code, actual_country_code);
|
||||
+
|
||||
+ // GB should map the UK.
|
||||
+ expected_country_code = "GB";
|
||||
+ actual_country_code = country_data_map->GetCountryCodeForAlias("UK");
|
||||
+ EXPECT_EQ(expected_country_code, actual_country_code);
|
||||
+}
|
||||
+
|
||||
} // namespace autofill
|
||||
diff --git a/components/autofill/core/browser/geo/country_data.cc b/components/autofill/core/browser/geo/country_data.cc
|
||||
index 1fe65ecf65323ce1917cb786b63d10ea4a7ac0b7..ec78e723ca71972d32ba00c2b46de9673fe91f46 100644
|
||||
--- a/components/autofill/core/browser/geo/country_data.cc
|
||||
+++ b/components/autofill/core/browser/geo/country_data.cc
|
||||
@@ -19,6 +19,17 @@ struct StaticCountryData {
|
||||
CountryData country_data;
|
||||
};
|
||||
|
||||
+// Alias definitions record for CountryData requests. A request for
|
||||
+// |country_code_alias| is served with the |CountryData| for
|
||||
+// |country_code_target|.
|
||||
+struct StaticCountryCodeAliasData {
|
||||
+ char country_code_alias[3];
|
||||
+ char country_code_target[3];
|
||||
+};
|
||||
+
|
||||
+// Alias definitions.
|
||||
+const StaticCountryCodeAliasData kCountryCodeAliases[] = {{"UK", "GB"}};
|
||||
+
|
||||
// Maps country codes to localized label string identifiers. Keep this sorted
|
||||
// by country code.
|
||||
// This list is comprized of countries appearing in both
|
||||
@@ -790,7 +801,7 @@ std::vector<std::string> GetCountryCodes() {
|
||||
return country_codes;
|
||||
}
|
||||
|
||||
-std::map<std::string, CountryData> GetCountryData() {
|
||||
+std::map<std::string, CountryData> GetCountryDataMap() {
|
||||
std::map<std::string, CountryData> country_data;
|
||||
// Add all the countries we have explicit data for.
|
||||
for (const auto& static_data : kCountryData) {
|
||||
@@ -813,6 +824,18 @@ std::map<std::string, CountryData> GetCountryData() {
|
||||
return country_data;
|
||||
}
|
||||
|
||||
+std::map<std::string, std::string> GetCountryCodeAliasMap() {
|
||||
+ std::map<std::string, std::string> country_code_aliases;
|
||||
+ // Create mappings for the aliases defined in |kCountryCodeAliases|.
|
||||
+ for (const auto& static_alias_data : kCountryCodeAliases) {
|
||||
+ // Insert the alias.
|
||||
+ country_code_aliases.insert(
|
||||
+ std::make_pair(std::string(static_alias_data.country_code_alias),
|
||||
+ std::string(static_alias_data.country_code_target)));
|
||||
+ }
|
||||
+ return country_code_aliases;
|
||||
+}
|
||||
+
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
@@ -821,8 +844,38 @@ CountryDataMap* CountryDataMap::GetInstance() {
|
||||
}
|
||||
|
||||
CountryDataMap::CountryDataMap()
|
||||
- : country_data_(GetCountryData()), country_codes_(GetCountryCodes()) {}
|
||||
+ : country_data_(GetCountryDataMap()),
|
||||
+ country_code_aliases_(GetCountryCodeAliasMap()),
|
||||
+ country_codes_(GetCountryCodes()) {}
|
||||
|
||||
CountryDataMap::~CountryDataMap() = default;
|
||||
|
||||
+bool CountryDataMap::HasCountryData(const std::string& country_code) const {
|
||||
+ return country_data_.count(country_code) > 0;
|
||||
+}
|
||||
+
|
||||
+const CountryData& CountryDataMap::GetCountryData(
|
||||
+ const std::string& country_code) const {
|
||||
+ auto lookup = country_data_.find(country_code);
|
||||
+ if (lookup != country_data_.end())
|
||||
+ return lookup->second;
|
||||
+ // If there is no entry for country_code return the entry for the US.
|
||||
+ return country_data_.find("US")->second;
|
||||
+}
|
||||
+
|
||||
+bool CountryDataMap::HasCountryCodeAlias(
|
||||
+ const std::string& country_code_alias) const {
|
||||
+ return country_code_aliases_.count(country_code_alias) > 0;
|
||||
+}
|
||||
+
|
||||
+const std::string CountryDataMap::GetCountryCodeForAlias(
|
||||
+ const std::string& country_code_alias) const {
|
||||
+ auto lookup = country_code_aliases_.find(country_code_alias);
|
||||
+ if (lookup != country_code_aliases_.end()) {
|
||||
+ DCHECK(HasCountryData(lookup->second));
|
||||
+ return lookup->second;
|
||||
+ }
|
||||
+ return std::string();
|
||||
+}
|
||||
+
|
||||
} // namespace autofill
|
||||
diff --git a/components/autofill/core/browser/geo/country_data.h b/components/autofill/core/browser/geo/country_data.h
|
||||
index b6a9497594b1c22a5521a9c40fab2decae449c3f..8266102deadd40e5f2b9b24703123f59034a9781 100644
|
||||
--- a/components/autofill/core/browser/geo/country_data.h
|
||||
+++ b/components/autofill/core/browser/geo/country_data.h
|
||||
@@ -58,10 +58,23 @@ class CountryDataMap {
|
||||
public:
|
||||
static CountryDataMap* GetInstance();
|
||||
|
||||
- const std::map<std::string, CountryData>& country_data() {
|
||||
- return country_data_;
|
||||
- }
|
||||
+ // Returns true if a |CountryData| entry for the supplied |country_code|
|
||||
+ // exists.
|
||||
+ bool HasCountryData(const std::string& country_code) const;
|
||||
|
||||
+ // Returns true if there is a country code alias for |country_code|.
|
||||
+ bool HasCountryCodeAlias(const std::string& country_code_alias) const;
|
||||
+
|
||||
+ // Returns the country code for a country code alias. If no alias definition
|
||||
+ // is present return an empty string.
|
||||
+ const std::string GetCountryCodeForAlias(
|
||||
+ const std::string& country_code_alias) const;
|
||||
+
|
||||
+ // Lookup the |CountryData| for the supplied |country_code|. If no entry
|
||||
+ // exists, return the data for the US as a best guess.
|
||||
+ const CountryData& GetCountryData(const std::string& country_code) const;
|
||||
+
|
||||
+ // Return a constant reference to a vector of all country codes.
|
||||
const std::vector<std::string>& country_codes() { return country_codes_; }
|
||||
|
||||
private:
|
||||
@@ -70,6 +83,7 @@ class CountryDataMap {
|
||||
friend struct base::DefaultSingletonTraits<CountryDataMap>;
|
||||
|
||||
const std::map<std::string, CountryData> country_data_;
|
||||
+ const std::map<std::string, std::string> country_code_aliases_;
|
||||
const std::vector<std::string> country_codes_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CountryDataMap);
|
||||
@@ -3,17 +3,8 @@ From: Jeremy Apthorp <jeremya@chromium.org>
|
||||
Date: Wed, 10 Oct 2018 15:07:34 -0700
|
||||
Subject: command-ismediakey.patch
|
||||
|
||||
Override MediaKeysListener::IsMediaKeycode to also listen for Volume Up, Volume Down,
|
||||
and Mute. We also need to patch out Chromium's usage of RemoteCommandCenterDelegate, as
|
||||
it uses MPRemoteCommandCenter. MPRemoteCommandCenter makes it such that GlobalShortcuts
|
||||
in Electron will not work as intended, because by design an app does not receive remote
|
||||
control events until it begins playing audio. This means that a media shortcut would not kick
|
||||
into effect until you, for example, began playing a YouTube video which sort of defeats the
|
||||
purpose of GlobalShortcuts.
|
||||
|
||||
At the moment there is no upstream possibility for this; but perhaps Chromium may
|
||||
consider some kind of switch, enabled by default, which would conditionally choose to avoid usage of
|
||||
RemoteCommandCenterDelegate on macOS.
|
||||
Override MediaKeysListener::IsMediaKeycode and associated functions to also listen for
|
||||
Volume Up, Volume Down, and Mute.
|
||||
|
||||
diff --git a/chrome/browser/extensions/global_shortcut_listener_win.cc b/chrome/browser/extensions/global_shortcut_listener_win.cc
|
||||
index c5125495b4d178ffb18be4d2d9670f7556412cbd..cddb321abb938c667a4a2089f87eab999510e9b1 100644
|
||||
@@ -73,18 +64,10 @@ index 1145e1f3d79482b5bb468c3128431ac674310e5f..e319e7a3e34e05b0e96d4a2dbb456355
|
||||
|
||||
} // namespace ui
|
||||
diff --git a/ui/base/accelerators/media_keys_listener_mac.mm b/ui/base/accelerators/media_keys_listener_mac.mm
|
||||
index 85378bb565de617b1bd611d28c8714361747a357..d67d558b91b49835dfa927893093948093c54f7a 100644
|
||||
index 85378bb565de617b1bd611d28c8714361747a357..36de4c0b0353be2418dacd388e92d7c38a7ee139 100644
|
||||
--- a/ui/base/accelerators/media_keys_listener_mac.mm
|
||||
+++ b/ui/base/accelerators/media_keys_listener_mac.mm
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <IOKit/hidsystem/ev_keymap.h>
|
||||
|
||||
#include "base/containers/flat_set.h"
|
||||
+#include "electron/buildflags/buildflags.h"
|
||||
#include "ui/base/accelerators/accelerator.h"
|
||||
#include "ui/base/accelerators/system_media_controls_media_keys_listener.h"
|
||||
|
||||
@@ -32,6 +33,12 @@ KeyboardCode MediaKeyCodeToKeyboardCode(int key_code) {
|
||||
@@ -32,6 +32,12 @@ KeyboardCode MediaKeyCodeToKeyboardCode(int key_code) {
|
||||
case NX_KEYTYPE_NEXT:
|
||||
case NX_KEYTYPE_FAST:
|
||||
return VKEY_MEDIA_NEXT_TRACK;
|
||||
@@ -97,7 +80,7 @@ index 85378bb565de617b1bd611d28c8714361747a357..d67d558b91b49835dfa9278930939480
|
||||
}
|
||||
return VKEY_UNKNOWN;
|
||||
}
|
||||
@@ -192,7 +199,10 @@ CGEventRef MediaKeysListenerImpl::EventTapCallback(CGEventTapProxy proxy,
|
||||
@@ -192,7 +198,10 @@ CGEventRef MediaKeysListenerImpl::EventTapCallback(CGEventTapProxy proxy,
|
||||
int key_code = (data1 & 0xFFFF0000) >> 16;
|
||||
if (key_code != NX_KEYTYPE_PLAY && key_code != NX_KEYTYPE_NEXT &&
|
||||
key_code != NX_KEYTYPE_PREVIOUS && key_code != NX_KEYTYPE_FAST &&
|
||||
@@ -109,3 +92,19 @@ index 85378bb565de617b1bd611d28c8714361747a357..d67d558b91b49835dfa9278930939480
|
||||
return event;
|
||||
}
|
||||
|
||||
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
|
||||
--- 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(
|
||||
case VKEY_MEDIA_STOP:
|
||||
service_->SetIsStopEnabled(true);
|
||||
break;
|
||||
+ case VKEY_VOLUME_DOWN:
|
||||
+ case VKEY_VOLUME_UP:
|
||||
+ case VKEY_VOLUME_MUTE:
|
||||
+ // Do nothing.
|
||||
+ break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ index a947db5fb562fb4ccbfb94df88f460f1da9451f4..77c816b2c5e98a4546c74d9358dfcf3f
|
||||
|
||||
gfx::ColorSpace::TransferID transfer_id =
|
||||
diff --git a/ui/gfx/mac/io_surface.cc b/ui/gfx/mac/io_surface.cc
|
||||
index c383d42c986aa29fcdfc2009901ed452ef480b55..1b8d0818155a407eb42c3f785e9609fe7bfa3dc7 100644
|
||||
index c383d42c986aa29fcdfc2009901ed452ef480b55..cdc87912b7d646a95796c84b76d583033c64c4dc 100644
|
||||
--- a/ui/gfx/mac/io_surface.cc
|
||||
+++ b/ui/gfx/mac/io_surface.cc
|
||||
@@ -16,6 +16,7 @@
|
||||
@@ -321,33 +321,37 @@ index c383d42c986aa29fcdfc2009901ed452ef480b55..1b8d0818155a407eb42c3f785e9609fe
|
||||
|
||||
namespace gfx {
|
||||
|
||||
@@ -261,6 +262,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);
|
||||
@@ -277,6 +283,14 @@ bool IOSurfaceCanSetColorSpace(const ColorSpace& color_space) {
|
||||
|
||||
void IOSurfaceSetColorSpace(IOSurfaceRef io_surface,
|
||||
@@ -126,6 +127,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;
|
||||
@@ -256,6 +265,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 ba3dbf23d1df7a3b0cc199054f36a88014daa0e7..f8a563a78cee2856da0f2ad556beba19b01a2e59 100644
|
||||
--- a/ui/gfx/switches.cc
|
||||
|
||||
@@ -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 1cafd4440108ccb8fe7f4f7c3d43a661dd626f15..8fdb75f76f5d9f207265c316e03818f36bcafbaa 100644
|
||||
--- a/services/network/public/mojom/network_service.mojom
|
||||
+++ b/services/network/public/mojom/network_service.mojom
|
||||
@@ -113,7 +113,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.
|
||||
148
patches/chromium/fix_hunspell_crash.patch
Normal file
148
patches/chromium/fix_hunspell_crash.patch
Normal file
@@ -0,0 +1,148 @@
|
||||
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: Make sure hunspell file is not destroyed in UI thread
|
||||
|
||||
Submitted to Chromium at:
|
||||
https://chromium-review.googlesource.com/c/chromium/src/+/2206199/1
|
||||
|
||||
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
|
||||
index 67ec4e285d9bf6b9de300845b2c53bda435e5784..74d403aeb1739d0424874a702e64cfd8c3fe4fcb 100644
|
||||
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
|
||||
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc
|
||||
@@ -91,21 +91,28 @@ bool SaveDictionaryData(std::unique_ptr<std::string> data,
|
||||
|
||||
} // namespace
|
||||
|
||||
-SpellcheckHunspellDictionary::DictionaryFile::DictionaryFile() {
|
||||
-}
|
||||
+SpellcheckHunspellDictionary::DictionaryFile::DictionaryFile(
|
||||
+ base::TaskRunner* task_runner) : task_runner_(task_runner) {}
|
||||
|
||||
SpellcheckHunspellDictionary::DictionaryFile::~DictionaryFile() {
|
||||
+ if (file.IsValid()) {
|
||||
+ task_runner_->PostTask(FROM_HERE,
|
||||
+ base::BindOnce(&CloseDictionary, std::move(file)));
|
||||
+ }
|
||||
}
|
||||
|
||||
SpellcheckHunspellDictionary::DictionaryFile::DictionaryFile(
|
||||
DictionaryFile&& other)
|
||||
- : path(other.path), file(std::move(other.file)) {}
|
||||
+ : path(other.path),
|
||||
+ file(std::move(other.file)),
|
||||
+ task_runner_(std::move(other.task_runner_)) {}
|
||||
|
||||
SpellcheckHunspellDictionary::DictionaryFile&
|
||||
SpellcheckHunspellDictionary::DictionaryFile::operator=(
|
||||
DictionaryFile&& other) {
|
||||
path = other.path;
|
||||
file = std::move(other.file);
|
||||
+ task_runner_ = std::move(other.task_runner_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -121,16 +128,10 @@ SpellcheckHunspellDictionary::SpellcheckHunspellDictionary(
|
||||
#if !defined(OS_ANDROID)
|
||||
spellcheck_service_(spellcheck_service),
|
||||
#endif
|
||||
- download_status_(DOWNLOAD_NONE) {
|
||||
-}
|
||||
+ download_status_(DOWNLOAD_NONE),
|
||||
+ dictionary_file_(task_runner_.get()) {}
|
||||
|
||||
SpellcheckHunspellDictionary::~SpellcheckHunspellDictionary() {
|
||||
- if (dictionary_file_.file.IsValid()) {
|
||||
- task_runner_->PostTask(
|
||||
- FROM_HERE,
|
||||
- base::BindOnce(&CloseDictionary, std::move(dictionary_file_.file)));
|
||||
- }
|
||||
-
|
||||
#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
|
||||
// Disable the language from platform spellchecker.
|
||||
if (spellcheck::UseBrowserSpellChecker())
|
||||
@@ -324,7 +325,8 @@ void SpellcheckHunspellDictionary::DownloadDictionary(GURL url) {
|
||||
#if !defined(OS_ANDROID)
|
||||
// static
|
||||
SpellcheckHunspellDictionary::DictionaryFile
|
||||
-SpellcheckHunspellDictionary::OpenDictionaryFile(const base::FilePath& path) {
|
||||
+SpellcheckHunspellDictionary::OpenDictionaryFile(base::TaskRunner* task_runner,
|
||||
+ const base::FilePath& path) {
|
||||
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
|
||||
base::BlockingType::MAY_BLOCK);
|
||||
|
||||
@@ -335,7 +337,7 @@ SpellcheckHunspellDictionary::OpenDictionaryFile(const base::FilePath& path) {
|
||||
// For systemwide installations on Windows, the default directory may not
|
||||
// have permissions for download. In that case, the alternate directory for
|
||||
// download is chrome::DIR_USER_DATA.
|
||||
- DictionaryFile dictionary;
|
||||
+ DictionaryFile dictionary(task_runner);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Check if the dictionary exists in the fallback location. If so, use it
|
||||
@@ -377,7 +379,7 @@ SpellcheckHunspellDictionary::OpenDictionaryFile(const base::FilePath& path) {
|
||||
// static
|
||||
SpellcheckHunspellDictionary::DictionaryFile
|
||||
SpellcheckHunspellDictionary::InitializeDictionaryLocation(
|
||||
- const std::string& language) {
|
||||
+ base::TaskRunner* task_runner, const std::string& language) {
|
||||
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
|
||||
base::BlockingType::MAY_BLOCK);
|
||||
|
||||
@@ -392,7 +394,7 @@ SpellcheckHunspellDictionary::InitializeDictionaryLocation(
|
||||
base::FilePath dict_path =
|
||||
spellcheck::GetVersionedFileName(language, dict_dir);
|
||||
|
||||
- return OpenDictionaryFile(dict_path);
|
||||
+ return OpenDictionaryFile(task_runner, dict_path);
|
||||
}
|
||||
|
||||
void SpellcheckHunspellDictionary::InitializeDictionaryLocationComplete(
|
||||
@@ -480,7 +482,8 @@ void SpellcheckHunspellDictionary::PlatformSupportsLanguageComplete(
|
||||
#if !defined(OS_ANDROID) && BUILDFLAG(USE_RENDERER_SPELLCHECKER)
|
||||
base::PostTaskAndReplyWithResult(
|
||||
task_runner_.get(), FROM_HERE,
|
||||
- base::BindOnce(&InitializeDictionaryLocation, language_),
|
||||
+ base::BindOnce(&InitializeDictionaryLocation,
|
||||
+ base::RetainedRef(task_runner_.get()), language_),
|
||||
base::BindOnce(
|
||||
&SpellcheckHunspellDictionary::InitializeDictionaryLocationComplete,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
|
||||
index 633ec3a96b39824fc9bcf374e59eb80148a2ae27..bfb90905ee045d8f08dbd0b348204b41fd185f41 100644
|
||||
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
|
||||
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
|
||||
@@ -99,7 +99,7 @@ class SpellcheckHunspellDictionary
|
||||
// blocking sequence.
|
||||
struct DictionaryFile {
|
||||
public:
|
||||
- DictionaryFile();
|
||||
+ explicit DictionaryFile(base::TaskRunner* task_runner);
|
||||
~DictionaryFile();
|
||||
|
||||
DictionaryFile(DictionaryFile&& other);
|
||||
@@ -112,6 +112,9 @@ class SpellcheckHunspellDictionary
|
||||
base::File file;
|
||||
|
||||
private:
|
||||
+ // Task runner where the file is created.
|
||||
+ scoped_refptr<base::TaskRunner> task_runner_;
|
||||
+
|
||||
DISALLOW_COPY_AND_ASSIGN(DictionaryFile);
|
||||
};
|
||||
|
||||
@@ -126,11 +129,12 @@ class SpellcheckHunspellDictionary
|
||||
#if !defined(OS_ANDROID)
|
||||
// Figures out the location for the dictionary, verifies its contents, and
|
||||
// opens it.
|
||||
- static DictionaryFile OpenDictionaryFile(const base::FilePath& path);
|
||||
+ static DictionaryFile OpenDictionaryFile(base::TaskRunner* task_runner,
|
||||
+ const base::FilePath& path);
|
||||
|
||||
// Gets the default location for the dictionary file.
|
||||
static DictionaryFile InitializeDictionaryLocation(
|
||||
- const std::string& language);
|
||||
+ base::TaskRunner* task_runner, const std::string& language);
|
||||
|
||||
// The reply point for PostTaskAndReplyWithResult, called after the dictionary
|
||||
// file has been initialized.
|
||||
@@ -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 86076cb3f39cdca7dbf31c668b8aaafb44e42d39..e7108f9548e0f01863339b12f6bd5e51b951b3fc 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/window_proxy.cc
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/window_proxy.cc
|
||||
@@ -109,10 +109,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
|
||||
@@ -123,6 +120,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 777bb67e5f7a1eb42438f91023a53c82fd041af2..3735f9b49899b4d36f005a3c2b741e3791ba0709 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/window_proxy.h
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/window_proxy.h
|
||||
@@ -157,6 +157,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 b8054889808b39f216bd85b019e2b05660c828de..5306426d84209c428a59fec6b468f57fbddd1fed 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)
|
||||
@@ -0,0 +1,144 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <samuel.r.attard@gmail.com>
|
||||
Date: Wed, 29 Apr 2020 13:36:00 -0700
|
||||
Subject: Never let a non-zero-size pixel snap to zero size
|
||||
|
||||
The logic for LayoutUnit::SnapSizeToPixel maps the size to
|
||||
the closest pixel align edge given a location. When a size of
|
||||
width less than 1 happens to straddle a pixel aligned edge this
|
||||
forces the size to zero.
|
||||
|
||||
Force the size to always be non-zero if the input size is non-zero,
|
||||
and change PhysicalRect to use the LayoutRect snapping to get
|
||||
correct cull rects.
|
||||
|
||||
Bug: 793785
|
||||
Change-Id: Ia4c30d10c389fb4677006441aac9ee380a7c2f41
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1948057
|
||||
Commit-Queue: Stephen Chenney <schenney@chromium.org>
|
||||
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#726516}
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/geometry/layout_unit.h b/third_party/blink/renderer/platform/geometry/layout_unit.h
|
||||
index eaaff017795237c83b9eb06e8cb70f8598ec5664..8ffe3e11501c005edb233130b231c33e6e79000b 100644
|
||||
--- a/third_party/blink/renderer/platform/geometry/layout_unit.h
|
||||
+++ b/third_party/blink/renderer/platform/geometry/layout_unit.h
|
||||
@@ -723,7 +723,12 @@ inline float& operator/=(float& a, const LayoutUnit& b) {
|
||||
|
||||
inline int SnapSizeToPixel(LayoutUnit size, LayoutUnit location) {
|
||||
LayoutUnit fraction = location.Fraction();
|
||||
- return (fraction + size).Round() - fraction.Round();
|
||||
+ int result = (fraction + size).Round() - fraction.Round();
|
||||
+ if (UNLIKELY(result == 0 &&
|
||||
+ std::abs(size.ToFloat()) > LayoutUnit::Epsilon() * 4)) {
|
||||
+ return size > 0 ? 1 : -1;
|
||||
+ }
|
||||
+ return result;
|
||||
}
|
||||
|
||||
inline int RoundToInt(LayoutUnit value) {
|
||||
diff --git a/third_party/blink/renderer/platform/geometry/layout_unit_test.cc b/third_party/blink/renderer/platform/geometry/layout_unit_test.cc
|
||||
index db1fa1f610f195eb7933ab044c26c3b2bae84120..05d4a2f762ede01f712470363ed118f7b37925a4 100644
|
||||
--- a/third_party/blink/renderer/platform/geometry/layout_unit_test.cc
|
||||
+++ b/third_party/blink/renderer/platform/geometry/layout_unit_test.cc
|
||||
@@ -155,8 +155,20 @@ TEST(LayoutUnitTest, LayoutUnitSnapSizeToPixel) {
|
||||
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.5), LayoutUnit(0.99)));
|
||||
EXPECT_EQ(2, SnapSizeToPixel(LayoutUnit(1.5), LayoutUnit(1)));
|
||||
|
||||
- EXPECT_EQ(0, SnapSizeToPixel(LayoutUnit(0.5), LayoutUnit(1.5)));
|
||||
- EXPECT_EQ(0, SnapSizeToPixel(LayoutUnit(0.99), LayoutUnit(1.5)));
|
||||
+ // 0.046875 is 3/64, lower than 4 * LayoutUnit::Epsilon()
|
||||
+ EXPECT_EQ(0, SnapSizeToPixel(LayoutUnit(0.046875), LayoutUnit(0)));
|
||||
+ // 0.078125 is 5/64, higher than 4 * LayoutUnit::Epsilon()
|
||||
+ EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(0.078125), LayoutUnit(0)));
|
||||
+
|
||||
+ // Negative versions
|
||||
+ EXPECT_EQ(0, SnapSizeToPixel(LayoutUnit(-0.046875), LayoutUnit(0)));
|
||||
+ EXPECT_EQ(-1, SnapSizeToPixel(LayoutUnit(-0.078125), LayoutUnit(0)));
|
||||
+
|
||||
+ // The next 2 would snap to zero but for the requirement that we not snap
|
||||
+ // sizes greater than 4 * LayoutUnit::Epsilon() to 0.
|
||||
+ EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(0.5), LayoutUnit(1.5)));
|
||||
+ EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(0.99), LayoutUnit(1.5)));
|
||||
+
|
||||
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.0), LayoutUnit(1.5)));
|
||||
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.49), LayoutUnit(1.5)));
|
||||
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.5), LayoutUnit(1.5)));
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/thin-element-render-ref.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/thin-element-render-ref.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0d5851d5544f9692d0761dc92c23b6b2b546b4d3
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/thin-element-render-ref.html
|
||||
@@ -0,0 +1,31 @@
|
||||
+<!DOCTYPE html>
|
||||
+<title>Reference: Thin elements should paint even at small size</title>
|
||||
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
|
||||
+<html>
|
||||
+ <head>
|
||||
+ <style>
|
||||
+ .disappearing-border {
|
||||
+ height:1px;
|
||||
+ width:100%;
|
||||
+ border-top:1px solid black;
|
||||
+ }
|
||||
+
|
||||
+ .disappearing-box {
|
||||
+ height:1px;
|
||||
+ width:100%;
|
||||
+ background-color: black;
|
||||
+ }
|
||||
+
|
||||
+ body {
|
||||
+ margin: 0px;
|
||||
+ padding: 0px;
|
||||
+ box-sizing: border-box;
|
||||
+ }
|
||||
+ </style>
|
||||
+</head>
|
||||
+<body>
|
||||
+ <div class="disappearing-border"></div>
|
||||
+ <div style="height:6.5px;"></div>
|
||||
+ <div class="disappearing-box"></div>
|
||||
+</body>
|
||||
+</html>
|
||||
\ No newline at end of file
|
||||
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/thin-element-render.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/thin-element-render.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fa587360a6d2625c8f02cd7f0eba54b3bb09a1f1
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/thin-element-render.html
|
||||
@@ -0,0 +1,33 @@
|
||||
+<!DOCTYPE html>
|
||||
+<title>Thin elements should still paint even at small size.</title>
|
||||
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
|
||||
+<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#width-height-keywords">
|
||||
+<link rel="match" href="thin-element-render-ref.html">
|
||||
+<html>
|
||||
+ <head>
|
||||
+ <style>
|
||||
+ .disappearing-border {
|
||||
+ height:0.25px;
|
||||
+ width:100%;
|
||||
+ border-top: 0.25px solid black;
|
||||
+ }
|
||||
+
|
||||
+ .disappearing-box {
|
||||
+ height:0.25px;
|
||||
+ width:100%;
|
||||
+ background-color: black;
|
||||
+ }
|
||||
+
|
||||
+ body {
|
||||
+ margin: 0px;
|
||||
+ padding: 0px;
|
||||
+ box-sizing: border-box;
|
||||
+ }
|
||||
+ </style>
|
||||
+</head>
|
||||
+<body>
|
||||
+ <div class="disappearing-border"></div>
|
||||
+ <div style="height:8px;"></div>
|
||||
+ <div class="disappearing-box"></div>
|
||||
+</body>
|
||||
+</html>
|
||||
\ No newline at end of file
|
||||
@@ -0,0 +1,359 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Harald Alvestrand <hta@chromium.org>
|
||||
Date: Wed, 22 Apr 2020 08:05:36 +0000
|
||||
Subject: Reland "Onstate handler is allowed to close a PeerConnection."
|
||||
|
||||
This reverts commit 94b16e2f5a5e99aec0c62754c31de2d297becf2d.
|
||||
|
||||
Reason for revert: Also landing fix from crbug.com/1071329
|
||||
Original change's description:
|
||||
> Revert "Onstate handler is allowed to close a PeerConnection."
|
||||
>
|
||||
> This reverts commit 9a2bc8e9cf63e70d47a443c673ae00d2b03ffc4f.
|
||||
>
|
||||
> Reason for revert: https://crbug.com/1073213
|
||||
>
|
||||
> Original change's description:
|
||||
> > Onstate handler is allowed to close a PeerConnection.
|
||||
> >
|
||||
> > (cherry picked from commit 919dd0c1244afdb269d023dd178bec8caec372ab)
|
||||
> >
|
||||
> > Bug: chromium:1068084
|
||||
> > Change-Id: Icd3f70b6784ac22ef4e3bc1c99233f51145a917f
|
||||
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2146542
|
||||
> > Commit-Queue: Harald Alvestrand <hta@chromium.org>
|
||||
> > Reviewed-by: Guido Urdaneta <guidou@chromium.org>
|
||||
> > Cr-Original-Commit-Position: refs/heads/master@{#759242}
|
||||
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2156993
|
||||
> > Reviewed-by: Harald Alvestrand <hta@chromium.org>
|
||||
> > Cr-Commit-Position: refs/branch-heads/4103@{#250}
|
||||
> > Cr-Branched-From: 8ad47e8d21f6866e4a37f47d83a860d41debf514-refs/heads/master@{#756066}
|
||||
>
|
||||
> TBR=hta@chromium.org
|
||||
>
|
||||
> Change-Id: If7400e9b7d02898bfadb31d31da2bf1a5df39801
|
||||
> No-Presubmit: true
|
||||
> No-Tree-Checks: true
|
||||
> No-Try: true
|
||||
> Bug: chromium:1068084, chromium:1073213
|
||||
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2159619
|
||||
> Reviewed-by: Carlos Knippschild <carlosk@chromium.org>
|
||||
> Commit-Queue: Carlos Knippschild <carlosk@chromium.org>
|
||||
> Cr-Commit-Position: refs/branch-heads/4103@{#262}
|
||||
> Cr-Branched-From: 8ad47e8d21f6866e4a37f47d83a860d41debf514-refs/heads/master@{#756066}
|
||||
|
||||
TBR=hta@chromium.org,carlosk@chromium.org
|
||||
|
||||
Change-Id: I7b6f58a11a83accc3cb14dcf3df637ea295a8d6e
|
||||
No-Presubmit: true
|
||||
No-Tree-Checks: true
|
||||
No-Try: true
|
||||
Bug: chromium:1068084, chromium:1073213
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2159715
|
||||
Reviewed-by: Harald Alvestrand <hta@chromium.org>
|
||||
Commit-Queue: Harald Alvestrand <hta@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/4103@{#271}
|
||||
Cr-Branched-From: 8ad47e8d21f6866e4a37f47d83a860d41debf514-refs/heads/master@{#756066}
|
||||
|
||||
diff --git a/third_party/blink/public/platform/web_rtc_peer_connection_handler.h b/third_party/blink/public/platform/web_rtc_peer_connection_handler.h
|
||||
index e1dd0f950d8a7391207e249242cd7b0e8d09a31a..1ad77dc31815a85e79d2e1cc5ce91cebd36a182e 100644
|
||||
--- a/third_party/blink/public/platform/web_rtc_peer_connection_handler.h
|
||||
+++ b/third_party/blink/public/platform/web_rtc_peer_connection_handler.h
|
||||
@@ -81,6 +81,15 @@ class WebRTCPeerConnectionHandler {
|
||||
virtual bool Initialize(
|
||||
const webrtc::PeerConnectionInterface::RTCConfiguration&,
|
||||
const WebMediaConstraints&) = 0;
|
||||
+
|
||||
+ virtual void Stop() = 0;
|
||||
+ // This function should be called when the object is taken out of service.
|
||||
+ // There might be functions that need to return through the object, so it
|
||||
+ // cannot be deleted yet, but no new operations should be allowed.
|
||||
+ // All references to the object except the owning reference are deleted
|
||||
+ // by this function.
|
||||
+ virtual void StopAndUnregister() = 0;
|
||||
+
|
||||
virtual void AssociateWithFrame(WebLocalFrame*) {}
|
||||
|
||||
// Unified Plan: The list of transceivers after the createOffer() call.
|
||||
@@ -144,7 +153,6 @@ class WebRTCPeerConnectionHandler {
|
||||
// In Unified Plan: Returns OK() with the updated transceiver state.
|
||||
virtual webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
|
||||
RemoveTrack(RTCRtpSenderPlatform*) = 0;
|
||||
- virtual void Stop() = 0;
|
||||
|
||||
// Returns a pointer to the underlying native PeerConnection object.
|
||||
virtual webrtc::PeerConnectionInterface* NativePeerConnection() = 0;
|
||||
diff --git a/third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h b/third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h
|
||||
index cfe440ac5e77dce9582ee053e61a74569448993b..4a7181f90d41aaf80ed3ff26fb0364fd78827c71 100644
|
||||
--- a/third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h
|
||||
+++ b/third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h
|
||||
@@ -84,7 +84,7 @@ class BLINK_PLATFORM_EXPORT WebRTCPeerConnectionHandlerClient {
|
||||
virtual void DidAddRemoteDataChannel(
|
||||
scoped_refptr<webrtc::DataChannelInterface>) = 0;
|
||||
virtual void DidNoteInterestingUsage(int usage_pattern) = 0;
|
||||
- virtual void ReleasePeerConnectionHandler() = 0;
|
||||
+ virtual void UnregisterPeerConnectionHandler() = 0;
|
||||
virtual void ClosePeerConnection();
|
||||
};
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.cc b/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.cc
|
||||
index beb724770432ff6d492c002cf14e05d9593887a8..b2c2b211da242afaf0845f245156c8114000aedb 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.cc
|
||||
@@ -395,6 +395,7 @@ MockWebRTCPeerConnectionHandler::CreateDataChannel(
|
||||
}
|
||||
|
||||
void MockWebRTCPeerConnectionHandler::Stop() {}
|
||||
+void MockWebRTCPeerConnectionHandler::StopAndUnregister() {}
|
||||
|
||||
webrtc::PeerConnectionInterface*
|
||||
MockWebRTCPeerConnectionHandler::NativePeerConnection() {
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.h b/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.h
|
||||
index 4fe3325eaeb3ef4bb7ce2186387513f96db3c913..c6b020707134e0628d6de28b29d354bf29fe24b1 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.h
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.h
|
||||
@@ -27,6 +27,8 @@ class MockWebRTCPeerConnectionHandler : public WebRTCPeerConnectionHandler {
|
||||
|
||||
bool Initialize(const webrtc::PeerConnectionInterface::RTCConfiguration&,
|
||||
const WebMediaConstraints&) override;
|
||||
+ void Stop() override;
|
||||
+ void StopAndUnregister() override;
|
||||
|
||||
WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
|
||||
RTCSessionDescriptionRequest*,
|
||||
@@ -73,7 +75,6 @@ class MockWebRTCPeerConnectionHandler : public WebRTCPeerConnectionHandler {
|
||||
scoped_refptr<webrtc::DataChannelInterface> CreateDataChannel(
|
||||
const WebString& label,
|
||||
const webrtc::DataChannelInit&) override;
|
||||
- void Stop() override;
|
||||
webrtc::PeerConnectionInterface* NativePeerConnection() override;
|
||||
void RunSynchronousOnceClosureOnSignalingThread(
|
||||
base::OnceClosure closure,
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.h b/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.h
|
||||
index 34345c9a3a81f1cd62b69743de2d597e36372591..6cb5ae5c9d67ae3e986eb29e8bb97d615a7d322d 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.h
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.h
|
||||
@@ -63,7 +63,7 @@ class MockWebRTCPeerConnectionHandlerClient
|
||||
MOCK_METHOD1(DidAddRemoteDataChannel,
|
||||
void(scoped_refptr<webrtc::DataChannelInterface>));
|
||||
MOCK_METHOD1(DidNoteInterestingUsage, void(int));
|
||||
- MOCK_METHOD0(ReleasePeerConnectionHandler, void());
|
||||
+ MOCK_METHOD0(UnregisterPeerConnectionHandler, void());
|
||||
|
||||
// Move-only arguments do not play nicely with MOCK, the workaround is to
|
||||
// EXPECT_CALL with these instead.
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
|
||||
index 6a70d3ba1f3c4ea263f07584110860265ff35162..8568a08d1380e844b27cc35919165357ba1b5c44 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
|
||||
@@ -800,9 +800,11 @@ RTCPeerConnection::~RTCPeerConnection() {
|
||||
}
|
||||
|
||||
void RTCPeerConnection::Dispose() {
|
||||
- // Promptly clears a raw reference from content/ to an on-heap object
|
||||
+ // Promptly clears the handler's pointer to |this|
|
||||
// so that content/ doesn't access it in a lazy sweeping phase.
|
||||
- peer_handler_.reset();
|
||||
+ if (peer_handler_) {
|
||||
+ peer_handler_->StopAndUnregister();
|
||||
+ }
|
||||
|
||||
// UMA for CallSetupStates. This metric is reported regardless of whether or
|
||||
// not getUserMedia() has been called in this document.
|
||||
@@ -3066,7 +3068,7 @@ void RTCPeerConnection::DidNoteInterestingUsage(int usage_pattern) {
|
||||
.Record(document->UkmRecorder());
|
||||
}
|
||||
|
||||
-void RTCPeerConnection::ReleasePeerConnectionHandler() {
|
||||
+void RTCPeerConnection::UnregisterPeerConnectionHandler() {
|
||||
if (stopped_)
|
||||
return;
|
||||
|
||||
@@ -3074,7 +3076,7 @@ void RTCPeerConnection::ReleasePeerConnectionHandler() {
|
||||
ice_connection_state_ = webrtc::PeerConnectionInterface::kIceConnectionClosed;
|
||||
signaling_state_ = webrtc::PeerConnectionInterface::SignalingState::kClosed;
|
||||
|
||||
- peer_handler_.reset();
|
||||
+ peer_handler_->StopAndUnregister();
|
||||
dispatch_scheduled_events_task_handle_.Cancel();
|
||||
feature_handle_for_scheduler_.reset();
|
||||
}
|
||||
@@ -3094,7 +3096,7 @@ ExecutionContext* RTCPeerConnection::GetExecutionContext() const {
|
||||
}
|
||||
|
||||
void RTCPeerConnection::ContextDestroyed(ExecutionContext*) {
|
||||
- ReleasePeerConnectionHandler();
|
||||
+ UnregisterPeerConnectionHandler();
|
||||
}
|
||||
|
||||
void RTCPeerConnection::ChangeSignalingState(
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
|
||||
index d756173ba4beb88a73018e54e263d42b55fd0db1..e5112d52c14c1b2416824c4f4616383f4f8743eb 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
|
||||
@@ -309,7 +309,7 @@ class MODULES_EXPORT RTCPeerConnection final
|
||||
void DidAddRemoteDataChannel(
|
||||
scoped_refptr<webrtc::DataChannelInterface> channel) override;
|
||||
void DidNoteInterestingUsage(int usage_pattern) override;
|
||||
- void ReleasePeerConnectionHandler() override;
|
||||
+ void UnregisterPeerConnectionHandler() override;
|
||||
void ClosePeerConnection() override;
|
||||
|
||||
// EventTarget
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
|
||||
index 6745fc1ae9746a3f9949f856b1501c48e85b5260..5b237e73a43f741aa0beb1ebffac31a1af711413 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
|
||||
@@ -1007,6 +1007,7 @@ RTCPeerConnectionHandler::RTCPeerConnectionHandler(
|
||||
: initialize_called_(false),
|
||||
client_(client),
|
||||
is_closed_(false),
|
||||
+ is_unregistered_(false),
|
||||
dependency_factory_(dependency_factory),
|
||||
track_adapter_map_(
|
||||
base::MakeRefCounted<blink::WebRtcMediaStreamTrackAdapterMap>(
|
||||
@@ -1019,6 +1020,12 @@ RTCPeerConnectionHandler::RTCPeerConnectionHandler(
|
||||
}
|
||||
|
||||
RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
|
||||
+ if (!is_unregistered_) {
|
||||
+ StopAndUnregister();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void RTCPeerConnectionHandler::StopAndUnregister() {
|
||||
DCHECK(task_runner_->RunsTasksInCurrentSequence());
|
||||
|
||||
Stop();
|
||||
@@ -1029,6 +1036,10 @@ RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
|
||||
|
||||
UMA_HISTOGRAM_COUNTS_10000("WebRTC.NumDataChannelsPerPeerConnection",
|
||||
num_data_channels_created_);
|
||||
+ // Clear the pointer to client_ so that it does not interfere with
|
||||
+ // garbage collection.
|
||||
+ client_ = nullptr;
|
||||
+ is_unregistered_ = true;
|
||||
}
|
||||
|
||||
void RTCPeerConnectionHandler::AssociateWithFrame(blink::WebLocalFrame* frame) {
|
||||
@@ -2131,6 +2142,10 @@ void RTCPeerConnectionHandler::OnSignalingChange(
|
||||
peer_connection_tracker_->TrackSignalingStateChange(this, stable_state);
|
||||
if (!is_closed_)
|
||||
client_->DidChangeSignalingState(stable_state);
|
||||
+ // The callback may have closed the PC. If so, do not continue.
|
||||
+ if (is_closed_ || !client_) {
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
previous_signaling_state_ = new_state;
|
||||
if (peer_connection_tracker_)
|
||||
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h
|
||||
index 1aa9ffa273be0e52e0c37268a78abf16b165b041..171d71e3ad69849d3bc5c3cc6d7c505f395df26a 100644
|
||||
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h
|
||||
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h
|
||||
@@ -107,6 +107,9 @@ class MODULES_EXPORT RTCPeerConnectionHandler
|
||||
server_configuration,
|
||||
const blink::WebMediaConstraints& options) override;
|
||||
|
||||
+ void Stop() override;
|
||||
+ void StopAndUnregister() override;
|
||||
+
|
||||
blink::WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
|
||||
blink::RTCSessionDescriptionRequest* request,
|
||||
const blink::WebMediaConstraints& options) override;
|
||||
@@ -162,7 +165,6 @@ class MODULES_EXPORT RTCPeerConnectionHandler
|
||||
scoped_refptr<webrtc::DataChannelInterface> CreateDataChannel(
|
||||
const blink::WebString& label,
|
||||
const webrtc::DataChannelInit& init) override;
|
||||
- void Stop() override;
|
||||
webrtc::PeerConnectionInterface* NativePeerConnection() override;
|
||||
void RunSynchronousOnceClosureOnSignalingThread(
|
||||
base::OnceClosure closure,
|
||||
@@ -339,14 +341,18 @@ class MODULES_EXPORT RTCPeerConnectionHandler
|
||||
// first call fails.
|
||||
bool initialize_called_;
|
||||
|
||||
- // |client_| is a weak pointer to the blink object (blink::RTCPeerConnection)
|
||||
+ // |client_| is a raw pointer to the blink object (blink::RTCPeerConnection)
|
||||
// that owns this object.
|
||||
- // It is valid for the lifetime of this object.
|
||||
- blink::WebRTCPeerConnectionHandlerClient* const client_;
|
||||
+ // It is valid for the lifetime of this object, but is cleared when
|
||||
+ // StopAndUnregister() is called, in order to make sure it doesn't
|
||||
+ // interfere with garbage collection of the owner object.
|
||||
+ blink::WebRTCPeerConnectionHandlerClient* client_;
|
||||
// True if this PeerConnection has been closed.
|
||||
// After the PeerConnection has been closed, this object may no longer
|
||||
// forward callbacks to blink.
|
||||
bool is_closed_;
|
||||
+ // True if StopAndUnregister has been called.
|
||||
+ bool is_unregistered_;
|
||||
|
||||
// Transition from kHaveLocalOffer to kHaveRemoteOffer indicates implicit
|
||||
// rollback in which case we need to also make visiting of kStable observable.
|
||||
diff --git a/third_party/blink/web_tests/fast/peerconnection/resources/statechange-iframe-destroy-child.html b/third_party/blink/web_tests/fast/peerconnection/resources/statechange-iframe-destroy-child.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c7e4ae5071d478329f66a6a70016a2705fff16a5
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/fast/peerconnection/resources/statechange-iframe-destroy-child.html
|
||||
@@ -0,0 +1,30 @@
|
||||
+<html>
|
||||
+<script>
|
||||
+'use strict;'
|
||||
+
|
||||
+let cnt = 0;
|
||||
+
|
||||
+function causeIssue() {
|
||||
+ youConnection = new RTCPeerConnection({});
|
||||
+
|
||||
+ youConnection.onsignalingstatechange = ev => {
|
||||
+ if(cnt==1) {
|
||||
+ parent.trigger();
|
||||
+ }
|
||||
+ cnt++;
|
||||
+ };
|
||||
+ var offerOptions = {
|
||||
+ offerToReceiveVideo: 1
|
||||
+ };
|
||||
+
|
||||
+ youConnection.createOffer(offerOptions)
|
||||
+ .then(function(offer){
|
||||
+ youConnection.setLocalDescription(offer);
|
||||
+ // Cause an implicit rollback.
|
||||
+ youConnection.setRemoteDescription(offer);
|
||||
+ });
|
||||
+}
|
||||
+
|
||||
+causeIssue();
|
||||
+</script>
|
||||
+</html>
|
||||
diff --git a/third_party/blink/web_tests/fast/peerconnection/statechange-iframe-destroy-parent.html b/third_party/blink/web_tests/fast/peerconnection/statechange-iframe-destroy-parent.html
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fcadc791fda05794362de0c1ff4352e258a6baeb
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/web_tests/fast/peerconnection/statechange-iframe-destroy-parent.html
|
||||
@@ -0,0 +1,24 @@
|
||||
+<html>
|
||||
+ <script src="../../resources/testharness.js"></script>
|
||||
+ <script src="../../resources/testharnessreport.js"></script>
|
||||
+ <iframe id="ifr">
|
||||
+ </iframe>
|
||||
+<script>
|
||||
+
|
||||
+let triggered = null;
|
||||
+
|
||||
+function trigger()
|
||||
+{
|
||||
+ ifr.remove();
|
||||
+ triggered();
|
||||
+}
|
||||
+
|
||||
+promise_test(t => {
|
||||
+ ifr.src = "resources/statechange-iframe-destroy-child.html";
|
||||
+ return new Promise(resolve => {
|
||||
+ triggered = resolve;
|
||||
+ });
|
||||
+}, 'Remove iframe from a statechange callback invoked from iframe');
|
||||
+
|
||||
+</script>
|
||||
+</html>
|
||||
@@ -118,10 +118,10 @@ index 6e3455921f5a1b81fe8a43d44beecfbd9aa93dc1..d3e521f1291a2f90963199cadba02ae3
|
||||
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/third_party/blink/renderer/modules/webaudio/base_audio_context.h
|
||||
index a99b2dddad44416d8761335f1111c441be79c486..051890e2742344d3ed2c8b6ae3b0c384eef252a0 100644
|
||||
index d6e4fe5e25ffbaa5273a7aa6d4042cc474ba1c06..af0a27d0cb49faa34de540df5c25ae4f1d6f8734 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/base_audio_context.h
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.h
|
||||
@@ -285,7 +285,7 @@ class MODULES_EXPORT BaseAudioContext
|
||||
@@ -282,7 +282,7 @@ class MODULES_EXPORT BaseAudioContext
|
||||
|
||||
DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
|
||||
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
{
|
||||
"src/electron/patches/chromium": "src",
|
||||
|
||||
"src/electron/patches/angle": "src/third_party/angle",
|
||||
|
||||
"src/electron/patches/boringssl": "src/third_party/boringssl/src",
|
||||
|
||||
"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/usrsctp": "src/third_party/usrsctp/usrsctplib"
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ inherit_electron_crashpad_pipe_name_in_child_process.patch
|
||||
fixme_revert_crypto_add_support_for_rsa-pss_keys.patch
|
||||
fix_extern_the_nativemoduleenv_and_options_parser_for_debug_builds.patch
|
||||
chore_read_nobrowserglobals_from_global_not_process.patch
|
||||
chore_split_createenvironment_into_createenvironment_and.patch
|
||||
chore_handle_default_configuration_not_being_set_in_the_electron_env.patch
|
||||
fsevents-stop-using-fsevents-to-watch-files.patch
|
||||
fsevents-regression-in-watching.patch
|
||||
@@ -41,3 +40,9 @@ fix_don_t_use_node-controlled_preparestacktrace.patch
|
||||
fix_remove_uses_of_node_use_v8_platform.patch
|
||||
fix_call_initializecontextruntime_in_initializecontext.patch
|
||||
refactor_transferrablemodule_is_deprecated_use_compiledwasmmodule.patch
|
||||
fix_don_t_preparemainexecution_twice.patch
|
||||
tls_emit_session_after_verifying_certificate.patch
|
||||
http2_implement_support_for_max_settings_entries.patch
|
||||
deps_update_nghttp2_to_1_40_0.patch
|
||||
deps_update_nghttp2_to_1_41_0.patch
|
||||
napi_fix_memory_corruption_vulnerability.patch
|
||||
|
||||
@@ -882,10 +882,10 @@ index 0000000000000000000000000000000000000000..f13b471d17128468bed06e66bd03a2ea
|
||||
+}
|
||||
diff --git a/filenames.json b/filenames.json
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bfe6555be5239c6d9cad59e8b845638d50f31ee3
|
||||
index 0000000000000000000000000000000000000000..76356ebaee56307b55e9da590d8c819f72599930
|
||||
--- /dev/null
|
||||
+++ b/filenames.json
|
||||
@@ -0,0 +1,447 @@
|
||||
@@ -0,0 +1,446 @@
|
||||
+// This file is automatically generated by generate_gn_filenames_json.py
|
||||
+// DO NOT EDIT
|
||||
+{
|
||||
@@ -955,7 +955,6 @@ index 0000000000000000000000000000000000000000..bfe6555be5239c6d9cad59e8b845638d
|
||||
+ }
|
||||
+ ],
|
||||
+ "library_files": [
|
||||
+ "lib/internal/bootstrap/environment.js",
|
||||
+ "lib/internal/bootstrap/loaders.js",
|
||||
+ "lib/internal/bootstrap/node.js",
|
||||
+ "lib/internal/bootstrap/pre_execution.js",
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <sattard@slack-corp.com>
|
||||
Date: Wed, 17 Jul 2019 14:45:59 -0700
|
||||
Subject: chore: split CreateEnvironment into CreateEnvironment and
|
||||
BootstrapEnvironment
|
||||
|
||||
This allows us to run operations on a created but not yet bootstrapped
|
||||
environment such as setting up an InspectorAgent
|
||||
|
||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||
index ae26cb7e9ef55fc0b965e28de4686aec87f42522..50886f4a998f1e7f346a6b7fad91ce49c3a7cdff 100644
|
||||
--- a/src/api/environment.cc
|
||||
+++ b/src/api/environment.cc
|
||||
@@ -263,7 +263,8 @@ Environment* CreateEnvironment(IsolateData* isolate_data,
|
||||
int argc,
|
||||
const char* const* argv,
|
||||
int exec_argc,
|
||||
- const char* const* exec_argv) {
|
||||
+ const char* const* exec_argv,
|
||||
+ bool bootstrap) {
|
||||
Isolate* isolate = context->GetIsolate();
|
||||
HandleScope handle_scope(isolate);
|
||||
Context::Scope context_scope(context);
|
||||
@@ -281,9 +282,16 @@ Environment* CreateEnvironment(IsolateData* isolate_data,
|
||||
Environment::kOwnsProcessState |
|
||||
Environment::kOwnsInspector));
|
||||
env->InitializeLibuv(per_process::v8_is_profiling);
|
||||
- if (env->RunBootstrapping().IsEmpty()) {
|
||||
+ if (bootstrap && !BootstrapEnvironment(env)) {
|
||||
return nullptr;
|
||||
}
|
||||
+ return env;
|
||||
+}
|
||||
+
|
||||
+bool BootstrapEnvironment(Environment* env) {
|
||||
+ if (env->RunBootstrapping().IsEmpty()) {
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
std::vector<Local<String>> parameters = {
|
||||
env->require_string(),
|
||||
@@ -296,9 +304,10 @@ Environment* CreateEnvironment(IsolateData* isolate_data,
|
||||
if (ExecuteBootstrapper(
|
||||
env, "internal/bootstrap/environment", ¶meters, &arguments)
|
||||
.IsEmpty()) {
|
||||
- return nullptr;
|
||||
+ return false;
|
||||
}
|
||||
- return env;
|
||||
+
|
||||
+ return true;
|
||||
}
|
||||
|
||||
void FreeEnvironment(Environment* env) {
|
||||
diff --git a/src/node.h b/src/node.h
|
||||
index 80a27dc734a81a7ca8d888d1d55fc8d24a536280..9c6dcbf7014f7cf87f7f66886cbf255978c244fa 100644
|
||||
--- a/src/node.h
|
||||
+++ b/src/node.h
|
||||
@@ -326,7 +326,9 @@ NODE_EXTERN Environment* CreateEnvironment(IsolateData* isolate_data,
|
||||
int argc,
|
||||
const char* const* argv,
|
||||
int exec_argc,
|
||||
- const char* const* exec_argv);
|
||||
+ const char* const* exec_argv,
|
||||
+ bool bootstrap = true);
|
||||
+NODE_EXTERN bool BootstrapEnvironment(Environment* env);
|
||||
|
||||
NODE_EXTERN void LoadEnvironment(Environment* env);
|
||||
NODE_EXTERN void FreeEnvironment(Environment* env);
|
||||
9820
patches/node/deps_update_nghttp2_to_1_40_0.patch
Normal file
9820
patches/node/deps_update_nghttp2_to_1_40_0.patch
Normal file
File diff suppressed because it is too large
Load Diff
494
patches/node/deps_update_nghttp2_to_1_41_0.patch
Normal file
494
patches/node/deps_update_nghttp2_to_1_41_0.patch
Normal file
@@ -0,0 +1,494 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: James M Snell <jasnell@gmail.com>
|
||||
Date: Mon, 27 Apr 2020 09:27:49 -0700
|
||||
Subject: deps: update nghttp2 to 1.41.0
|
||||
|
||||
Fixes: https://hackerone.com/reports/446662
|
||||
CVE-ID: CVE-2020-11080
|
||||
PR-URL: https://github.com/nodejs-private/node-private/pull/204
|
||||
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
||||
|
||||
diff --git a/deps/nghttp2/lib/CMakeLists.txt b/deps/nghttp2/lib/CMakeLists.txt
|
||||
deleted file mode 100644
|
||||
index 4e3f5da0f9f00afb272de2e110d0e101c075fc01..0000000000000000000000000000000000000000
|
||||
--- a/deps/nghttp2/lib/CMakeLists.txt
|
||||
+++ /dev/null
|
||||
@@ -1,76 +0,0 @@
|
||||
-add_subdirectory(includes)
|
||||
-
|
||||
-include_directories(
|
||||
- "${CMAKE_CURRENT_SOURCE_DIR}/includes"
|
||||
- "${CMAKE_CURRENT_BINARY_DIR}/includes"
|
||||
-)
|
||||
-
|
||||
-add_definitions(-DBUILDING_NGHTTP2)
|
||||
-
|
||||
-set(NGHTTP2_SOURCES
|
||||
- nghttp2_pq.c nghttp2_map.c nghttp2_queue.c
|
||||
- nghttp2_frame.c
|
||||
- nghttp2_buf.c
|
||||
- nghttp2_stream.c nghttp2_outbound_item.c
|
||||
- nghttp2_session.c nghttp2_submit.c
|
||||
- nghttp2_helper.c
|
||||
- nghttp2_npn.c
|
||||
- nghttp2_hd.c nghttp2_hd_huffman.c nghttp2_hd_huffman_data.c
|
||||
- nghttp2_version.c
|
||||
- nghttp2_priority_spec.c
|
||||
- nghttp2_option.c
|
||||
- nghttp2_callbacks.c
|
||||
- nghttp2_mem.c
|
||||
- nghttp2_http.c
|
||||
- nghttp2_rcbuf.c
|
||||
- nghttp2_debug.c
|
||||
-)
|
||||
-
|
||||
-set(NGHTTP2_RES "")
|
||||
-
|
||||
-if(WIN32)
|
||||
- configure_file(
|
||||
- version.rc.in
|
||||
- ${CMAKE_CURRENT_BINARY_DIR}/version.rc
|
||||
- @ONLY)
|
||||
-
|
||||
- set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
||||
-endif()
|
||||
-
|
||||
-# Public shared library
|
||||
-if(ENABLE_SHARED_LIB)
|
||||
- add_library(nghttp2 SHARED ${NGHTTP2_SOURCES} ${NGHTTP2_RES})
|
||||
- set_target_properties(nghttp2 PROPERTIES
|
||||
- COMPILE_FLAGS "${WARNCFLAGS}"
|
||||
- VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
|
||||
- C_VISIBILITY_PRESET hidden
|
||||
- )
|
||||
- target_include_directories(nghttp2 INTERFACE
|
||||
- "${CMAKE_CURRENT_BINARY_DIR}/includes"
|
||||
- "${CMAKE_CURRENT_SOURCE_DIR}/includes"
|
||||
- )
|
||||
-
|
||||
- install(TARGETS nghttp2
|
||||
- ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
- LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
- RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
-endif()
|
||||
-
|
||||
-if(HAVE_CUNIT OR ENABLE_STATIC_LIB)
|
||||
- # Static library (for unittests because of symbol visibility)
|
||||
- add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES})
|
||||
- set_target_properties(nghttp2_static PROPERTIES
|
||||
- COMPILE_FLAGS "${WARNCFLAGS}"
|
||||
- VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
|
||||
- ARCHIVE_OUTPUT_NAME nghttp2_static
|
||||
- )
|
||||
- target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
|
||||
- if(ENABLE_STATIC_LIB)
|
||||
- install(TARGETS nghttp2_static
|
||||
- DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
- endif()
|
||||
-endif()
|
||||
-
|
||||
-
|
||||
-install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
|
||||
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h
|
||||
index e3aeb9fed31ecc11e068a42e656c307575b4f024..9be6eea5c02257ac12522e43829f47b3f371b857 100644
|
||||
--- a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h
|
||||
+++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h
|
||||
@@ -228,6 +228,13 @@ typedef struct {
|
||||
*/
|
||||
#define NGHTTP2_CLIENT_MAGIC_LEN 24
|
||||
|
||||
+/**
|
||||
+ * @macro
|
||||
+ *
|
||||
+ * The default max number of settings per SETTINGS frame
|
||||
+ */
|
||||
+#define NGHTTP2_DEFAULT_MAX_SETTINGS 32
|
||||
+
|
||||
/**
|
||||
* @enum
|
||||
*
|
||||
@@ -398,6 +405,11 @@ typedef enum {
|
||||
* receives an other type of frame.
|
||||
*/
|
||||
NGHTTP2_ERR_SETTINGS_EXPECTED = -536,
|
||||
+ /**
|
||||
+ * When a local endpoint receives too many settings entries
|
||||
+ * in a single SETTINGS frame.
|
||||
+ */
|
||||
+ NGHTTP2_ERR_TOO_MANY_SETTINGS = -537,
|
||||
/**
|
||||
* The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is
|
||||
* under unexpected condition and processing was terminated (e.g.,
|
||||
@@ -2659,6 +2671,17 @@ NGHTTP2_EXTERN void nghttp2_option_set_no_closed_streams(nghttp2_option *option,
|
||||
NGHTTP2_EXTERN void nghttp2_option_set_max_outbound_ack(nghttp2_option *option,
|
||||
size_t val);
|
||||
|
||||
+/**
|
||||
+ * @function
|
||||
+ *
|
||||
+ * This function sets the maximum number of SETTINGS entries per
|
||||
+ * SETTINGS frame that will be accepted. If more than those entries
|
||||
+ * are received, the peer is considered to be misbehaving and session
|
||||
+ * will be closed. The default value is 32.
|
||||
+ */
|
||||
+NGHTTP2_EXTERN void nghttp2_option_set_max_settings(nghttp2_option *option,
|
||||
+ size_t val);
|
||||
+
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h
|
||||
index 45d21e2645c6cf8be52e445b3ab8862c08597d85..795a44c1e86863119e33e09309d7305e579af132 100644
|
||||
--- a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h
|
||||
+++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h
|
||||
@@ -29,7 +29,7 @@
|
||||
* @macro
|
||||
* Version number of the nghttp2 library release
|
||||
*/
|
||||
-#define NGHTTP2_VERSION "1.40.0"
|
||||
+#define NGHTTP2_VERSION "1.41.0"
|
||||
|
||||
/**
|
||||
* @macro
|
||||
@@ -37,6 +37,6 @@
|
||||
* release. This is a 24 bit number with 8 bits for major number, 8 bits
|
||||
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
|
||||
*/
|
||||
-#define NGHTTP2_VERSION_NUM 0x012800
|
||||
+#define NGHTTP2_VERSION_NUM 0x012900
|
||||
|
||||
#endif /* NGHTTP2VER_H */
|
||||
diff --git a/deps/nghttp2/lib/nghttp2_helper.c b/deps/nghttp2/lib/nghttp2_helper.c
|
||||
index 91136a61986014706b091d177e6abdf88f6444e3..0bd5414723d73688a2a546f9036c3d910ef3e53c 100644
|
||||
--- a/deps/nghttp2/lib/nghttp2_helper.c
|
||||
+++ b/deps/nghttp2/lib/nghttp2_helper.c
|
||||
@@ -334,6 +334,8 @@ const char *nghttp2_strerror(int error_code) {
|
||||
case NGHTTP2_ERR_FLOODED:
|
||||
return "Flooding was detected in this HTTP/2 session, and it must be "
|
||||
"closed";
|
||||
+ case NGHTTP2_ERR_TOO_MANY_SETTINGS:
|
||||
+ return "SETTINGS frame contained more than the maximum allowed entries";
|
||||
default:
|
||||
return "Unknown error code";
|
||||
}
|
||||
diff --git a/deps/nghttp2/lib/nghttp2_option.c b/deps/nghttp2/lib/nghttp2_option.c
|
||||
index e53f22d367f84a11792721d38a1cdc1a538e2a03..34348e6606ccf4206048f3f2f76d75a2ec366cc8 100644
|
||||
--- a/deps/nghttp2/lib/nghttp2_option.c
|
||||
+++ b/deps/nghttp2/lib/nghttp2_option.c
|
||||
@@ -121,3 +121,8 @@ void nghttp2_option_set_max_outbound_ack(nghttp2_option *option, size_t val) {
|
||||
option->opt_set_mask |= NGHTTP2_OPT_MAX_OUTBOUND_ACK;
|
||||
option->max_outbound_ack = val;
|
||||
}
|
||||
+
|
||||
+void nghttp2_option_set_max_settings(nghttp2_option *option, size_t val) {
|
||||
+ option->opt_set_mask |= NGHTTP2_OPT_MAX_SETTINGS;
|
||||
+ option->max_settings = val;
|
||||
+}
|
||||
diff --git a/deps/nghttp2/lib/nghttp2_option.h b/deps/nghttp2/lib/nghttp2_option.h
|
||||
index 1f740aaa6e364ed5a8df4804cff307ef36970b0b..939729fdcd5b6ec11078aef0d9b51e45270092a3 100644
|
||||
--- a/deps/nghttp2/lib/nghttp2_option.h
|
||||
+++ b/deps/nghttp2/lib/nghttp2_option.h
|
||||
@@ -67,6 +67,7 @@ typedef enum {
|
||||
NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9,
|
||||
NGHTTP2_OPT_NO_CLOSED_STREAMS = 1 << 10,
|
||||
NGHTTP2_OPT_MAX_OUTBOUND_ACK = 1 << 11,
|
||||
+ NGHTTP2_OPT_MAX_SETTINGS = 1 << 12,
|
||||
} nghttp2_option_flag;
|
||||
|
||||
/**
|
||||
@@ -85,6 +86,10 @@ struct nghttp2_option {
|
||||
* NGHTTP2_OPT_MAX_OUTBOUND_ACK
|
||||
*/
|
||||
size_t max_outbound_ack;
|
||||
+ /**
|
||||
+ * NGHTTP2_OPT_MAX_SETTINGS
|
||||
+ */
|
||||
+ size_t max_settings;
|
||||
/**
|
||||
* Bitwise OR of nghttp2_option_flag to determine that which fields
|
||||
* are specified.
|
||||
diff --git a/deps/nghttp2/lib/nghttp2_session.c b/deps/nghttp2/lib/nghttp2_session.c
|
||||
index 9df3d6f32938a692191abbad915e028a9669d24d..39f81f498cda798bcd18926414d7297f34361d2b 100644
|
||||
--- a/deps/nghttp2/lib/nghttp2_session.c
|
||||
+++ b/deps/nghttp2/lib/nghttp2_session.c
|
||||
@@ -458,6 +458,7 @@ static int session_new(nghttp2_session **session_ptr,
|
||||
|
||||
(*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN;
|
||||
(*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM;
|
||||
+ (*session_ptr)->max_settings = NGHTTP2_DEFAULT_MAX_SETTINGS;
|
||||
|
||||
if (option) {
|
||||
if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) &&
|
||||
@@ -521,6 +522,11 @@ static int session_new(nghttp2_session **session_ptr,
|
||||
if (option->opt_set_mask & NGHTTP2_OPT_MAX_OUTBOUND_ACK) {
|
||||
(*session_ptr)->max_outbound_ack = option->max_outbound_ack;
|
||||
}
|
||||
+
|
||||
+ if ((option->opt_set_mask & NGHTTP2_OPT_MAX_SETTINGS) &&
|
||||
+ option->max_settings) {
|
||||
+ (*session_ptr)->max_settings = option->max_settings;
|
||||
+ }
|
||||
}
|
||||
|
||||
rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
|
||||
@@ -2494,14 +2500,6 @@ static int session_update_stream_consumed_size(nghttp2_session *session,
|
||||
static int session_update_connection_consumed_size(nghttp2_session *session,
|
||||
size_t delta_size);
|
||||
|
||||
-static int session_update_recv_connection_window_size(nghttp2_session *session,
|
||||
- size_t delta_size);
|
||||
-
|
||||
-static int session_update_recv_stream_window_size(nghttp2_session *session,
|
||||
- nghttp2_stream *stream,
|
||||
- size_t delta_size,
|
||||
- int send_window_update);
|
||||
-
|
||||
/*
|
||||
* Called after a frame is sent. This function runs
|
||||
* on_frame_send_callback and handles stream closure upon END_STREAM
|
||||
@@ -2735,7 +2733,7 @@ static int session_after_frame_sent1(nghttp2_session *session) {
|
||||
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
|
||||
rv = session_update_connection_consumed_size(session, 0);
|
||||
} else {
|
||||
- rv = session_update_recv_connection_window_size(session, 0);
|
||||
+ rv = nghttp2_session_update_recv_connection_window_size(session, 0);
|
||||
}
|
||||
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
@@ -2761,7 +2759,8 @@ static int session_after_frame_sent1(nghttp2_session *session) {
|
||||
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
|
||||
rv = session_update_stream_consumed_size(session, stream, 0);
|
||||
} else {
|
||||
- rv = session_update_recv_stream_window_size(session, stream, 0, 1);
|
||||
+ rv =
|
||||
+ nghttp2_session_update_recv_stream_window_size(session, stream, 0, 1);
|
||||
}
|
||||
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
@@ -5019,22 +5018,10 @@ static int adjust_recv_window_size(int32_t *recv_window_size_ptr, size_t delta,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Accumulates received bytes |delta_size| for stream-level flow
|
||||
- * control and decides whether to send WINDOW_UPDATE to that stream.
|
||||
- * If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set, WINDOW_UPDATE will not
|
||||
- * be sent.
|
||||
- *
|
||||
- * This function returns 0 if it succeeds, or one of the following
|
||||
- * negative error codes:
|
||||
- *
|
||||
- * NGHTTP2_ERR_NOMEM
|
||||
- * Out of memory.
|
||||
- */
|
||||
-static int session_update_recv_stream_window_size(nghttp2_session *session,
|
||||
- nghttp2_stream *stream,
|
||||
- size_t delta_size,
|
||||
- int send_window_update) {
|
||||
+int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
|
||||
+ nghttp2_stream *stream,
|
||||
+ size_t delta_size,
|
||||
+ int send_window_update) {
|
||||
int rv;
|
||||
rv = adjust_recv_window_size(&stream->recv_window_size, delta_size,
|
||||
stream->local_window_size);
|
||||
@@ -5063,20 +5050,8 @@ static int session_update_recv_stream_window_size(nghttp2_session *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Accumulates received bytes |delta_size| for connection-level flow
|
||||
- * control and decides whether to send WINDOW_UPDATE to the
|
||||
- * connection. If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set,
|
||||
- * WINDOW_UPDATE will not be sent.
|
||||
- *
|
||||
- * This function returns 0 if it succeeds, or one of the following
|
||||
- * negative error codes:
|
||||
- *
|
||||
- * NGHTTP2_ERR_NOMEM
|
||||
- * Out of memory.
|
||||
- */
|
||||
-static int session_update_recv_connection_window_size(nghttp2_session *session,
|
||||
- size_t delta_size) {
|
||||
+int nghttp2_session_update_recv_connection_window_size(nghttp2_session *session,
|
||||
+ size_t delta_size) {
|
||||
int rv;
|
||||
rv = adjust_recv_window_size(&session->recv_window_size, delta_size,
|
||||
session->local_window_size);
|
||||
@@ -5678,6 +5653,12 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
break;
|
||||
}
|
||||
|
||||
+ /* Check the settings flood counter early to be safe */
|
||||
+ if (session->obq_flood_counter_ >= session->max_outbound_ack &&
|
||||
+ !(iframe->frame.hd.flags & NGHTTP2_FLAG_ACK)) {
|
||||
+ return NGHTTP2_ERR_FLOODED;
|
||||
+ }
|
||||
+
|
||||
iframe->state = NGHTTP2_IB_READ_SETTINGS;
|
||||
|
||||
if (iframe->payloadleft) {
|
||||
@@ -5688,6 +5669,16 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
iframe->max_niv =
|
||||
iframe->frame.hd.length / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH + 1;
|
||||
|
||||
+ if (iframe->max_niv - 1 > session->max_settings) {
|
||||
+ rv = nghttp2_session_terminate_session_with_reason(
|
||||
+ session, NGHTTP2_ENHANCE_YOUR_CALM,
|
||||
+ "SETTINGS: too many setting entries");
|
||||
+ if (nghttp2_is_fatal(rv)) {
|
||||
+ return rv;
|
||||
+ }
|
||||
+ return (ssize_t)inlen;
|
||||
+ }
|
||||
+
|
||||
iframe->iv = nghttp2_mem_malloc(mem, sizeof(nghttp2_settings_entry) *
|
||||
iframe->max_niv);
|
||||
|
||||
@@ -6454,7 +6445,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
}
|
||||
|
||||
/* Pad Length field is subject to flow control */
|
||||
- rv = session_update_recv_connection_window_size(session, readlen);
|
||||
+ rv = nghttp2_session_update_recv_connection_window_size(session, readlen);
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@@ -6477,7 +6468,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
|
||||
stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id);
|
||||
if (stream) {
|
||||
- rv = session_update_recv_stream_window_size(
|
||||
+ rv = nghttp2_session_update_recv_stream_window_size(
|
||||
session, stream, readlen,
|
||||
iframe->payloadleft ||
|
||||
(iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0);
|
||||
@@ -6524,7 +6515,8 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
if (readlen > 0) {
|
||||
ssize_t data_readlen;
|
||||
|
||||
- rv = session_update_recv_connection_window_size(session, readlen);
|
||||
+ rv = nghttp2_session_update_recv_connection_window_size(session,
|
||||
+ readlen);
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@@ -6533,7 +6525,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
return (ssize_t)inlen;
|
||||
}
|
||||
|
||||
- rv = session_update_recv_stream_window_size(
|
||||
+ rv = nghttp2_session_update_recv_stream_window_size(
|
||||
session, stream, readlen,
|
||||
iframe->payloadleft ||
|
||||
(iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0);
|
||||
@@ -6634,7 +6626,8 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
||||
if (readlen > 0) {
|
||||
/* Update connection-level flow control window for ignored
|
||||
DATA frame too */
|
||||
- rv = session_update_recv_connection_window_size(session, readlen);
|
||||
+ rv = nghttp2_session_update_recv_connection_window_size(session,
|
||||
+ readlen);
|
||||
if (nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@@ -7454,6 +7447,11 @@ static int nghttp2_session_upgrade_internal(nghttp2_session *session,
|
||||
if (settings_payloadlen % NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) {
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
+ /* SETTINGS frame contains too many settings */
|
||||
+ if (settings_payloadlen / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH
|
||||
+ > session->max_settings) {
|
||||
+ return NGHTTP2_ERR_TOO_MANY_SETTINGS;
|
||||
+ }
|
||||
rv = nghttp2_frame_unpack_settings_payload2(&iv, &niv, settings_payload,
|
||||
settings_payloadlen, mem);
|
||||
if (rv != 0) {
|
||||
diff --git a/deps/nghttp2/lib/nghttp2_session.h b/deps/nghttp2/lib/nghttp2_session.h
|
||||
index 90ead9c0395b4f1e42f94daadae57928e6c38df3..07bfbb6c90c8df07c0de4909bb72ff4942d15763 100644
|
||||
--- a/deps/nghttp2/lib/nghttp2_session.h
|
||||
+++ b/deps/nghttp2/lib/nghttp2_session.h
|
||||
@@ -267,6 +267,8 @@ struct nghttp2_session {
|
||||
/* The maximum length of header block to send. Calculated by the
|
||||
same way as nghttp2_hd_deflate_bound() does. */
|
||||
size_t max_send_header_block_length;
|
||||
+ /* The maximum number of settings accepted per SETTINGS frame. */
|
||||
+ size_t max_settings;
|
||||
/* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
|
||||
uint32_t next_stream_id;
|
||||
/* The last stream ID this session initiated. For client session,
|
||||
@@ -898,4 +900,36 @@ int nghttp2_session_terminate_session_with_reason(nghttp2_session *session,
|
||||
uint32_t error_code,
|
||||
const char *reason);
|
||||
|
||||
+/*
|
||||
+ * Accumulates received bytes |delta_size| for connection-level flow
|
||||
+ * control and decides whether to send WINDOW_UPDATE to the
|
||||
+ * connection. If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set,
|
||||
+ * WINDOW_UPDATE will not be sent.
|
||||
+ *
|
||||
+ * This function returns 0 if it succeeds, or one of the following
|
||||
+ * negative error codes:
|
||||
+ *
|
||||
+ * NGHTTP2_ERR_NOMEM
|
||||
+ * Out of memory.
|
||||
+ */
|
||||
+int nghttp2_session_update_recv_connection_window_size(nghttp2_session *session,
|
||||
+ size_t delta_size);
|
||||
+
|
||||
+/*
|
||||
+ * Accumulates received bytes |delta_size| for stream-level flow
|
||||
+ * control and decides whether to send WINDOW_UPDATE to that stream.
|
||||
+ * If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set, WINDOW_UPDATE will not
|
||||
+ * be sent.
|
||||
+ *
|
||||
+ * This function returns 0 if it succeeds, or one of the following
|
||||
+ * negative error codes:
|
||||
+ *
|
||||
+ * NGHTTP2_ERR_NOMEM
|
||||
+ * Out of memory.
|
||||
+ */
|
||||
+int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
|
||||
+ nghttp2_stream *stream,
|
||||
+ size_t delta_size,
|
||||
+ int send_window_update);
|
||||
+
|
||||
#endif /* NGHTTP2_SESSION_H */
|
||||
diff --git a/deps/nghttp2/lib/nghttp2_submit.c b/deps/nghttp2/lib/nghttp2_submit.c
|
||||
index f604eff5c9017fc272ac876d255d522303826d5e..744a49cf6098ec656a72553aa6f6f25240749109 100644
|
||||
--- a/deps/nghttp2/lib/nghttp2_submit.c
|
||||
+++ b/deps/nghttp2/lib/nghttp2_submit.c
|
||||
@@ -450,6 +450,13 @@ int nghttp2_session_set_local_window_size(nghttp2_session *session,
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
+
|
||||
+ if (window_size_increment > 0) {
|
||||
+ return nghttp2_session_add_window_update(session, 0, stream_id,
|
||||
+ window_size_increment);
|
||||
+ }
|
||||
+
|
||||
+ return nghttp2_session_update_recv_connection_window_size(session, 0);
|
||||
} else {
|
||||
stream = nghttp2_session_get_stream(session, stream_id);
|
||||
|
||||
@@ -476,11 +483,14 @@ int nghttp2_session_set_local_window_size(nghttp2_session *session,
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
- }
|
||||
|
||||
- if (window_size_increment > 0) {
|
||||
- return nghttp2_session_add_window_update(session, 0, stream_id,
|
||||
- window_size_increment);
|
||||
+ if (window_size_increment > 0) {
|
||||
+ return nghttp2_session_add_window_update(session, 0, stream_id,
|
||||
+ window_size_increment);
|
||||
+ }
|
||||
+
|
||||
+ return nghttp2_session_update_recv_stream_window_size(session, stream, 0,
|
||||
+ 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -5,10 +5,10 @@ Subject: fix: call InitializeContextRuntime in InitializeContext
|
||||
|
||||
|
||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||
index 50886f4a998f1e7f346a6b7fad91ce49c3a7cdff..6ec07527ad7a806f889d884507e9def1cf68b4c8 100644
|
||||
index ae26cb7e9ef55fc0b965e28de4686aec87f42522..05282ebb4414c9f1757763fd68893bf0c6005279 100644
|
||||
--- a/src/api/environment.cc
|
||||
+++ b/src/api/environment.cc
|
||||
@@ -371,8 +371,6 @@ Local<Context> NewContext(Isolate* isolate,
|
||||
@@ -362,8 +362,6 @@ Local<Context> NewContext(Isolate* isolate,
|
||||
return Local<Context>();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ index 50886f4a998f1e7f346a6b7fad91ce49c3a7cdff..6ec07527ad7a806f889d884507e9def1
|
||||
return context;
|
||||
}
|
||||
|
||||
@@ -457,6 +455,11 @@ bool InitializeContext(Local<Context> context) {
|
||||
@@ -448,6 +446,11 @@ bool InitializeContext(Local<Context> context) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
61
patches/node/fix_don_t_preparemainexecution_twice.patch
Normal file
61
patches/node/fix_don_t_preparemainexecution_twice.patch
Normal file
@@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Tue, 2 Jun 2020 17:04:54 -0500
|
||||
Subject: fix: don't prepareMainExecution twice
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In https://github.com/nodejs/node/pull/26788 (v12.0.0), Node.js added a
|
||||
bootstrapper to `CreateEnvironment`, which would prepare the main thread
|
||||
for execution any time an embedder created a new environment. However, this
|
||||
caused an unfortunate doubling-up effect; Node.js also ran bootstrapping
|
||||
(called `prepareMainThreadExecution`) for all other execution paths
|
||||
(like the repl, the actual main module, eval, etc).
|
||||

|
||||
To fix this, we can just remove bootstrapping code from `CreateEnvironment`.
|
||||

|
||||
|
||||
diff --git a/lib/internal/bootstrap/environment.js b/lib/internal/bootstrap/environment.js
|
||||
deleted file mode 100644
|
||||
index 79a67dae378202ee377f2f138560b74f673af6e4..0000000000000000000000000000000000000000
|
||||
--- a/lib/internal/bootstrap/environment.js
|
||||
+++ /dev/null
|
||||
@@ -1,13 +0,0 @@
|
||||
-'use strict';
|
||||
-
|
||||
-// This runs necessary preparations to prepare a complete Node.js context
|
||||
-// that depends on run time states.
|
||||
-// It is currently only intended for preparing contexts for embedders.
|
||||
-
|
||||
-/* global markBootstrapComplete */
|
||||
-const {
|
||||
- prepareMainThreadExecution
|
||||
-} = require('internal/bootstrap/pre_execution');
|
||||
-
|
||||
-prepareMainThreadExecution();
|
||||
-markBootstrapComplete();
|
||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||
index 05282ebb4414c9f1757763fd68893bf0c6005279..862b67f425ff43756093460cbeac214fdfe8ed84 100644
|
||||
--- a/src/api/environment.cc
|
||||
+++ b/src/api/environment.cc
|
||||
@@ -285,19 +285,6 @@ Environment* CreateEnvironment(IsolateData* isolate_data,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- std::vector<Local<String>> parameters = {
|
||||
- env->require_string(),
|
||||
- FIXED_ONE_BYTE_STRING(env->isolate(), "markBootstrapComplete")};
|
||||
- std::vector<Local<Value>> arguments = {
|
||||
- env->native_module_require(),
|
||||
- env->NewFunctionTemplate(MarkBootstrapComplete)
|
||||
- ->GetFunction(env->context())
|
||||
- .ToLocalChecked()};
|
||||
- if (ExecuteBootstrapper(
|
||||
- env, "internal/bootstrap/environment", ¶meters, &arguments)
|
||||
- .IsEmpty()) {
|
||||
- return nullptr;
|
||||
- }
|
||||
return env;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: James M Snell <jasnell@gmail.com>
|
||||
Date: Mon, 27 Apr 2020 10:47:58 -0700
|
||||
Subject: http2: implement support for max settings entries
|
||||
|
||||
Adds the maxSettings option to limit the number of settings
|
||||
entries allowed per SETTINGS frame. Default 32
|
||||
|
||||
Signed-off-by: James M Snell <jasnell@gmail.com>
|
||||
|
||||
Fixes: https://hackerone.com/reports/446662
|
||||
CVE-ID: CVE-2020-11080
|
||||
PR-URL: https://github.com/nodejs-private/node-private/pull/206
|
||||
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
|
||||
|
||||
diff --git a/doc/api/http2.md b/doc/api/http2.md
|
||||
index c37cc41d422384db6360d75d6b564e1e08c0a714..764c4b74ee013d7a3330599b09afea64a08180a1 100644
|
||||
--- a/doc/api/http2.md
|
||||
+++ b/doc/api/http2.md
|
||||
@@ -1958,6 +1958,8 @@ changes:
|
||||
* `options` {Object}
|
||||
* `maxDeflateDynamicTableSize` {number} Sets the maximum dynamic table size
|
||||
for deflating header fields. **Default:** `4Kib`.
|
||||
+ * `maxSettings` {number} Sets the maximum number of settings entries per
|
||||
+ `SETTINGS` frame. The minimum value allowed is `1`. **Default:** `32`.
|
||||
* `maxSessionMemory`{number} Sets the maximum memory that the `Http2Session`
|
||||
is permitted to use. The value is expressed in terms of number of megabytes,
|
||||
e.g. `1` equal 1 megabyte. The minimum value allowed is `1`.
|
||||
@@ -2073,6 +2075,8 @@ changes:
|
||||
**Default:** `false`.
|
||||
* `maxDeflateDynamicTableSize` {number} Sets the maximum dynamic table size
|
||||
for deflating header fields. **Default:** `4Kib`.
|
||||
+ * `maxSettings` {number} Sets the maximum number of settings entries per
|
||||
+ `SETTINGS` frame. The minimum value allowed is `1`. **Default:** `32`.
|
||||
* `maxSessionMemory`{number} Sets the maximum memory that the `Http2Session`
|
||||
is permitted to use. The value is expressed in terms of number of megabytes,
|
||||
e.g. `1` equal 1 megabyte. The minimum value allowed is `1`. This is a
|
||||
@@ -2154,6 +2158,9 @@ server.listen(80);
|
||||
<!-- YAML
|
||||
added: v8.4.0
|
||||
changes:
|
||||
+ - version: REPLACEME
|
||||
+ pr-url: https://github.com/nodejs-private/node-private/pull/204
|
||||
+ description: Added `maxSettings` option with a default of 32.
|
||||
- version: v8.9.3
|
||||
pr-url: https://github.com/nodejs/node/pull/17105
|
||||
description: Added the `maxOutstandingPings` option with a default limit of
|
||||
@@ -2168,6 +2175,8 @@ changes:
|
||||
* `options` {Object}
|
||||
* `maxDeflateDynamicTableSize` {number} Sets the maximum dynamic table size
|
||||
for deflating header fields. **Default:** `4Kib`.
|
||||
+ * `maxSettings` {number} Sets the maximum number of settings entries per
|
||||
+ `SETTINGS` frame. The minimum value allowed is `1`. **Default:** `32`.
|
||||
* `maxSessionMemory`{number} Sets the maximum memory that the `Http2Session`
|
||||
is permitted to use. The value is expressed in terms of number of megabytes,
|
||||
e.g. `1` equal 1 megabyte. The minimum value allowed is `1`.
|
||||
diff --git a/lib/internal/http2/util.js b/lib/internal/http2/util.js
|
||||
index 9cc2a30897b6aed9760b619f98d518fc6ee3ed2a..69a9ea2c64158d26362f6df39e146bcdd4b0dc43 100644
|
||||
--- a/lib/internal/http2/util.js
|
||||
+++ b/lib/internal/http2/util.js
|
||||
@@ -194,7 +194,8 @@ const IDX_OPTIONS_MAX_HEADER_LIST_PAIRS = 5;
|
||||
const IDX_OPTIONS_MAX_OUTSTANDING_PINGS = 6;
|
||||
const IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS = 7;
|
||||
const IDX_OPTIONS_MAX_SESSION_MEMORY = 8;
|
||||
-const IDX_OPTIONS_FLAGS = 9;
|
||||
+const IDX_OPTIONS_MAX_SETTINGS = 9;
|
||||
+const IDX_OPTIONS_FLAGS = 10;
|
||||
|
||||
function updateOptionsBuffer(options) {
|
||||
var flags = 0;
|
||||
@@ -243,6 +244,11 @@ function updateOptionsBuffer(options) {
|
||||
optionsBuffer[IDX_OPTIONS_MAX_SESSION_MEMORY] =
|
||||
Math.max(1, options.maxSessionMemory);
|
||||
}
|
||||
+ if (typeof options.maxSettings === 'number') {
|
||||
+ flags |= (1 << IDX_OPTIONS_MAX_SETTINGS);
|
||||
+ optionsBuffer[IDX_OPTIONS_MAX_SETTINGS] =
|
||||
+ Math.max(1, options.maxSettings);
|
||||
+ }
|
||||
optionsBuffer[IDX_OPTIONS_FLAGS] = flags;
|
||||
}
|
||||
|
||||
diff --git a/src/node_http2.cc b/src/node_http2.cc
|
||||
index 358c687768d61682943dbb04ee3bd32c051c321f..cac64a8c885b0363202e7f00b415fe969e4552d3 100644
|
||||
--- a/src/node_http2.cc
|
||||
+++ b/src/node_http2.cc
|
||||
@@ -202,6 +202,12 @@ Http2Options::Http2Options(Environment* env, nghttp2_session_type type) {
|
||||
if (flags & (1 << IDX_OPTIONS_MAX_SESSION_MEMORY)) {
|
||||
SetMaxSessionMemory(buffer[IDX_OPTIONS_MAX_SESSION_MEMORY] * 1e6);
|
||||
}
|
||||
+
|
||||
+ if (flags & (1 << IDX_OPTIONS_MAX_SETTINGS)) {
|
||||
+ nghttp2_option_set_max_settings(
|
||||
+ options_,
|
||||
+ static_cast<size_t>(buffer[IDX_OPTIONS_MAX_SETTINGS]));
|
||||
+ }
|
||||
}
|
||||
|
||||
void Http2Session::Http2Settings::Init() {
|
||||
diff --git a/src/node_http2_state.h b/src/node_http2_state.h
|
||||
index 692299a187f60a5e5b7d045b9894abc435a29de8..fd8f1c56607b1457f921382f729abfc6c63bfb0d 100644
|
||||
--- a/src/node_http2_state.h
|
||||
+++ b/src/node_http2_state.h
|
||||
@@ -52,6 +52,7 @@ namespace http2 {
|
||||
IDX_OPTIONS_MAX_OUTSTANDING_PINGS,
|
||||
IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS,
|
||||
IDX_OPTIONS_MAX_SESSION_MEMORY,
|
||||
+ IDX_OPTIONS_MAX_SETTINGS,
|
||||
IDX_OPTIONS_FLAGS
|
||||
};
|
||||
|
||||
diff --git a/test/parallel/test-http2-max-settings.js b/test/parallel/test-http2-max-settings.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2eae223d21bcc7388cb15969b6a3934acc6b3a7f
|
||||
--- /dev/null
|
||||
+++ b/test/parallel/test-http2-max-settings.js
|
||||
@@ -0,0 +1,35 @@
|
||||
+'use strict';
|
||||
+
|
||||
+const common = require('../common');
|
||||
+if (!common.hasCrypto)
|
||||
+ common.skip('missing crypto');
|
||||
+
|
||||
+const http2 = require('http2');
|
||||
+
|
||||
+const server = http2.createServer({ maxSettings: 1 });
|
||||
+
|
||||
+// TODO(@jasnell): There is still a session event
|
||||
+// emitted on the server side but it will be destroyed
|
||||
+// immediately after creation and there will be no
|
||||
+// stream created.
|
||||
+server.on('session', common.mustCall((session) => {
|
||||
+ session.on('stream', common.mustNotCall());
|
||||
+ session.on('remoteSettings', common.mustNotCall());
|
||||
+}));
|
||||
+server.on('stream', common.mustNotCall());
|
||||
+
|
||||
+server.listen(0, common.mustCall(() => {
|
||||
+ // Specify two settings entries when a max of 1 is allowed.
|
||||
+ // Connection should error immediately.
|
||||
+ const client = http2.connect(
|
||||
+ `http://localhost:${server.address().port}`, {
|
||||
+ settings: {
|
||||
+ // The actual settings values do not matter.
|
||||
+ headerTableSize: 1000,
|
||||
+ enablePush: false,
|
||||
+ } });
|
||||
+
|
||||
+ client.on('error', common.mustCall(() => {
|
||||
+ server.close();
|
||||
+ }));
|
||||
+}));
|
||||
diff --git a/test/parallel/test-http2-util-update-options-buffer.js b/test/parallel/test-http2-util-update-options-buffer.js
|
||||
index d9cfa0784926aeb720fccc28f0c1257bf35ac30e..9587d93d3bcbc84aafa669d2c95841df8bacc010 100644
|
||||
--- a/test/parallel/test-http2-util-update-options-buffer.js
|
||||
+++ b/test/parallel/test-http2-util-update-options-buffer.js
|
||||
@@ -22,7 +22,8 @@ const IDX_OPTIONS_MAX_HEADER_LIST_PAIRS = 5;
|
||||
const IDX_OPTIONS_MAX_OUTSTANDING_PINGS = 6;
|
||||
const IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS = 7;
|
||||
const IDX_OPTIONS_MAX_SESSION_MEMORY = 8;
|
||||
-const IDX_OPTIONS_FLAGS = 9;
|
||||
+const IDX_OPTIONS_MAX_SETTINGS = 9;
|
||||
+const IDX_OPTIONS_FLAGS = 10;
|
||||
|
||||
{
|
||||
updateOptionsBuffer({
|
||||
@@ -34,7 +35,8 @@ const IDX_OPTIONS_FLAGS = 9;
|
||||
maxHeaderListPairs: 6,
|
||||
maxOutstandingPings: 7,
|
||||
maxOutstandingSettings: 8,
|
||||
- maxSessionMemory: 9
|
||||
+ maxSessionMemory: 9,
|
||||
+ maxSettings: 10,
|
||||
});
|
||||
|
||||
strictEqual(optionsBuffer[IDX_OPTIONS_MAX_DEFLATE_DYNAMIC_TABLE_SIZE], 1);
|
||||
@@ -46,6 +48,7 @@ const IDX_OPTIONS_FLAGS = 9;
|
||||
strictEqual(optionsBuffer[IDX_OPTIONS_MAX_OUTSTANDING_PINGS], 7);
|
||||
strictEqual(optionsBuffer[IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS], 8);
|
||||
strictEqual(optionsBuffer[IDX_OPTIONS_MAX_SESSION_MEMORY], 9);
|
||||
+ strictEqual(optionsBuffer[IDX_OPTIONS_MAX_SETTINGS], 10);
|
||||
|
||||
const flags = optionsBuffer[IDX_OPTIONS_FLAGS];
|
||||
|
||||
@@ -57,6 +60,7 @@ const IDX_OPTIONS_FLAGS = 9;
|
||||
ok(flags & (1 << IDX_OPTIONS_MAX_HEADER_LIST_PAIRS));
|
||||
ok(flags & (1 << IDX_OPTIONS_MAX_OUTSTANDING_PINGS));
|
||||
ok(flags & (1 << IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS));
|
||||
+ ok(flags & (1 << IDX_OPTIONS_MAX_SETTINGS));
|
||||
}
|
||||
|
||||
{
|
||||
125
patches/node/napi_fix_memory_corruption_vulnerability.patch
Normal file
125
patches/node/napi_fix_memory_corruption_vulnerability.patch
Normal file
@@ -0,0 +1,125 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= <tniessen@tnie.de>
|
||||
Date: Mon, 27 Jan 2020 13:38:36 -0400
|
||||
Subject: napi: fix memory corruption vulnerability
|
||||
|
||||
Fixes: https://hackerone.com/reports/784186
|
||||
CVE-ID: CVE-2020-8174
|
||||
PR-URL: https://github.com/nodejs-private/node-private/pull/195
|
||||
Reviewed-By: Anna Henningsen <anna@addaleax.net>
|
||||
Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com>
|
||||
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
|
||||
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
|
||||
Reviewed-By: Rich Trott <rtrott@gmail.com>
|
||||
|
||||
diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc
|
||||
index a87af79a8908321a3f080fb32f9afc62695dcf07..a92bdfec2073f3107a170244ab5183c5263a62da 100644
|
||||
--- a/src/js_native_api_v8.cc
|
||||
+++ b/src/js_native_api_v8.cc
|
||||
@@ -2067,7 +2067,7 @@ napi_status napi_get_value_string_latin1(napi_env env,
|
||||
if (!buf) {
|
||||
CHECK_ARG(env, result);
|
||||
*result = val.As<v8::String>()->Length();
|
||||
- } else {
|
||||
+ } else if (bufsize != 0) {
|
||||
int copied =
|
||||
val.As<v8::String>()->WriteOneByte(env->isolate,
|
||||
reinterpret_cast<uint8_t*>(buf),
|
||||
@@ -2079,6 +2079,8 @@ napi_status napi_get_value_string_latin1(napi_env env,
|
||||
if (result != nullptr) {
|
||||
*result = copied;
|
||||
}
|
||||
+ } else if (result != nullptr) {
|
||||
+ *result = 0;
|
||||
}
|
||||
|
||||
return napi_clear_last_error(env);
|
||||
@@ -2106,7 +2108,7 @@ napi_status napi_get_value_string_utf8(napi_env env,
|
||||
if (!buf) {
|
||||
CHECK_ARG(env, result);
|
||||
*result = val.As<v8::String>()->Utf8Length(env->isolate);
|
||||
- } else {
|
||||
+ } else if (bufsize != 0) {
|
||||
int copied = val.As<v8::String>()->WriteUtf8(
|
||||
env->isolate,
|
||||
buf,
|
||||
@@ -2118,6 +2120,8 @@ napi_status napi_get_value_string_utf8(napi_env env,
|
||||
if (result != nullptr) {
|
||||
*result = copied;
|
||||
}
|
||||
+ } else if (result != nullptr) {
|
||||
+ *result = 0;
|
||||
}
|
||||
|
||||
return napi_clear_last_error(env);
|
||||
@@ -2146,7 +2150,7 @@ napi_status napi_get_value_string_utf16(napi_env env,
|
||||
CHECK_ARG(env, result);
|
||||
// V8 assumes UTF-16 length is the same as the number of characters.
|
||||
*result = val.As<v8::String>()->Length();
|
||||
- } else {
|
||||
+ } else if (bufsize != 0) {
|
||||
int copied = val.As<v8::String>()->Write(env->isolate,
|
||||
reinterpret_cast<uint16_t*>(buf),
|
||||
0,
|
||||
@@ -2157,6 +2161,8 @@ napi_status napi_get_value_string_utf16(napi_env env,
|
||||
if (result != nullptr) {
|
||||
*result = copied;
|
||||
}
|
||||
+ } else if (result != nullptr) {
|
||||
+ *result = 0;
|
||||
}
|
||||
|
||||
return napi_clear_last_error(env);
|
||||
diff --git a/test/js-native-api/test_string/test.js b/test/js-native-api/test_string/test.js
|
||||
index 1be34212a11c3f163e4b5c444c5320afd09976a5..b03cd0b361204466c673473d2d46dfde31857272 100644
|
||||
--- a/test/js-native-api/test_string/test.js
|
||||
+++ b/test/js-native-api/test_string/test.js
|
||||
@@ -81,3 +81,5 @@ assert.throws(() => {
|
||||
assert.throws(() => {
|
||||
test_string.TestLargeUtf16();
|
||||
}, /^Error: Invalid argument$/);
|
||||
+
|
||||
+test_string.TestMemoryCorruption(' '.repeat(64 * 1024));
|
||||
diff --git a/test/js-native-api/test_string/test_string.c b/test/js-native-api/test_string/test_string.c
|
||||
index 471678c251677afc81b9c14e47fa5a278d4d696b..e840feeacf2110e330e56fc2d47b0132eb0efc6a 100644
|
||||
--- a/test/js-native-api/test_string/test_string.c
|
||||
+++ b/test/js-native-api/test_string/test_string.c
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <limits.h> // INT_MAX
|
||||
+#include <string.h>
|
||||
#include <js_native_api.h>
|
||||
#include "../common.h"
|
||||
|
||||
@@ -244,6 +245,24 @@ static napi_value TestLargeUtf16(napi_env env, napi_callback_info info) {
|
||||
return output;
|
||||
}
|
||||
|
||||
+static napi_value TestMemoryCorruption(napi_env env, napi_callback_info info) {
|
||||
+ size_t argc = 1;
|
||||
+ napi_value args[1];
|
||||
+ NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
|
||||
+
|
||||
+ NAPI_ASSERT(env, argc == 1, "Wrong number of arguments");
|
||||
+
|
||||
+ char buf[10] = { 0 };
|
||||
+ NAPI_CALL(env, napi_get_value_string_utf8(env, args[0], buf, 0, NULL));
|
||||
+
|
||||
+ char zero[10] = { 0 };
|
||||
+ if (memcmp(buf, zero, sizeof(buf)) != 0) {
|
||||
+ NAPI_CALL(env, napi_throw_error(env, NULL, "Buffer overwritten"));
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
EXTERN_C_START
|
||||
napi_value Init(napi_env env, napi_value exports) {
|
||||
napi_property_descriptor properties[] = {
|
||||
@@ -258,6 +277,7 @@ napi_value Init(napi_env env, napi_value exports) {
|
||||
DECLARE_NAPI_PROPERTY("TestLargeUtf8", TestLargeUtf8),
|
||||
DECLARE_NAPI_PROPERTY("TestLargeLatin1", TestLargeLatin1),
|
||||
DECLARE_NAPI_PROPERTY("TestLargeUtf16", TestLargeUtf16),
|
||||
+ DECLARE_NAPI_PROPERTY("TestMemoryCorruption", TestMemoryCorruption),
|
||||
};
|
||||
|
||||
NAPI_CALL(env, napi_define_properties(
|
||||
201
patches/node/tls_emit_session_after_verifying_certificate.patch
Normal file
201
patches/node/tls_emit_session_after_verifying_certificate.patch
Normal file
@@ -0,0 +1,201 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Fedor Indutny <fedor@indutny.com>
|
||||
Date: Tue, 17 Mar 2020 20:51:38 -0700
|
||||
Subject: tls: emit `session` after verifying certificate
|
||||
|
||||
Prior to this patch `session` event was emitted after `secure` event on
|
||||
TLSSocket, but before `secureConnect` event. This is problematic for
|
||||
`https.Agent` because it must cache session only after verifying the
|
||||
remote peer's certificate.
|
||||
|
||||
Connecting to a server that presents an invalid certificate resulted
|
||||
in the session being cached after the handshake with the server and
|
||||
evicted right after a certifiate validation error and socket's
|
||||
destruction. A request initiated during this narrow window would pick
|
||||
the faulty session, send it to the malicious server and skip the
|
||||
verification of the server's certificate.
|
||||
|
||||
Fixes: https://hackerone.com/reports/811502
|
||||
CVE-ID: CVE-2020-8172
|
||||
PR-URL: https://github.com/nodejs-private/node-private/pull/200
|
||||
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
|
||||
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
||||
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
|
||||
Reviewed-By: James M Snell <jasnell@gmail.com>
|
||||
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
|
||||
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
|
||||
|
||||
diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js
|
||||
index 9c3fe656a7ce806381bc18a33102820b7967d6e5..6c124e7223e567ec3e0323938fabe7b54c9f4b76 100644
|
||||
--- a/lib/_tls_wrap.js
|
||||
+++ b/lib/_tls_wrap.js
|
||||
@@ -67,6 +67,8 @@ const kHandshakeTimeout = Symbol('handshake-timeout');
|
||||
const kRes = Symbol('res');
|
||||
const kSNICallback = Symbol('snicallback');
|
||||
const kEnableTrace = Symbol('enableTrace');
|
||||
+const kPendingSession = Symbol('pendingSession');
|
||||
+const kIsVerified = Symbol('verified');
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
@@ -250,7 +252,11 @@ function requestOCSPDone(socket) {
|
||||
function onnewsessionclient(sessionId, session) {
|
||||
debug('client emit session');
|
||||
const owner = this[owner_symbol];
|
||||
- owner.emit('session', session);
|
||||
+ if (owner[kIsVerified]) {
|
||||
+ owner.emit('session', session);
|
||||
+ } else {
|
||||
+ owner[kPendingSession] = session;
|
||||
+ }
|
||||
}
|
||||
|
||||
function onnewsession(sessionId, session) {
|
||||
@@ -388,6 +394,8 @@ function TLSSocket(socket, opts) {
|
||||
this.authorized = false;
|
||||
this.authorizationError = null;
|
||||
this[kRes] = null;
|
||||
+ this[kIsVerified] = false;
|
||||
+ this[kPendingSession] = null;
|
||||
|
||||
var wrap;
|
||||
if ((socket instanceof net.Socket && socket._handle) || !socket) {
|
||||
@@ -557,6 +565,8 @@ TLSSocket.prototype._destroySSL = function _destroySSL() {
|
||||
this.ssl._secureContext.context = null;
|
||||
}
|
||||
this.ssl = null;
|
||||
+ this[kPendingSession] = null;
|
||||
+ this[kIsVerified] = false;
|
||||
};
|
||||
|
||||
// Constructor guts, arbitrarily factored out.
|
||||
@@ -1350,6 +1360,12 @@ function onConnectSecure() {
|
||||
this.emit('secureConnect');
|
||||
}
|
||||
|
||||
+ this[kIsVerified] = true;
|
||||
+ const session = this[kPendingSession];
|
||||
+ this[kPendingSession] = null;
|
||||
+ if (session)
|
||||
+ this.emit('session', session);
|
||||
+
|
||||
this.removeListener('end', onConnectEnd);
|
||||
}
|
||||
|
||||
diff --git a/test/parallel/test-https-agent-session-injection.js b/test/parallel/test-https-agent-session-injection.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..cb9358b1b1700925e893fa9680fc734b35fb699c
|
||||
--- /dev/null
|
||||
+++ b/test/parallel/test-https-agent-session-injection.js
|
||||
@@ -0,0 +1,59 @@
|
||||
+'use strict';
|
||||
+const common = require('../common');
|
||||
+const assert = require('assert');
|
||||
+
|
||||
+if (!common.hasCrypto)
|
||||
+ common.skip('missing crypto');
|
||||
+
|
||||
+const https = require('https');
|
||||
+const fixtures = require('../common/fixtures');
|
||||
+
|
||||
+const options = {
|
||||
+ key: fixtures.readKey('agent1-key.pem'),
|
||||
+
|
||||
+ // NOTE: Certificate Common Name is 'agent1'
|
||||
+ cert: fixtures.readKey('agent1-cert.pem'),
|
||||
+
|
||||
+ // NOTE: TLS 1.3 creates new session ticket **after** handshake so
|
||||
+ // `getSession()` output will be different even if the session was reused
|
||||
+ // during the handshake.
|
||||
+ secureProtocol: 'TLSv1_2_method'
|
||||
+};
|
||||
+
|
||||
+const ca = [ fixtures.readKey('ca1-cert.pem') ];
|
||||
+
|
||||
+const server = https.createServer(options, function(req, res) {
|
||||
+ res.end('ok');
|
||||
+}).listen(0, common.mustCall(function() {
|
||||
+ const port = this.address().port;
|
||||
+
|
||||
+ const req = https.get({
|
||||
+ port,
|
||||
+ path: '/',
|
||||
+ ca,
|
||||
+ servername: 'nodejs.org',
|
||||
+ }, common.mustNotCall(() => {}));
|
||||
+
|
||||
+ req.on('error', common.mustCall((err) => {
|
||||
+ assert.strictEqual(
|
||||
+ err.message,
|
||||
+ 'Hostname/IP does not match certificate\'s altnames: ' +
|
||||
+ 'Host: nodejs.org. is not cert\'s CN: agent1');
|
||||
+
|
||||
+ const second = https.get({
|
||||
+ port,
|
||||
+ path: '/',
|
||||
+ ca,
|
||||
+ servername: 'nodejs.org',
|
||||
+ }, common.mustNotCall(() => {}));
|
||||
+
|
||||
+ second.on('error', common.mustCall((err) => {
|
||||
+ server.close();
|
||||
+
|
||||
+ assert.strictEqual(
|
||||
+ err.message,
|
||||
+ 'Hostname/IP does not match certificate\'s altnames: ' +
|
||||
+ 'Host: nodejs.org. is not cert\'s CN: agent1');
|
||||
+ }));
|
||||
+ }));
|
||||
+}));
|
||||
diff --git a/test/parallel/test-tls-secure-session.js b/test/parallel/test-tls-secure-session.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b4b9638a2ccc7a27f63285f42e825fbf342e435d
|
||||
--- /dev/null
|
||||
+++ b/test/parallel/test-tls-secure-session.js
|
||||
@@ -0,0 +1,46 @@
|
||||
+'use strict';
|
||||
+const common = require('../common');
|
||||
+if (!common.hasCrypto)
|
||||
+ common.skip('missing crypto');
|
||||
+const fixtures = require('../common/fixtures');
|
||||
+const assert = require('assert');
|
||||
+const tls = require('tls');
|
||||
+
|
||||
+const options = {
|
||||
+ key: fixtures.readKey('agent1-key.pem'),
|
||||
+
|
||||
+ // NOTE: Certificate Common Name is 'agent1'
|
||||
+ cert: fixtures.readKey('agent1-cert.pem'),
|
||||
+
|
||||
+ // NOTE: TLS 1.3 creates new session ticket **after** handshake so
|
||||
+ // `getSession()` output will be different even if the session was reused
|
||||
+ // during the handshake.
|
||||
+ secureProtocol: 'TLSv1_2_method'
|
||||
+};
|
||||
+
|
||||
+const server = tls.createServer(options, common.mustCall((socket) => {
|
||||
+ socket.end();
|
||||
+})).listen(0, common.mustCall(() => {
|
||||
+ let connected = false;
|
||||
+ let session = null;
|
||||
+
|
||||
+ const client = tls.connect({
|
||||
+ rejectUnauthorized: false,
|
||||
+ port: server.address().port,
|
||||
+ }, common.mustCall(() => {
|
||||
+ assert(!connected);
|
||||
+ assert(!session);
|
||||
+
|
||||
+ connected = true;
|
||||
+ }));
|
||||
+
|
||||
+ client.on('session', common.mustCall((newSession) => {
|
||||
+ assert(connected);
|
||||
+ assert(!session);
|
||||
+
|
||||
+ session = newSession;
|
||||
+
|
||||
+ client.end();
|
||||
+ server.close();
|
||||
+ }));
|
||||
+}));
|
||||
1
patches/usrsctp/.patches
Normal file
1
patches/usrsctp/.patches
Normal file
@@ -0,0 +1 @@
|
||||
cherry-pick-e89fe66d0473.patch
|
||||
57
patches/usrsctp/cherry-pick-e89fe66d0473.patch
Normal file
57
patches/usrsctp/cherry-pick-e89fe66d0473.patch
Normal file
@@ -0,0 +1,57 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Tuexen <tuexen@fh-muenster.de>
|
||||
Date: Fri, 10 Apr 2020 00:43:45 +0000
|
||||
Subject: Improve input validation when processing AUTH chunks
|
||||
|
||||
Cherry picked from:
|
||||
https://chromium.googlesource.com/external/github.com/sctplab/usrsctp/+/b218e8957d7af0b07ee3ca74caded05ada8d1df9
|
||||
https://chromium.googlesource.com/external/github.com/sctplab/usrsctp/+/e89fe66d04735dcfc6bfda1648fbe68008da6277
|
||||
|
||||
Bug: 1073602
|
||||
|
||||
diff --git a/usrsctplib/netinet/sctp_input.c b/usrsctplib/netinet/sctp_input.c
|
||||
index c62bb8506dc0fb86112f35e0b66d08c198e8f9bd..4e53dfb27ec597a8f6ac99c329bc80b9d7306836 100755
|
||||
--- a/usrsctplib/netinet/sctp_input.c
|
||||
+++ b/usrsctplib/netinet/sctp_input.c
|
||||
@@ -2178,7 +2178,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
|
||||
int init_offset, initack_offset, initack_limit;
|
||||
int retval;
|
||||
int error = 0;
|
||||
- uint8_t auth_chunk_buf[SCTP_PARAM_BUFFER_SIZE];
|
||||
+ uint8_t auth_chunk_buf[SCTP_CHUNK_BUFFER_SIZE];
|
||||
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
|
||||
struct socket *so;
|
||||
|
||||
@@ -2373,8 +2373,11 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
|
||||
if (auth_skipped) {
|
||||
struct sctp_auth_chunk *auth;
|
||||
|
||||
- auth = (struct sctp_auth_chunk *)
|
||||
- sctp_m_getptr(m, auth_offset, auth_len, auth_chunk_buf);
|
||||
+ if (auth_len <= SCTP_CHUNK_BUFFER_SIZE) {
|
||||
+ auth = (struct sctp_auth_chunk *)sctp_m_getptr(m, auth_offset, auth_len, auth_chunk_buf);
|
||||
+ } else {
|
||||
+ auth = NULL;
|
||||
+ }
|
||||
if ((auth == NULL) || sctp_handle_auth(stcb, auth, m, auth_offset)) {
|
||||
/* auth HMAC failed, dump the assoc and packet */
|
||||
SCTPDBG(SCTP_DEBUG_AUTH1,
|
||||
@@ -4846,11 +4849,13 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
if (auth_skipped && (stcb != NULL)) {
|
||||
struct sctp_auth_chunk *auth;
|
||||
|
||||
- auth = (struct sctp_auth_chunk *)
|
||||
- sctp_m_getptr(m, auth_offset,
|
||||
- auth_len, chunk_buf);
|
||||
- got_auth = 1;
|
||||
- auth_skipped = 0;
|
||||
+ if (auth_len <= SCTP_CHUNK_BUFFER_SIZE) {
|
||||
+ auth = (struct sctp_auth_chunk *)sctp_m_getptr(m, auth_offset, auth_len, chunk_buf);
|
||||
+ got_auth = 1;
|
||||
+ auth_skipped = 0;
|
||||
+ } else {
|
||||
+ auth = NULL;
|
||||
+ }
|
||||
if ((auth == NULL) || sctp_handle_auth(stcb, auth, m,
|
||||
auth_offset)) {
|
||||
/* auth HMAC failed so dump it */
|
||||
@@ -9,3 +9,7 @@ do_not_export_private_v8_symbols_on_windows.patch
|
||||
revert_cleanup_switch_offset_of_to_offsetof_where_possible.patch
|
||||
objects_fix_memory_leak_in_prototypeusers_add.patch
|
||||
fix_build_deprecated_attirbute_for_older_msvc_versions.patch
|
||||
use_context_of_then_function_for_promiseresolvethenablejob.patch
|
||||
merged_regexp_reserve_space_for_all_registers_in_interpreter.patch
|
||||
cherry-pick-d4ddf645c3ca.patch
|
||||
turn_some_dchecks_into_checks_in_schedule_methods.patch
|
||||
|
||||
30
patches/v8/cherry-pick-d4ddf645c3ca.patch
Normal file
30
patches/v8/cherry-pick-d4ddf645c3ca.patch
Normal file
@@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Tebbi <tebbi@chromium.org>
|
||||
Date: Tue, 5 May 2020 14:19:52 +0200
|
||||
Subject: fix bug in DeadCodeElimination
|
||||
|
||||
Bug: chromium:1076708
|
||||
Change-Id: I88a5eae0e562e32f1915deff3c4150ec4be14c6c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2181266
|
||||
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
|
||||
Commit-Queue: Georg Neis <neis@chromium.org>
|
||||
Auto-Submit: Tobias Tebbi <tebbi@chromium.org>
|
||||
Reviewed-by: Georg Neis <neis@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#67564}
|
||||
|
||||
diff --git a/src/compiler/dead-code-elimination.cc b/src/compiler/dead-code-elimination.cc
|
||||
index f39e6cabfbeb3e4fdd95a36d619c14adb6d5d956..bab6b7b506e368b7b4219015cc34a84b156ccd2d 100644
|
||||
--- a/src/compiler/dead-code-elimination.cc
|
||||
+++ b/src/compiler/dead-code-elimination.cc
|
||||
@@ -317,7 +317,10 @@ Reduction DeadCodeElimination::ReduceDeoptimizeOrReturnOrTerminateOrTailCall(
|
||||
node->opcode() == IrOpcode::kTailCall);
|
||||
Reduction reduction = PropagateDeadControl(node);
|
||||
if (reduction.Changed()) return reduction;
|
||||
- if (FindDeadInput(node) != nullptr) {
|
||||
+ // Terminate nodes are not part of actual control flow, so they should never
|
||||
+ // be replaced with Throw.
|
||||
+ if (node->opcode() != IrOpcode::kTerminate &&
|
||||
+ FindDeadInput(node) != nullptr) {
|
||||
Node* effect = NodeProperties::GetEffectInput(node, 0);
|
||||
Node* control = NodeProperties::GetControlInput(node, 0);
|
||||
if (effect->opcode() != IrOpcode::kUnreachable) {
|
||||
@@ -0,0 +1,81 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jakob Gruber <jgruber@chromium.org>
|
||||
Date: Mon, 6 Apr 2020 15:48:53 +0200
|
||||
Subject: Merged: [regexp] Reserve space for all registers in interpreter
|
||||
|
||||
This is a minimal version of https://crrev.com/c/2135642 intended for
|
||||
backmerges.
|
||||
|
||||
Ensure that the interpreter has space for all required registers.
|
||||
|
||||
(cherry picked from commit 30658b6b1b672e535e6046fa84674882e29b2279)
|
||||
|
||||
Tbr: leszeks@chromium.org
|
||||
No-Try: true
|
||||
No-Presubmit: true
|
||||
No-Treechecks: true
|
||||
Bug: chromium:1067270
|
||||
Change-Id: Iefd016b4845fb8698d1e0ef5f6a03df0e66aa576
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2137403
|
||||
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
|
||||
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#67013}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2144052
|
||||
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/8.1@{#61}
|
||||
Cr-Branched-From: a4dcd39d521d14c4b1cac020812e44ee04a7f244-refs/heads/8.1.307@{#1}
|
||||
Cr-Branched-From: f22c213304ec3542df87019aed0909b7dafeaa93-refs/heads/master@{#66031}
|
||||
|
||||
diff --git a/src/regexp/regexp-interpreter.cc b/src/regexp/regexp-interpreter.cc
|
||||
index adea0cf7c0951bd707cfd05dc3b69a34b55efa77..c0d4435d380f880f2d6890d3ac783944518560e2 100644
|
||||
--- a/src/regexp/regexp-interpreter.cc
|
||||
+++ b/src/regexp/regexp-interpreter.cc
|
||||
@@ -1045,8 +1045,29 @@ IrregexpInterpreter::Result IrregexpInterpreter::MatchForCallFromJs(
|
||||
return IrregexpInterpreter::RETRY;
|
||||
}
|
||||
|
||||
- return Match(isolate, regexp_obj, subject_string, registers, registers_length,
|
||||
- start_position, call_origin);
|
||||
+ // In generated code, registers are allocated on the stack. The given
|
||||
+ // `registers` argument is only guaranteed to hold enough space for permanent
|
||||
+ // registers (i.e. for captures), and not for temporary registers used only
|
||||
+ // during matcher execution. We match that behavior in the interpreter by
|
||||
+ // using a SmallVector as internal register storage.
|
||||
+ static constexpr int kBaseRegisterArraySize = 64; // Arbitrary.
|
||||
+ const int internal_register_count =
|
||||
+ Smi::ToInt(regexp_obj.DataAt(JSRegExp::kIrregexpMaxRegisterCountIndex));
|
||||
+ base::SmallVector<int, kBaseRegisterArraySize> internal_registers(
|
||||
+ internal_register_count);
|
||||
+
|
||||
+ Result result =
|
||||
+ Match(isolate, regexp_obj, subject_string, internal_registers.data(),
|
||||
+ internal_register_count, start_position, call_origin);
|
||||
+
|
||||
+ // Copy capture registers to the output array.
|
||||
+ if (result == IrregexpInterpreter::SUCCESS) {
|
||||
+ CHECK_GE(internal_registers.size(), registers_length);
|
||||
+ MemCopy(registers, internal_registers.data(),
|
||||
+ registers_length * sizeof(registers[0]));
|
||||
+ }
|
||||
+
|
||||
+ return result;
|
||||
}
|
||||
|
||||
IrregexpInterpreter::Result IrregexpInterpreter::MatchForCallFromRuntime(
|
||||
diff --git a/test/mjsunit/regress/regress-1067270.js b/test/mjsunit/regress/regress-1067270.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1c6eddf505aa55e622df9d7116ea7fbb2f516713
|
||||
--- /dev/null
|
||||
+++ b/test/mjsunit/regress/regress-1067270.js
|
||||
@@ -0,0 +1,11 @@
|
||||
+// 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
|
||||
+
|
||||
+const needle = Array(1802).join(" +") + Array(16884).join("A");
|
||||
+const string = "A";
|
||||
+
|
||||
+assertEquals(string.search(needle), -1);
|
||||
+assertEquals(string.search(needle), -1);
|
||||
@@ -0,0 +1,108 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Georg Neis <neis@chromium.org>
|
||||
Date: Tue, 5 May 2020 20:11:02 +0200
|
||||
Subject: Turn some DCHECKs into CHECKs in Schedule methods
|
||||
|
||||
Bug: chromium:1076708
|
||||
Change-Id: I7f065791310606e11fe89936a36f0fe7cb0d38e7
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2182639
|
||||
Auto-Submit: Georg Neis <neis@chromium.org>
|
||||
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
|
||||
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/master@{#67576}
|
||||
|
||||
diff --git a/src/compiler/schedule.cc b/src/compiler/schedule.cc
|
||||
index 8bdcef511b6ad9e42e54661e8b676170ac6ebe69..cc3243cb2e1b2080c208f8d4c72e1f450e33cf7c 100644
|
||||
--- a/src/compiler/schedule.cc
|
||||
+++ b/src/compiler/schedule.cc
|
||||
@@ -218,7 +218,7 @@ void Schedule::AddNode(BasicBlock* block, Node* node) {
|
||||
}
|
||||
|
||||
void Schedule::AddGoto(BasicBlock* block, BasicBlock* succ) {
|
||||
- DCHECK_EQ(BasicBlock::kNone, block->control());
|
||||
+ CHECK_EQ(BasicBlock::kNone, block->control());
|
||||
block->set_control(BasicBlock::kGoto);
|
||||
AddSuccessor(block, succ);
|
||||
}
|
||||
@@ -243,7 +243,7 @@ bool IsPotentiallyThrowingCall(IrOpcode::Value opcode) {
|
||||
|
||||
void Schedule::AddCall(BasicBlock* block, Node* call, BasicBlock* success_block,
|
||||
BasicBlock* exception_block) {
|
||||
- DCHECK_EQ(BasicBlock::kNone, block->control());
|
||||
+ CHECK_EQ(BasicBlock::kNone, block->control());
|
||||
DCHECK(IsPotentiallyThrowingCall(call->opcode()));
|
||||
block->set_control(BasicBlock::kCall);
|
||||
AddSuccessor(block, success_block);
|
||||
@@ -253,7 +253,7 @@ void Schedule::AddCall(BasicBlock* block, Node* call, BasicBlock* success_block,
|
||||
|
||||
void Schedule::AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock,
|
||||
BasicBlock* fblock) {
|
||||
- DCHECK_EQ(BasicBlock::kNone, block->control());
|
||||
+ CHECK_EQ(BasicBlock::kNone, block->control());
|
||||
DCHECK_EQ(IrOpcode::kBranch, branch->opcode());
|
||||
block->set_control(BasicBlock::kBranch);
|
||||
AddSuccessor(block, tblock);
|
||||
@@ -263,7 +263,7 @@ void Schedule::AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock,
|
||||
|
||||
void Schedule::AddSwitch(BasicBlock* block, Node* sw, BasicBlock** succ_blocks,
|
||||
size_t succ_count) {
|
||||
- DCHECK_EQ(BasicBlock::kNone, block->control());
|
||||
+ CHECK_EQ(BasicBlock::kNone, block->control());
|
||||
DCHECK_EQ(IrOpcode::kSwitch, sw->opcode());
|
||||
block->set_control(BasicBlock::kSwitch);
|
||||
for (size_t index = 0; index < succ_count; ++index) {
|
||||
@@ -273,28 +273,28 @@ void Schedule::AddSwitch(BasicBlock* block, Node* sw, BasicBlock** succ_blocks,
|
||||
}
|
||||
|
||||
void Schedule::AddTailCall(BasicBlock* block, Node* input) {
|
||||
- DCHECK_EQ(BasicBlock::kNone, block->control());
|
||||
+ CHECK_EQ(BasicBlock::kNone, block->control());
|
||||
block->set_control(BasicBlock::kTailCall);
|
||||
SetControlInput(block, input);
|
||||
if (block != end()) AddSuccessor(block, end());
|
||||
}
|
||||
|
||||
void Schedule::AddReturn(BasicBlock* block, Node* input) {
|
||||
- DCHECK_EQ(BasicBlock::kNone, block->control());
|
||||
+ CHECK_EQ(BasicBlock::kNone, block->control());
|
||||
block->set_control(BasicBlock::kReturn);
|
||||
SetControlInput(block, input);
|
||||
if (block != end()) AddSuccessor(block, end());
|
||||
}
|
||||
|
||||
void Schedule::AddDeoptimize(BasicBlock* block, Node* input) {
|
||||
- DCHECK_EQ(BasicBlock::kNone, block->control());
|
||||
+ CHECK_EQ(BasicBlock::kNone, block->control());
|
||||
block->set_control(BasicBlock::kDeoptimize);
|
||||
SetControlInput(block, input);
|
||||
if (block != end()) AddSuccessor(block, end());
|
||||
}
|
||||
|
||||
void Schedule::AddThrow(BasicBlock* block, Node* input) {
|
||||
- DCHECK_EQ(BasicBlock::kNone, block->control());
|
||||
+ CHECK_EQ(BasicBlock::kNone, block->control());
|
||||
block->set_control(BasicBlock::kThrow);
|
||||
SetControlInput(block, input);
|
||||
if (block != end()) AddSuccessor(block, end());
|
||||
@@ -302,8 +302,8 @@ void Schedule::AddThrow(BasicBlock* block, Node* input) {
|
||||
|
||||
void Schedule::InsertBranch(BasicBlock* block, BasicBlock* end, Node* branch,
|
||||
BasicBlock* tblock, BasicBlock* fblock) {
|
||||
- DCHECK_NE(BasicBlock::kNone, block->control());
|
||||
- DCHECK_EQ(BasicBlock::kNone, end->control());
|
||||
+ CHECK_NE(BasicBlock::kNone, block->control());
|
||||
+ CHECK_EQ(BasicBlock::kNone, end->control());
|
||||
end->set_control(block->control());
|
||||
block->set_control(BasicBlock::kBranch);
|
||||
MoveSuccessors(block, end);
|
||||
@@ -317,8 +317,8 @@ void Schedule::InsertBranch(BasicBlock* block, BasicBlock* end, Node* branch,
|
||||
|
||||
void Schedule::InsertSwitch(BasicBlock* block, BasicBlock* end, Node* sw,
|
||||
BasicBlock** succ_blocks, size_t succ_count) {
|
||||
- DCHECK_NE(BasicBlock::kNone, block->control());
|
||||
- DCHECK_EQ(BasicBlock::kNone, end->control());
|
||||
+ CHECK_NE(BasicBlock::kNone, block->control());
|
||||
+ CHECK_EQ(BasicBlock::kNone, end->control());
|
||||
end->set_control(block->control());
|
||||
block->set_control(BasicBlock::kSwitch);
|
||||
MoveSuccessors(block, end);
|
||||
@@ -0,0 +1,99 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Attard <samuel.r.attard@gmail.com>
|
||||
Date: Mon, 20 Apr 2020 12:11:40 -0700
|
||||
Subject: Use context of then function for PromiseResolveThenableJob
|
||||
|
||||
When a microtask is executed, we need to use an appropriate,
|
||||
non-detached Context for its execution. Currently with
|
||||
PromiseResolveThenableJobs [1], the Context used is always drawn from
|
||||
the realm of the Promise constructor being used. This may cause
|
||||
non-intuitive behavior, such as in the following case:
|
||||
|
||||
const DeadPromise = iframe.contentWindow.Promise;
|
||||
const p = DeadPromise.resolve({
|
||||
then() {
|
||||
return { success: true };
|
||||
}
|
||||
});
|
||||
p.then(result => { console.log(result); });
|
||||
|
||||
// Some time later, but synchronously...
|
||||
iframe.src = "http://example.com"; // navigate away.
|
||||
// DeadPromise's Context is detached state now.
|
||||
// p never gets resolved, and its reaction handler never gets called.
|
||||
|
||||
To fix this behavior, when PromiseResolveThenableJob is being queued up,
|
||||
the `then` method of the thenable should be used to determine the
|
||||
context of the resultant microtask. Doing so aligns with Firefox, and
|
||||
also with the latest HTML spec [2][3].
|
||||
|
||||
diff --git a/src/builtins/builtins-promise-gen.cc b/src/builtins/builtins-promise-gen.cc
|
||||
index fc0a3515883514f5e8b704cd10b0c4820c5107dc..adf9743f0e2ecfbe834cb053c5d3611e85b3d294 100644
|
||||
--- a/src/builtins/builtins-promise-gen.cc
|
||||
+++ b/src/builtins/builtins-promise-gen.cc
|
||||
@@ -1333,10 +1333,17 @@ TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) {
|
||||
{
|
||||
// 12. Perform EnqueueJob("PromiseJobs", PromiseResolveThenableJob,
|
||||
// «promise, resolution, thenAction»).
|
||||
+ // According to HTML, we use the context of the then function
|
||||
+ // (|thenAction|) as the context of the microtask. See step 3 of HTML's
|
||||
+ // EnqueueJob:
|
||||
+ // https://html.spec.whatwg.org/C/#enqueuejob(queuename,-job,-arguments)
|
||||
+ VARIABLE(var_then_context, MachineRepresentation::kTagged, native_context);
|
||||
+ ExtractHandlerContext(var_then.value(), &var_then_context);
|
||||
+ const TNode<NativeContext> native_then_context = LoadNativeContext(var_then_context.value());
|
||||
const TNode<PromiseResolveThenableJobTask> task =
|
||||
AllocatePromiseResolveThenableJobTask(promise, var_then.value(),
|
||||
- CAST(resolution), native_context);
|
||||
- TailCallBuiltin(Builtins::kEnqueueMicrotask, native_context, task);
|
||||
+ CAST(resolution), native_then_context);
|
||||
+ TailCallBuiltin(Builtins::kEnqueueMicrotask, native_then_context, task);
|
||||
}
|
||||
|
||||
BIND(&if_fulfill);
|
||||
diff --git a/src/objects/objects.cc b/src/objects/objects.cc
|
||||
index df192142c16de26678f832b1f7107c383f28ff2a..947141a5e6be4793c8915663e7f4cd7b7ae11486 100644
|
||||
--- a/src/objects/objects.cc
|
||||
+++ b/src/objects/objects.cc
|
||||
@@ -5903,10 +5903,20 @@ MaybeHandle<Object> JSPromise::Resolve(Handle<JSPromise> promise,
|
||||
|
||||
// 12. Perform EnqueueJob("PromiseJobs", PromiseResolveThenableJob,
|
||||
// «promise, resolution, thenAction»).
|
||||
+
|
||||
+ // According to HTML, we use the context of the then function (|thenAction|)
|
||||
+ // as the context of the microtask. See step 3 of HTML's EnqueueJob:
|
||||
+ // https://html.spec.whatwg.org/C/#enqueuejob(queuename,-job,-arguments)
|
||||
+ Handle<NativeContext> then_context;
|
||||
+ if (!JSReceiver::GetContextForMicrotask(Handle<JSReceiver>::cast(then_action))
|
||||
+ .ToHandle(&then_context)) {
|
||||
+ then_context = isolate->native_context();
|
||||
+ }
|
||||
+
|
||||
Handle<PromiseResolveThenableJobTask> task =
|
||||
isolate->factory()->NewPromiseResolveThenableJobTask(
|
||||
promise, Handle<JSReceiver>::cast(then_action),
|
||||
- Handle<JSReceiver>::cast(resolution), isolate->native_context());
|
||||
+ Handle<JSReceiver>::cast(resolution), then_context);
|
||||
if (isolate->debug()->is_active() && resolution->IsJSPromise()) {
|
||||
// Mark the dependency of the new {promise} on the {resolution}.
|
||||
Object::SetProperty(isolate, resolution,
|
||||
@@ -5914,8 +5924,7 @@ MaybeHandle<Object> JSPromise::Resolve(Handle<JSPromise> promise,
|
||||
promise)
|
||||
.Check();
|
||||
}
|
||||
- MicrotaskQueue* microtask_queue =
|
||||
- isolate->native_context()->microtask_queue();
|
||||
+ MicrotaskQueue* microtask_queue = then_context->microtask_queue();
|
||||
if (microtask_queue) microtask_queue->EnqueueMicrotask(*task);
|
||||
|
||||
// 13. Return undefined.
|
||||
@@ -5951,6 +5960,9 @@ Handle<Object> JSPromise::TriggerPromiseReactions(Isolate* isolate,
|
||||
Handle<PromiseReaction> reaction = Handle<PromiseReaction>::cast(task);
|
||||
reactions = handle(reaction->next(), isolate);
|
||||
|
||||
+ // According to HTML, we use the context of the appropriate handler as the
|
||||
+ // context of the microtask. See step 3 of HTML's EnqueueJob:
|
||||
+ // https://html.spec.whatwg.org/C/#enqueuejob(queuename,-job,-arguments)
|
||||
Handle<NativeContext> handler_context;
|
||||
|
||||
Handle<HeapObject> primary_handler;
|
||||
@@ -39,7 +39,7 @@ async function checkIfDocOnlyChange () {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (nonDocChange) {
|
||||
if (nonDocChange || filesChanged.data.length === 0) {
|
||||
process.exit(1);
|
||||
} else {
|
||||
process.exit(0);
|
||||
|
||||
@@ -8,11 +8,13 @@ def read_patch(patch_dir, patch_filename):
|
||||
"""Read a patch from |patch_dir/filename| and amend the commit message with
|
||||
metadata about the patch file it came from."""
|
||||
ret = []
|
||||
added_filename_line = False
|
||||
patch_path = os.path.join(patch_dir, patch_filename)
|
||||
with codecs.open(patch_path, encoding='utf-8') as f:
|
||||
for l in f.readlines():
|
||||
if l.startswith('diff -'):
|
||||
if not added_filename_line and (l.startswith('diff -') or l.startswith('---')):
|
||||
ret.append('Patch-Filename: {}\n'.format(patch_filename))
|
||||
added_filename_line = True
|
||||
ret.append(l)
|
||||
return ''.join(ret)
|
||||
|
||||
|
||||
@@ -166,7 +166,6 @@
|
||||
"parallel/test-v8-flags",
|
||||
"parallel/test-v8-coverage",
|
||||
"parallel/test-vm-basic",
|
||||
"parallel/test-vm-codegen",
|
||||
"parallel/test-vm-parse-abort-on-uncaught-exception",
|
||||
"parallel/test-vm-syntax-error-message",
|
||||
"parallel/test-warn-sigprof",
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "url/url_constants.h"
|
||||
// In SHARED_INTERMEDIATE_DIR.
|
||||
#include "widevine_cdm_version.h" // NOLINT(build/include)
|
||||
#include "widevine_cdm_version.h" // NOLINT(build/include_directory)
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE)
|
||||
#include "base/native_library.h"
|
||||
|
||||
@@ -29,6 +29,17 @@
|
||||
#include "shell/common/crash_reporter/crash_reporter_win.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
bool AllowWasmCodeGenerationCallback(v8::Local<v8::Context> context,
|
||||
v8::Local<v8::String>) {
|
||||
v8::Local<v8::Value> wasm_code_gen = context->GetEmbedderData(
|
||||
node::ContextEmbedderIndex::kAllowWasmCodeGeneration);
|
||||
return wasm_code_gen->IsUndefined() || wasm_code_gen->IsTrue();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
|
||||
#if !defined(OS_LINUX)
|
||||
@@ -76,23 +87,25 @@ int NodeMain(int argc, char* argv[]) {
|
||||
|
||||
// Initialize gin::IsolateHolder.
|
||||
JavascriptEnvironment gin_env(loop);
|
||||
gin_env.isolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
|
||||
|
||||
node::IsolateData* isolate_data =
|
||||
node::CreateIsolateData(gin_env.isolate(), loop, gin_env.platform());
|
||||
CHECK_NE(nullptr, isolate_data);
|
||||
|
||||
node::Environment* env =
|
||||
node::CreateEnvironment(isolate_data, gin_env.context(), argc, argv,
|
||||
exec_argc, exec_argv, false);
|
||||
node::Environment* env = node::CreateEnvironment(
|
||||
isolate_data, gin_env.context(), argc, argv, exec_argc, exec_argv);
|
||||
CHECK_NE(nullptr, env);
|
||||
|
||||
// Enable support for v8 inspector.
|
||||
NodeDebugger node_debugger(env);
|
||||
node_debugger.Start();
|
||||
|
||||
node::BootstrapEnvironment(env);
|
||||
|
||||
gin_helper::Dictionary process(gin_env.isolate(), env->process_object());
|
||||
|
||||
gin_env.isolate()->SetAllowWasmCodeGenerationCallback(
|
||||
AllowWasmCodeGenerationCallback);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
process.SetMethod("log", &ElectronBindings::Log);
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "base/callback.h"
|
||||
#include "base/location.h"
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "uv.h" // NOLINT(build/include)
|
||||
#include "uv.h" // NOLINT(build/include_directory)
|
||||
|
||||
namespace electron {
|
||||
|
||||
|
||||
@@ -1415,8 +1415,8 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
base::BindRepeating(&Browser::GetVersion, browser))
|
||||
.SetMethod("setVersion",
|
||||
base::BindRepeating(&Browser::SetVersion, browser))
|
||||
.SetMethod("_getName", base::BindRepeating(&Browser::GetName, browser))
|
||||
.SetMethod("_setName", base::BindRepeating(&Browser::SetName, browser))
|
||||
.SetMethod("getName", base::BindRepeating(&Browser::GetName, browser))
|
||||
.SetMethod("setName", base::BindRepeating(&Browser::SetName, browser))
|
||||
.SetMethod("isReady", base::BindRepeating(&Browser::is_ready, browser))
|
||||
.SetMethod("whenReady", base::BindRepeating(&Browser::WhenReady, browser))
|
||||
.SetMethod("addRecentDocument",
|
||||
@@ -1437,20 +1437,15 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod(
|
||||
"getApplicationNameForProtocol",
|
||||
base::BindRepeating(&Browser::GetApplicationNameForProtocol, browser))
|
||||
.SetMethod("_setBadgeCount",
|
||||
.SetMethod("setBadgeCount",
|
||||
base::BindRepeating(&Browser::SetBadgeCount, browser))
|
||||
.SetMethod("_getBadgeCount",
|
||||
.SetMethod("getBadgeCount",
|
||||
base::BindRepeating(&Browser::GetBadgeCount, browser))
|
||||
.SetMethod("getLoginItemSettings", &App::GetLoginItemSettings)
|
||||
.SetMethod("setLoginItemSettings",
|
||||
base::BindRepeating(&Browser::SetLoginItemSettings, browser))
|
||||
.SetMethod("isEmojiPanelSupported",
|
||||
base::BindRepeating(&Browser::IsEmojiPanelSupported, browser))
|
||||
.SetProperty("badgeCount",
|
||||
base::BindRepeating(&Browser::GetBadgeCount, browser),
|
||||
base::BindRepeating(&Browser::SetBadgeCount, browser))
|
||||
.SetProperty("name", base::BindRepeating(&Browser::GetName, browser),
|
||||
base::BindRepeating(&Browser::SetName, browser))
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("hide", base::BindRepeating(&Browser::Hide, browser))
|
||||
.SetMethod("show", base::BindRepeating(&Browser::Show, browser))
|
||||
@@ -1475,9 +1470,6 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||
.SetMethod("showEmojiPanel",
|
||||
base::BindRepeating(&Browser::ShowEmojiPanel, browser))
|
||||
.SetProperty("accessibilitySupportEnabled",
|
||||
&App::IsAccessibilitySupportEnabled,
|
||||
&App::SetAccessibilitySupportEnabled)
|
||||
#endif
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("setUserTasks",
|
||||
@@ -1504,9 +1496,9 @@ void App::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("requestSingleInstanceLock", &App::RequestSingleInstanceLock)
|
||||
.SetMethod("releaseSingleInstanceLock", &App::ReleaseSingleInstanceLock)
|
||||
.SetMethod("relaunch", &App::Relaunch)
|
||||
.SetMethod("_isAccessibilitySupportEnabled",
|
||||
.SetMethod("isAccessibilitySupportEnabled",
|
||||
&App::IsAccessibilitySupportEnabled)
|
||||
.SetMethod("_setAccessibilitySupportEnabled",
|
||||
.SetMethod("setAccessibilitySupportEnabled",
|
||||
&App::SetAccessibilitySupportEnabled)
|
||||
.SetMethod("disableHardwareAcceleration",
|
||||
&App::DisableHardwareAcceleration)
|
||||
|
||||
@@ -28,7 +28,9 @@ bool RegisteringMediaKeyForUntrustedClient(const ui::Accelerator& accelerator) {
|
||||
if (base::mac::IsAtLeastOS10_14()) {
|
||||
constexpr ui::KeyboardCode mediaKeys[] = {
|
||||
ui::VKEY_MEDIA_PLAY_PAUSE, ui::VKEY_MEDIA_NEXT_TRACK,
|
||||
ui::VKEY_MEDIA_PREV_TRACK, ui::VKEY_MEDIA_STOP};
|
||||
ui::VKEY_MEDIA_PREV_TRACK, ui::VKEY_MEDIA_STOP,
|
||||
ui::VKEY_VOLUME_UP, ui::VKEY_VOLUME_DOWN,
|
||||
ui::VKEY_VOLUME_MUTE};
|
||||
|
||||
if (std::find(std::begin(mediaKeys), std::end(mediaKeys),
|
||||
accelerator.key_code()) != std::end(mediaKeys)) {
|
||||
@@ -59,7 +61,7 @@ GlobalShortcut::~GlobalShortcut() {
|
||||
void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
|
||||
if (accelerator_callback_map_.find(accelerator) ==
|
||||
accelerator_callback_map_.end()) {
|
||||
// This should never occur, because if it does, GlobalGlobalShortcutListener
|
||||
// This should never occur, because if it does, GlobalShortcutListener
|
||||
// notifies us with wrong accelerator.
|
||||
NOTREACHED();
|
||||
return;
|
||||
|
||||
@@ -40,6 +40,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"
|
||||
@@ -548,12 +549,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));
|
||||
}
|
||||
@@ -561,9 +564,16 @@ void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
|
||||
void Session::SetUserAgent(const std::string& user_agent,
|
||||
mate::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() {
|
||||
|
||||
@@ -100,17 +100,12 @@ void SystemPreferences::BuildPrototype(
|
||||
.SetMethod("removeUserDefault", &SystemPreferences::RemoveUserDefault)
|
||||
.SetMethod("isSwipeTrackingFromScrollEventsEnabled",
|
||||
&SystemPreferences::IsSwipeTrackingFromScrollEventsEnabled)
|
||||
.SetMethod("_getEffectiveAppearance",
|
||||
.SetMethod("getEffectiveAppearance",
|
||||
&SystemPreferences::GetEffectiveAppearance)
|
||||
.SetMethod("_getAppLevelAppearance",
|
||||
.SetMethod("getAppLevelAppearance",
|
||||
&SystemPreferences::GetAppLevelAppearance)
|
||||
.SetMethod("_setAppLevelAppearance",
|
||||
.SetMethod("setAppLevelAppearance",
|
||||
&SystemPreferences::SetAppLevelAppearance)
|
||||
.SetProperty("appLevelAppearance",
|
||||
&SystemPreferences::GetAppLevelAppearance,
|
||||
&SystemPreferences::SetAppLevelAppearance)
|
||||
.SetProperty("effectiveAppearance",
|
||||
&SystemPreferences::GetEffectiveAppearance)
|
||||
.SetMethod("getSystemColor", &SystemPreferences::GetSystemColor)
|
||||
.SetMethod("canPromptTouchID", &SystemPreferences::CanPromptTouchID)
|
||||
.SetMethod("promptTouchID", &SystemPreferences::PromptTouchID)
|
||||
|
||||
@@ -683,10 +683,16 @@ void TopLevelWindow::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
|
||||
gin::V8ToString(isolate, object->GetConstructorName()) == "Menu" &&
|
||||
gin::ConvertFromV8(isolate, value, &menu) && !menu.IsEmpty()) {
|
||||
menu_.Reset(isolate, menu.ToV8());
|
||||
window_->SetMenu(menu->model());
|
||||
|
||||
// We only want to update the menu if the menu has a non-zero item count,
|
||||
// or we risk crashes.
|
||||
if (menu->model()->GetItemCount() == 0) {
|
||||
RemoveMenu();
|
||||
} else {
|
||||
window_->SetMenu(menu->model());
|
||||
}
|
||||
} else if (value->IsNull()) {
|
||||
menu_.Reset();
|
||||
window_->SetMenu(nullptr);
|
||||
RemoveMenu();
|
||||
} else {
|
||||
isolate->ThrowException(
|
||||
v8::Exception::TypeError(gin::StringToV8(isolate, "Invalid Menu")));
|
||||
@@ -1124,30 +1130,18 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setSheetOffset", &TopLevelWindow::SetSheetOffset)
|
||||
.SetMethod("moveAbove", &TopLevelWindow::MoveAbove)
|
||||
.SetMethod("moveTop", &TopLevelWindow::MoveTop)
|
||||
.SetMethod("_setResizable", &TopLevelWindow::SetResizable)
|
||||
.SetMethod("_isResizable", &TopLevelWindow::IsResizable)
|
||||
.SetProperty("resizable", &TopLevelWindow::IsResizable,
|
||||
&TopLevelWindow::SetResizable)
|
||||
.SetMethod("_setMovable", &TopLevelWindow::SetMovable)
|
||||
.SetMethod("_isMovable", &TopLevelWindow::IsMovable)
|
||||
.SetProperty("movable", &TopLevelWindow::IsMovable,
|
||||
&TopLevelWindow::SetMovable)
|
||||
.SetMethod("_setMinimizable", &TopLevelWindow::SetMinimizable)
|
||||
.SetMethod("_isMinimizable", &TopLevelWindow::IsMinimizable)
|
||||
.SetProperty("minimizable", &TopLevelWindow::IsMinimizable,
|
||||
&TopLevelWindow::SetMinimizable)
|
||||
.SetMethod("_setMaximizable", &TopLevelWindow::SetMaximizable)
|
||||
.SetMethod("_isMaximizable", &TopLevelWindow::IsMaximizable)
|
||||
.SetProperty("maximizable", &TopLevelWindow::IsMaximizable,
|
||||
&TopLevelWindow::SetMaximizable)
|
||||
.SetMethod("_setFullScreenable", &TopLevelWindow::SetFullScreenable)
|
||||
.SetMethod("_isFullScreenable", &TopLevelWindow::IsFullScreenable)
|
||||
.SetProperty("fullScreenable", &TopLevelWindow::IsFullScreenable,
|
||||
&TopLevelWindow::SetFullScreenable)
|
||||
.SetMethod("_setClosable", &TopLevelWindow::SetClosable)
|
||||
.SetMethod("_isClosable", &TopLevelWindow::IsClosable)
|
||||
.SetProperty("closable", &TopLevelWindow::IsClosable,
|
||||
&TopLevelWindow::SetClosable)
|
||||
.SetMethod("setResizable", &TopLevelWindow::SetResizable)
|
||||
.SetMethod("isResizable", &TopLevelWindow::IsResizable)
|
||||
.SetMethod("setMovable", &TopLevelWindow::SetMovable)
|
||||
.SetMethod("isMovable", &TopLevelWindow::IsMovable)
|
||||
.SetMethod("setMinimizable", &TopLevelWindow::SetMinimizable)
|
||||
.SetMethod("isMinimizable", &TopLevelWindow::IsMinimizable)
|
||||
.SetMethod("setMaximizable", &TopLevelWindow::SetMaximizable)
|
||||
.SetMethod("isMaximizable", &TopLevelWindow::IsMaximizable)
|
||||
.SetMethod("setFullScreenable", &TopLevelWindow::SetFullScreenable)
|
||||
.SetMethod("isFullScreenable", &TopLevelWindow::IsFullScreenable)
|
||||
.SetMethod("setClosable", &TopLevelWindow::SetClosable)
|
||||
.SetMethod("isClosable", &TopLevelWindow::IsClosable)
|
||||
.SetMethod("setAlwaysOnTop", &TopLevelWindow::SetAlwaysOnTop)
|
||||
.SetMethod("isAlwaysOnTop", &TopLevelWindow::IsAlwaysOnTop)
|
||||
.SetMethod("center", &TopLevelWindow::Center)
|
||||
@@ -1220,10 +1214,8 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
&TopLevelWindow::IsExcludedFromShownWindowsMenu,
|
||||
&TopLevelWindow::SetExcludedFromShownWindowsMenu)
|
||||
#endif
|
||||
.SetMethod("_setAutoHideMenuBar", &TopLevelWindow::SetAutoHideMenuBar)
|
||||
.SetMethod("_isMenuBarAutoHide", &TopLevelWindow::IsMenuBarAutoHide)
|
||||
.SetProperty("autoHideMenuBar", &TopLevelWindow::IsMenuBarAutoHide,
|
||||
&TopLevelWindow::SetAutoHideMenuBar)
|
||||
.SetMethod("setAutoHideMenuBar", &TopLevelWindow::SetAutoHideMenuBar)
|
||||
.SetMethod("isMenuBarAutoHide", &TopLevelWindow::IsMenuBarAutoHide)
|
||||
.SetMethod("setMenuBarVisibility", &TopLevelWindow::SetMenuBarVisibility)
|
||||
.SetMethod("isMenuBarVisible", &TopLevelWindow::IsMenuBarVisible)
|
||||
.SetMethod("setAspectRatio", &TopLevelWindow::SetAspectRatio)
|
||||
|
||||
@@ -347,6 +347,7 @@ mate::WrappableBase* SimpleURLLoaderWrapper::New(gin::Arguments* args) {
|
||||
request->attach_same_site_cookies = true;
|
||||
opts.Get("method", &request->method);
|
||||
opts.Get("url", &request->url);
|
||||
opts.Get("referrer", &request->referrer);
|
||||
std::map<std::string, std::string> extra_headers;
|
||||
if (opts.Get("extraHeaders", &extra_headers)) {
|
||||
for (const auto& it : extra_headers) {
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/gfx_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/language_util.h"
|
||||
#include "shell/common/mouse_util.h"
|
||||
#include "shell/common/native_mate_converters/blink_converter.h"
|
||||
#include "shell/common/native_mate_converters/content_converter.h"
|
||||
@@ -520,7 +521,24 @@ void WebContents::InitWithSessionAndOptions(
|
||||
managed_web_contents()->GetView()->SetDelegate(this);
|
||||
|
||||
auto* prefs = web_contents()->GetMutableRendererPrefs();
|
||||
prefs->accept_languages = g_browser_process->GetApplicationLocale();
|
||||
|
||||
// Collect preferred languages from OS and browser process.
|
||||
// accept_languages effects HTTP header, navigator.languages,
|
||||
// and CJK fallback font selection.
|
||||
//
|
||||
// Note that an application locale set to the browser
|
||||
// process might be different with the one set to the preference
|
||||
// list. (e.g. overridden with --lang)
|
||||
std::string accept_languages =
|
||||
g_browser_process->GetApplicationLocale() + ",";
|
||||
for (auto const& language : electron::GetPreferredLanguages()) {
|
||||
if (language == g_browser_process->GetApplicationLocale()) {
|
||||
continue;
|
||||
}
|
||||
accept_languages += language + ",";
|
||||
}
|
||||
accept_languages.pop_back();
|
||||
prefs->accept_languages = accept_languages;
|
||||
|
||||
#if defined(OS_LINUX) || defined(OS_WIN)
|
||||
// Update font settings.
|
||||
@@ -2641,10 +2659,8 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("_goForward", &WebContents::GoForward)
|
||||
.SetMethod("_goToOffset", &WebContents::GoToOffset)
|
||||
.SetMethod("isCrashed", &WebContents::IsCrashed)
|
||||
.SetMethod("_setUserAgent", &WebContents::SetUserAgent)
|
||||
.SetMethod("_getUserAgent", &WebContents::GetUserAgent)
|
||||
.SetProperty("userAgent", &WebContents::GetUserAgent,
|
||||
&WebContents::SetUserAgent)
|
||||
.SetMethod("setUserAgent", &WebContents::SetUserAgent)
|
||||
.SetMethod("getUserAgent", &WebContents::GetUserAgent)
|
||||
.SetMethod("savePage", &WebContents::SavePage)
|
||||
.SetMethod("openDevTools", &WebContents::OpenDevTools)
|
||||
.SetMethod("closeDevTools", &WebContents::CloseDevTools)
|
||||
@@ -2655,10 +2671,8 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("toggleDevTools", &WebContents::ToggleDevTools)
|
||||
.SetMethod("inspectElement", &WebContents::InspectElement)
|
||||
.SetMethod("setIgnoreMenuShortcuts", &WebContents::SetIgnoreMenuShortcuts)
|
||||
.SetMethod("_setAudioMuted", &WebContents::SetAudioMuted)
|
||||
.SetMethod("_isAudioMuted", &WebContents::IsAudioMuted)
|
||||
.SetProperty("audioMuted", &WebContents::IsAudioMuted,
|
||||
&WebContents::SetAudioMuted)
|
||||
.SetMethod("setAudioMuted", &WebContents::SetAudioMuted)
|
||||
.SetMethod("isAudioMuted", &WebContents::IsAudioMuted)
|
||||
.SetMethod("isCurrentlyAudible", &WebContents::IsCurrentlyAudible)
|
||||
.SetMethod("undo", &WebContents::Undo)
|
||||
.SetMethod("redo", &WebContents::Redo)
|
||||
@@ -2689,20 +2703,14 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("startPainting", &WebContents::StartPainting)
|
||||
.SetMethod("stopPainting", &WebContents::StopPainting)
|
||||
.SetMethod("isPainting", &WebContents::IsPainting)
|
||||
.SetMethod("_setFrameRate", &WebContents::SetFrameRate)
|
||||
.SetMethod("_getFrameRate", &WebContents::GetFrameRate)
|
||||
.SetProperty("frameRate", &WebContents::GetFrameRate,
|
||||
&WebContents::SetFrameRate)
|
||||
.SetMethod("setFrameRate", &WebContents::SetFrameRate)
|
||||
.SetMethod("getFrameRate", &WebContents::GetFrameRate)
|
||||
#endif
|
||||
.SetMethod("invalidate", &WebContents::Invalidate)
|
||||
.SetMethod("_setZoomLevel", &WebContents::SetZoomLevel)
|
||||
.SetMethod("_getZoomLevel", &WebContents::GetZoomLevel)
|
||||
.SetProperty("zoomLevel", &WebContents::GetZoomLevel,
|
||||
&WebContents::SetZoomLevel)
|
||||
.SetMethod("_setZoomFactor", &WebContents::SetZoomFactor)
|
||||
.SetMethod("_getZoomFactor", &WebContents::GetZoomFactor)
|
||||
.SetProperty("zoomFactor", &WebContents::GetZoomFactor,
|
||||
&WebContents::SetZoomFactor)
|
||||
.SetMethod("setZoomLevel", &WebContents::SetZoomLevel)
|
||||
.SetMethod("getZoomLevel", &WebContents::GetZoomLevel)
|
||||
.SetMethod("setZoomFactor", &WebContents::SetZoomFactor)
|
||||
.SetMethod("getZoomFactor", &WebContents::GetZoomFactor)
|
||||
.SetMethod("getType", &WebContents::GetType)
|
||||
.SetMethod("_getPreloadPaths", &WebContents::GetPreloadPaths)
|
||||
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
|
||||
|
||||
@@ -54,7 +54,7 @@ class Browser : public WindowListObserver {
|
||||
void Shutdown();
|
||||
|
||||
// Focus the application.
|
||||
void Focus();
|
||||
void Focus(mate::Arguments* args);
|
||||
|
||||
// Returns the version of the executable (or bundle).
|
||||
std::string GetVersion() const;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user