Compare commits

..

89 Commits

Author SHA1 Message Date
Electron Bot
952603d9ae Bump v8.3.2 2020-06-15 09:05:09 -07:00
Jeremy Rose
32b45e7783 fix: throw instead of crash when using ipcRenderer after context released (#23979)
* fix: throw instead of crash when using ipcRenderer after context released (#23917)

* meh

* Update api-ipc-renderer-spec.ts
2020-06-13 08:28:17 -07:00
trop[bot]
514c1e6d4b fix: showing certificate dialog with no window (#24120)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-06-13 08:19:30 -07:00
trop[bot]
67b04b4040 chore: cherry-pick 867fcd45891e from chromium (#24088)
https://chromium-review.googlesource.com/c/chromium/src/+/2134037

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-06-12 12:13:29 -07:00
Samuel Attard
415387cc2c Revert "fix: do not use CONTEXT_MENU flag for tray menu (#23886)" (#24079)
This reverts commit 91d1bd651e.
2020-06-11 11:28:02 -07:00
Electron Bot
0826770b20 Revert "Bump v8.3.2"
This reverts commit c2e22abf08.
2020-06-11 09:42:29 -07:00
Electron Bot
c2e22abf08 Bump v8.3.2 2020-06-11 09:24:35 -07:00
Milan Burda
9c28c8f637 chore: revert deprecated WebContents properties (#24071) 2020-06-11 09:16:33 -07:00
Milan Burda
478d405d42 chore: support props/fns for BrowserWindow (#24074) 2020-06-11 09:14:47 -07:00
Milan Burda
0b616b3e2e chore: more modules to dual prop/fn support (#22734) (#24075)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
2020-06-11 11:06:54 -05:00
Milan Burda
49711d12f8 chore: update app module property support (#22747) (#24072)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-06-11 08:56:28 -07:00
Cheng Zhao
fe56f1dda6 fix: add .paks for media-internals and webrtc-internals pages (#24063)
Co-authored-by: Gellert Hegyi <gellert.hegyi@around.co>
2020-06-11 08:38:49 -07:00
Shelley Vohr
f10c8e6dd5 chore: roll latest Node.js security release (#23953) 2020-06-09 11:55:34 -04:00
Charles Kerr
27c1fc87e3 fix: add missing isComposing KeyboardEvent property (#24015) 2020-06-08 17:45:57 -07:00
Shelley Vohr
be08ff1665 fix: nativeImage remote serialization (#23797)
* fix: nativeImage remote serialization (#23543)

We weren't serializing nativeImages properly in the remote module, leading to gin conversion errors when trying to, for example, create a new context menu in the renderer with icons using nativeImage. This fixes that by adding a new special case to handle them.

* refactor: correctly serialize nativeImage/buffer with typeUtils (#23666)

* refactor: correctly serialize nativeImage/buffer with typeUtils

* test: add serialization specs

* fix: construct from dataURL

* test: test for dataURL specificity

* refactor: use typeutils for nativeImage serialization

* fix: ensure nativeImage serialization main->renderer

* chore: fix FTBFS

Co-authored-by: Charles Kerr <charles@charleskerr.com>
2020-06-08 12:08:54 -07:00
Charles Kerr
547e50c699 docs: errors in isolated world are not dispatched (#24016)
* docs: errors in isolated world are not dispatched

* empty commit

* fix manual oops

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-06-08 14:51:39 -04:00
Shelley Vohr
a06170648c fix: compensate for lazy-loaded circular deps (#23955) 2020-06-08 10:09:40 -07:00
Milan Burda
88fdf8ccf5 fix: use acceptLanguages argument in session.setUserAgent() (#23944) (#23963)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2020-06-08 09:19:32 -07:00
trop[bot]
d12be5d392 feat: add V8CacheOptions webpreference (#23869)
* feat: add V8CacheOptions webpreference

* address review comments

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-06-08 11:07:44 -05:00
Cheng Zhao
e62cd6a5fa fix: read GTK dark theme setting on Linux (#23965) 2020-06-04 19:33:53 -07:00
Shelley Vohr
c412f7ddf1 fix: handle asynchronous URL loading in bw proxy (#23947) 2020-06-03 15:54:43 -07:00
Shelley Vohr
0afec38c81 fix: volume key globalShortcut registration (#23948) 2020-06-03 13:31:18 -07:00
Robo
38f0a8e85b fix: default to NTLM v2 in the network service for POSIX platforms (#23933)
* fix: default to NTLM v2 in the network service for POSIX platforms

* chore: update patch
2020-06-03 11:48:37 -07:00
Shelley Vohr
0aa7b7f712 test: skip 'handles Promise timeouts correctly' when ELECTRON_RUN_AS_NODE is disabled (#23949) 2020-06-03 14:18:07 -04:00
trop[bot]
23bd9166d7 fix: restore original GTK/appindicator implementation of tray icons (#23927)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-06-03 11:08:04 -07:00
Charles Kerr
c374f20fd1 fix: don't run environment bootstrapper (#23924)
* fix: don't prepareMainExecution twice

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-06-03 10:12:29 -05:00
trop[bot]
b5839f42a2 fix: correctly support the --inspect-brk-node flag (#23919)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-06-03 17:01:26 +09:00
trop[bot]
2dcfefa577 build: make electron renderer init scripts profilable (#23914)
The devtools profiler is not attached at the point we run out init scripts (or our apps preload scripts), we do not really want to change when we run these init scripts but for when a dev is doing performance work it makes sense to give them an option to make the devtools profiler actually work on both our init scripts and their preload script.  This PR adds that logic behind an environment variable ELECTRON_PROFILE_INIT_SCRIPTS.

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-06-02 12:28:27 -07:00
trop[bot]
b045ee77af fix: add patch to prevent crash during frame swap with ctx isolation enabled (#23894)
* fix: add patch to prevent crash during frame swap with ctx isolation enabled

* Update .patches

* chore: update patches

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2020-06-02 10:54:35 -07:00
Biru Mohanathas
32c2736c07 fix: Make the --disable-color-correct-rendering switch work again (8-x-y) (#23827)
Backport of #23787

See that PR for details.

Notes: Fix disabling color correct rendering with `--disable-color-correct-rendering`
2020-06-02 13:50:35 -04:00
Charles Kerr
91d1bd651e fix: do not use CONTEXT_MENU flag for tray menu (#23886) 2020-06-02 11:11:35 +09:00
Electron Bot
c8177f8418 Bump v8.3.1 2020-06-01 09:32:39 -07:00
trop[bot]
b8c086613f fix: weakly reference MenuModel from MenuController (#23807)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-28 09:47:47 -07:00
Alexey Kuzmin
2e80a2e447 test: refactor how spec files are collected (#23815)
(cherry picked from commit 3a7775fa73)
2020-05-28 09:41:27 -07:00
Pedro Pontes
936a1659f6 chore: cherry-pick d795ac1209c8 and 919dd0c1244a from chromium (#23788)
* Onstate handler is allowed to close a PeerConnection.

Backports the 2-part fix to https://crbug.com/1068084

===

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}

===

Onstate handler is allowed to close a PeerConnection.

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-Commit-Position: refs/heads/master@{#759242}

===

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-05-28 11:34:49 -04:00
Cheng Zhao
d7289cbb55 Revert "fix: trigger activate event when app is activated via app switcher (#23772)" (#23820)
This reverts commit e671c2c053.
2020-05-28 09:01:37 -04:00
trop[bot]
aab0c66817 fix: pass correct buffer length (#23799)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-05-27 14:09:35 -07:00
trop[bot]
e671c2c053 fix: trigger activate event when app is activated via app switcher (#23772)
When application is activated thru macOS app switcher (cmd+tab) the
App's activate event is note emitted. The reason is that
`applicationShouldHandleReopen:hasVisibleWindows:` is sent only when app
is activated via Dock. Using `applicationDidBecomeActive:` is handling
all cases properly.

Co-authored-by: Lukas Weber <luweber@microsoft.com>
2020-05-27 09:52:20 +09:00
Pedro Pontes
c7778a8f2f chore: cherry-pick d4ddf645c3ca from chromium (#23747)
* chore: cherry-pick d4ddf645c3ca from chromium

* update patches

* [turbofan] 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}

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-05-25 12:02:08 -07:00
trop[bot]
c35803aee1 fix: trigger about panel for about role on on win (#23714)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-21 21:40:09 -04:00
LuoJinghua
9f2fc5d72c net: Don't ignore the referer header in net.request (#23688) 2020-05-21 20:24:28 -04:00
trop[bot]
a65fe57342 fix: make sure hunspell file is not destroyed in UI thread (#23658)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-05-21 15:40:03 -07:00
Alexey Kuzmin
473219bfbe test: call "expect()" on a correct call stack (#23697)
* test: call "expect()" on a correct call stack

(cherry picked from commit 33d6a99d40)

* fixup! test: call "expect()" on a correct call stack
2020-05-21 15:38:42 -07:00
trop[bot]
a8196fbc18 refactor: improve MoveItemToTrash error description (#23629)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-18 11:11:05 -04:00
Alexey Kuzmin
6b8ca86459 test: fix conditions for some tests (#23489) (#23607) 2020-05-18 10:12:38 +09:00
Samuel Attard
7290d77cdc refactor: remove the RenderFrameFunctionStore and use privates to memory manage (#23592) (#23612) 2020-05-15 16:33:48 -07:00
Electron Bot
426d45cd85 Bump v8.3.0 2020-05-14 17:33:43 -07:00
trop[bot]
79298d37cd build: remove unused header from a patch (#23591)
It can cause build failures because the header is generated
and there's no explicit dependency on a target that creates it.

Co-authored-by: Aleksei Kuzmin <alkuzmin@microsoft.com>
2020-05-14 20:32:29 -04:00
Robo
2a44b1a20f feat: add enableWebSQL webpreference (#23311) (#23581) 2020-05-14 20:31:45 -04:00
Charles Kerr
6f331e4f6a feat: add force option to app.focus() (#23574) 2020-05-14 17:30:52 -07:00
Andrey Belenko
dc71541641 chore: cherry-pick 7101418f85a0 from chromium (#23532)
* chore: cherry-pick 7101418f85a0 from chromium

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
Co-authored-by: Andrey Belenko <anbelen@microsoft.com>
2020-05-14 11:21:32 -04:00
Pedro Pontes
a4de4793dd chore: cherry-pick 1288aa12369e from angle (#23561) 2020-05-14 11:08:16 -04:00
trop[bot]
f7509d590c fix: leave behind the unmodified XDG_CURRENT_DESKTOP variable (#23552)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2020-05-14 10:43:51 -04:00
Shelley Vohr
42ab97f905 fix: run Node.js at-exit callbacks in renderer proc (#23564) 2020-05-14 10:08:34 -04:00
Andrey Belenko
faf2871efe chore: cherry-pick 86c02c5dcd37 from chromium (#23528)
Co-authored-by: Andrey Belenko <anbelen@microsoft.com>
2020-05-13 15:59:10 -07:00
Cheng Zhao
ea4e92f64d fix: do not destroy thread in UI thread (#23550) 2020-05-13 10:01:22 -07:00
trop[bot]
15d792aded build: use correct v8_context_snapshot_generator in mksnapshot zip (#23542)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-05-13 09:39:56 -04:00
Cheng Zhao
70f05a1579 chore: cherry-pick e89fe66d0473 from Chromium (#23514) 2020-05-13 17:07:54 +09:00
Cheng Zhao
2d40fad79e chore: cherry-pick 67864c214770 from Chromium (#23517) 2020-05-13 14:43:22 +09:00
Pedro Pontes
edabc96e75 chore: cherry-pick 38990b7d56e6 from chromium (#23504)
* chore: cherry-pick 38990b7d56e6 from chromium

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-05-13 09:07:40 +09:00
Jeremy Apthorp
4a45196ff1 chore: cherry-pick 45b8c2bb07d2 from v8 (#23465) 2020-05-08 11:42:27 -07:00
Jeremy Apthorp
0bd661bd99 chore: cherry-pick 826a4af58b3d from chromium (#23462) 2020-05-08 11:24:41 -07:00
Jeremy Apthorp
b9e709039e chore: cherry-pick 686d1bfbcb8f from chromium (#23456) 2020-05-08 11:16:26 -07:00
trop[bot]
c63430c5d0 fix: multiple extension filters on macOS (#23449)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-07 11:57:40 -07:00
Charles Kerr
60bcf42edf fix: respect system language preferences on Windows & macOS (#23407)
* fix: respect system language preferences on Win/macOS (#23247)

This commit fixes https://github.com/electron/electron/issues/18829

Previously the full preferences set to OS was not given to Chromium.

Also, this commit improves fallback font selection for CJK text.
Chromium uses browser languages to determine fallback fonts on Windows,
especially kanji/han characters in CJK.

For instance, when user sets 'en-US, ja-JP' to Accept-Language,
while Chromium chooses Japanese font for kanji text, but Electron
chooses Chinese font.  This is because only the first language was given
to Accept-Language on Electron.

This patch is based on https://github.com/electron/electron/pull/15532

Co-authored-by: Nitish Sakhawalkar <nitsakh@icloud.com>
Co-authored-by: Kasumi Hanazuki <kasumi@rollingapple.net>

Co-authored-by: Nitish Sakhawalkar <nitsakh@icloud.com>
Co-authored-by: Kasumi Hanazuki <kasumi@rollingapple.net>

* fix: remove unintentionally-committed code

Some excess code was accidentally included in the last commit's cherry-pick.

* chore: fix extraneous #include found by lint

* fix: correct another manual backport error :P

Co-authored-by: Sorah Fukumori <her@sorah.jp>
Co-authored-by: Nitish Sakhawalkar <nitsakh@icloud.com>
Co-authored-by: Kasumi Hanazuki <kasumi@rollingapple.net>
2020-05-05 09:35:51 -07:00
Shelley Vohr
d5f9654c12 refactor: make passing empty template no-op in setMenu (#23402) 2020-05-04 20:03:36 -07:00
trop[bot]
d2fb214a54 docs: event.newGuest for new-window in WebContents and webContents in BrowsweWindow's constructor (#23355)
* docs: `newGuest` in `WebContents` and `webContents` in `BrowsweWindow`

According to the example codes in the documentation of `new-window`
event in `WebContents`, `webContents` in `BrowsweWindow` constructor
options and `newGuest` in `event` argument of `new-window` handler are
both existing but documented. This patch is for adding the related
documentations. Also, it provides typescript-definitations for these
two properties.

* Remove the documnent of `webContents` in BrowserWindow constructor option.

Co-authored-by: Sean Lee <sean.l@canva.com>
2020-05-04 12:41:37 -07:00
Robo
6294f811a7 fix: hold browser_context instead of render_frame_host to fix lifetime issues (#23271) (#23396)
Co-authored-by: Paul Frazee <pfrazee@gmail.com>
2020-05-04 10:16:56 -07:00
Robo
30ae6f45a4 fix: ensure guest-embedder map is updated when webview is removed (#23342) (#23397)
There are use cases of webview where the container holding the webview is not
actually destroyed first, instead just webview gets removed from DOM, in such
situations the browser process map is not updated accordingly and holds reference
to stale guest contents, and any window operations like scroll, resize or keyboard
events that has to chain through browser embedder will lead to UAF crash.

Ref: https://github.com/microsoft/vscode/issues/92420
2020-05-04 08:30:28 -07:00
trop[bot]
60ef8ac58d ci: make sure msedge isn't running at end of woa test (#23358)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-04-30 15:12:53 -04:00
Electron Bot
6c42564337 Bump v8.2.5 2020-04-30 10:03:43 -07:00
Samuel Attard
479fc57cef fix: do not leak IPC or context bridge promises (#23321) (#23339) 2020-04-30 09:51:51 -07:00
Samuel Attard
b2fb14fd48 fix: backport fix for zero-size pixels in blink (#23336) 2020-04-30 08:26:48 -07:00
Electron Bot
d8f90444aa Bump v8.2.4 2020-04-27 18:07:21 -07:00
Samuel Attard
045331666c refactor: port window-setup to use ctx bridge instead of being run in the main world (#23302)
* refactor: port parts of window-setup to use ctx bridge instead of being run in the main world (#23194)

* refactor: port parts of window-setup to use ctx bridge instead of being run in the main world

* chore: update ctx bridge specs for new base numbers

* refactor: port window.open and window.opener to use ctx bridge instead of hole punching (#23235)

* refactor: port window.open and window.opener to use ctx bridge instead of hole punching

* refactor: only run the isolated init bundle when webview is enabled

* s/gin/mate

* fix: do not inject in content scripts and do not override window.history because it does not work
2020-04-27 18:05:15 -07:00
Samuel Attard
0ac42125d2 style: use build/include_directory for NOLINT (#23266) (#23303)
build/include linter was splitted to build/include_directory at
depot_tools upstream.

https://crrev.com/c/2159690
https://crbug.com/1073191

Co-authored-by: Sorah Fukumori <sora134@gmail.com>
2020-04-27 14:35:34 -07:00
Charles Kerr
ce04014739 fix: use Node's microtasks policy in node_main.cc (#23234) 2020-04-23 11:00:33 -07:00
trop[bot]
19bd97d80c ci: robustify doc only change check (#23258) 2020-04-23 10:55:36 -07:00
Electron Bot
ea2e34c4c3 chore: bump chromium to 80.0.3987.165 (8-x-y) (#23217)
* chore: bump chromium in DEPS to 80.0.3987.165

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-04-23 10:50:40 -07:00
Samuel Attard
5f6498d13a fix: do not mutate ipc instances across contexts (#23240) 2020-04-22 17:36:45 -07:00
Jeremy Apthorp
e3c1292548 fix: block custom window.open when nativeWindowOpen is true (#23188) (#23225) 2020-04-22 17:05:42 -07:00
Samuel Attard
b3e53839a4 fix: do not allow child windows to specify their own preload script (#23230) 2020-04-22 16:02:31 -07:00
Samuel Attard
f3e9f10cad fix: ensure that functions are not retained beyond their context being released (#23207) (#23231) 2020-04-22 15:54:19 -07:00
shelley vohr
2c8927a9a2 test: fix type errors in devToolsWebContents (#23206) 2020-04-22 09:23:21 -07:00
trop[bot]
c6786aed26 build: improve patch filename remembering (#23093)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-04-21 14:06:29 -07:00
Jeremy Apthorp
5b3b09fb7f fix: heap-use-after-free in tray.popUpContextMenu (#22842) (#23181) 2020-04-21 13:27:06 -07:00
Samuel Attard
9f5924c5ea fix: backport V8 promise context fix (#23177) 2020-04-20 18:01:16 -07:00
Shelley Vohr
25f5d764ac fix: wasm codegen in script.runInNewContext (#23147) 2020-04-20 15:29:13 -04:00
trop[bot]
941c72fcfe docs: fix devToolsWebContents union type (#23172)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-04-20 11:35:54 -07:00
188 changed files with 17106 additions and 1427 deletions

View File

@@ -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

View File

@@ -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
View File

@@ -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':

View File

@@ -1 +1 @@
8.2.3
8.3.2

View File

@@ -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()

View File

@@ -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)
}
})

View File

@@ -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'),

View File

@@ -1,5 +1,6 @@
module.exports = require('./webpack.config.base')({
target: 'renderer',
alwaysHasNode: true,
targetDeletesNodeGlobals: true
targetDeletesNodeGlobals: true,
wrapInitWithProfilingTimeout: true
})

View File

@@ -1,4 +1,5 @@
module.exports = require('./webpack.config.base')({
target: 'sandboxed_renderer',
alwaysHasNode: false
alwaysHasNode: false,
wrapInitWithProfilingTimeout: true,
})

View File

@@ -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",

View File

@@ -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)`.

View File

@@ -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()`

View File

@@ -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.

View File

@@ -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

View File

@@ -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.

View File

@@ -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.

View File

@@ -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`

View File

@@ -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.

View File

@@ -0,0 +1,4 @@
# NewWindowEvent Object extends `Event`
* `newGuest` BrowserWindow (optional)

View File

@@ -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.

View File

@@ -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.

View File

@@ -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

View File

@@ -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",

View File

@@ -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",

View File

@@ -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",

View File

@@ -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);

View File

@@ -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;

View File

@@ -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');
}

View File

@@ -10,7 +10,8 @@ const roles = {
about: {
get label () {
return isLinux ? 'About' : `About ${app.name}`;
}
},
...(isWindows && { appMethod: 'showAboutPanel' })
},
close: {
label: isMac ? 'Close Window' : 'Close',

View File

@@ -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) => {

View File

@@ -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(

View File

@@ -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');

View File

@@ -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);

View File

@@ -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

View File

@@ -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';
}

View File

@@ -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':

View File

@@ -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;

View File

@@ -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)) {

View File

@@ -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);
}

View File

@@ -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
};

View File

@@ -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;

View File

@@ -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),

View File

@@ -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;
};
}

View File

@@ -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
};

View File

@@ -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();

View File

@@ -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);
}
};

View File

@@ -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;

View File

@@ -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
View File

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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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*

View 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 =

View 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

View 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(

View 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>
+

View 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;
}

View 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);

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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.

View 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.

View File

@@ -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)

View File

@@ -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

View 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>

View File

@@ -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)

View File

@@ -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"
}

View File

@@ -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

View File

@@ -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",

View File

@@ -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:

View File

@@ -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", &parameters, &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);

File diff suppressed because it is too large Load Diff

View 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;

View File

@@ -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) {
}
}

View 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", &parameters, &arguments)
- .IsEmpty()) {
- return nullptr;
- }
return env;
}

View File

@@ -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));
}
{

View 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(

View 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
View File

@@ -0,0 +1 @@
cherry-pick-e89fe66d0473.patch

View 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 */

View File

@@ -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

View 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) {

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -39,7 +39,7 @@ async function checkIfDocOnlyChange () {
return true;
}
});
if (nonDocChange) {
if (nonDocChange || filesChanged.data.length === 0) {
process.exit(1);
} else {
process.exit(0);

View File

@@ -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)

View File

@@ -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",

View File

@@ -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"

View File

@@ -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

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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;

View File

@@ -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() {

View File

@@ -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)

View File

@@ -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)

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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