Compare commits

..

101 Commits

Author SHA1 Message Date
Electron Bot
d6d9d954b4 Bump v10.3.0 2021-01-14 08:50:03 -08:00
Erick Zhao
2ee375c5bf docs: update devtools extension tutorial (#26326) (#27312)
* docs: update devtools extension tutorial

* Update docs/tutorial/devtools-extension.md

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>

* update

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-01-14 14:55:12 +09:00
trop[bot]
c04ec2d332 build: fix installing of code-signing identity on macOS (#27293)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-01-13 13:46:13 -08:00
Keeley Hammond
4f9122647a ci: fix broken homebrew cache (#27308)
Backport of #27224
2021-01-13 11:11:30 -08:00
trop[bot]
846504af8e test: disable flaky reporting API test (#27272)
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-01-12 10:12:17 +09:00
Shelley Vohr
5d97320ba3 Revert "Bump v10.2.1"
This reverts commit 2aaa5438cd.
2021-01-11 14:27:47 -08:00
Electron Bot
2aaa5438cd Bump v10.2.1 2021-01-11 09:33:58 -08:00
Shelley Vohr
08da5ee22a fix: handle BrowserView reparenting (#27220) 2021-01-11 10:49:56 +09:00
trop[bot]
f3a4b44662 test: skip PictureInPicture video when media not supported (#27234)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-01-07 21:39:04 -08:00
trop[bot]
424177164e test: skip media-started-playing media-paused events test when media not supported (#27238)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-01-07 18:46:19 -08:00
Shelley Vohr
079251f168 fix: draggable views on BrowserViews on Windows (#27222) 2021-01-07 13:11:07 -08:00
trop[bot]
17054405d8 docs: document frameId meaning (#27190)
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-01-05 17:19:40 +09:00
trop[bot]
d1d8c9badd fix: default offset when no drag regions (#27185)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-01-05 12:14:15 +09:00
Eryk Rakowski
700c410ec3 fix(extensions): implement missing web_request hooks (#27097)
* fix(extensions): implement missing web_request hooks (#22655)

Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
Co-authored-by: samuelmaddock <samuel.maddock@gmail.com>

* fix: remove ukm_source_id

Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
Co-authored-by: samuelmaddock <samuel.maddock@gmail.com>
2021-01-05 11:40:36 +09:00
Eryk Rakowski
d3f7ad2035 feat: add support for webContents option in BrowserView (#27094)
* feat: add support for webContents option in BrowserView (#26802)

* feat: add support for webContents option in BrowserView

* tests: add tests

* fix: missing webContents import

* fix: WebContents::New -> Create
2021-01-05 11:22:56 +09:00
Erick Zhao
f5deaedfaa docs: update OSR max FPS number (#27060) 2020-12-17 20:30:53 +09:00
trop[bot]
2717a48f30 fix: memory leak in desktopCapturer.getSources (#27057)
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2020-12-16 20:47:47 -08:00
Jeremy Rose
fea41c6f6d fix: throw when using globalShortcut before ready (#27023)
* fix: throw when using globalShortcut before ready (#27002)

* add missing include
2020-12-17 10:07:44 +09:00
Michaela Laurencin
d58bfdcdfd chore: cherry-pick 2d18de63acf1 from chromium (#26953)
* chore: cherry-pick 2d18de63acf1 from chromium

* resolve conflict

* modified patches from CRLF to LF

* Update cherry-pick-2d18de63acf1.patch

Remove test from patch
2020-12-15 16:36:13 -05:00
trop[bot]
d0451832ed fix: add SafeForTerminationScopes for SIGINT interruptions (#26970)
* fix: add SafeForTerminationScopes for SIGINT interruptions

* update patches

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-12-14 11:02:48 -08:00
trop[bot]
22481aa347 ci: ignore failures on Ninja summary (#26993)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2020-12-14 13:43:52 -05:00
Jeremy Rose
7b0bb0b637 fix: cherry-pick b84b4f3323b from chromium (#26963) 2020-12-14 13:01:43 -05:00
Michaela Laurencin
36f8e9daa2 chore: cherry-pick 6763a713f957 from skia (#26956) 2020-12-11 15:05:16 -08:00
Electron Bot
4594af595e Bump v10.2.0 2020-12-11 13:03:39 -08:00
Jeremy Rose
0bbd268eb4 fix: restrict sendToFrame to same-process frames by default (#26875) (#26927)
* fix: restrict sendToFrame to same-process frames by default (#26875)

* missed a conflict

* fix build

* fix build again

* fix usage of defer
2020-12-11 13:01:40 -08:00
trop[bot]
47b9207e6d fix: Upload all *.dll.pdb to symbol server (#26964)
Fixes #26961.

Notes: Add Electron DLLs like libGLESv2.dll to symbol server

Co-authored-by: Biru Mohanathas <birunthan@mohanathas.com>
2020-12-11 12:53:16 -08:00
trop[bot]
846412cdf1 fix: Avoid crashing in NativeViewHost::SetParentAccessible on Windows 10 (#26949)
* fix: Avoid crashing in NativeViewHost::SetParentAccessible on Windows

This fixes #26905. The patch was obtained from @deepak1556, who in turn
got it from the Microsoft Teams folks.

I believe the crash started happening due to the changes in
5c6c8e994b%5E!/#F15

This affects Electron 9 and later.

Notes: Fix occasional crash on Windows

* Update .patches

* update patches

Co-authored-by: Biru Mohanathas <birunthan@mohanathas.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
Co-authored-by: Electron Bot <electron@github.com>
2020-12-11 12:12:08 -08:00
Jeremy Rose
b77e48a2c7 chore: cherry-pick 3abc372c9c00 from chromium (#26894)
* chore: cherry-pick 3abc372c9c00 from chromium

* resolve conflict
2020-12-11 11:03:59 -08:00
trop[bot]
87d98480fa docs: add missing deprecated systemPreferences APIs to breaking-changes (#26934)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-12-11 10:59:09 -08:00
Jeremy Rose
6d468cd9b5 chore: cherry-pick 290fe9c6e245 from v8 (#26896) 2020-12-10 15:28:32 -08:00
Jeremy Rose
38e585434f chore: cherry-pick d8d64b7cd244 from chromium (#26892) 2020-12-10 15:25:17 -08:00
trop[bot]
5481d27bcd fix: message box missing an "OK" button in GTK (#26915)
Co-authored-by: Mimi <1119186082@qq.com>
2020-12-10 13:05:18 -08:00
Pedro Pontes
135133e391 chore: cherry-pick 381c4b5679 from chromium. (#26832) 2020-12-10 11:23:38 -05:00
Pedro Pontes
ad8de076e3 chore: cherry-pick ecdec1fb0f42 from chromium (#26866)
* chore: cherry-pick ecdec1fb0f42 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2020-12-09 15:01:37 -08:00
Pedro Pontes
5bad2d106c chore: cherry-pick 8c346e3cd9 from chromium. (#26830)
* chore: cherry-pick 8c346e3cd9 from chromium.

* update patches

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Electron Bot <electron@github.com>
2020-12-09 09:23:32 -08:00
Milan Burda
883b089e0f fix: systemPreferences.effectiveAppearance returning systemPreferences.getAppLevelAppearance() (#26852) (#26882) 2020-12-09 14:59:01 +09:00
Pedro Pontes
d0abffc1e7 chore: cherry-pick 5ffbb7ed173a from chromium (#26855)
* chore: cherry-pick 5ffbb7ed173a from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2020-12-08 20:38:02 -08:00
Electron Bot
e24e77f4a2 Bump v10.1.7 2020-12-07 14:30:27 -08:00
trop[bot]
9562a92c5d fix: handle security warnings promise when JS is disabled (#26871)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-12-07 13:03:37 -08:00
Pedro Pontes
4efe747847 chore: cherry-pick bbc6ab5bb49c from chromium (#26860)
* chore: cherry-pick bbc6ab5bb49c from chromium

* update patches

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2020-12-07 13:52:58 -05:00
Pedro Pontes
47f015f1e8 chore: cherry-pick eec5025668f8 from chromium (#26858)
* chore: cherry-pick eec5025668f8 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2020-12-07 10:56:35 -05:00
trop[bot]
5604037294 build: use all-for-one goma (#26699) (#26799)
* Revert "Revert "build: use one-for-all goma (#26679)" (#26689)"

This reverts commit 38ab829ea6.

* build: ensure file descriptor limit is higher on macOS

Co-authored-by: Samuel Attard <sam@electronjs.org>
2020-12-03 11:45:21 -08:00
trop[bot]
f6a3ba5d67 docs: BrowserWindow extension APIs are deprecated in Electron 9 (#26781)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-12-01 21:32:50 -08:00
trop[bot]
34fe161bdd fix: add check in IsMaximized for non-WS_THICKFRAME windows (#26779)
Co-authored-by: mlaurencin <mlaurencin@electronjs.org>
2020-12-01 21:30:40 -08:00
Shelley Vohr
e1bf7b9d8b fix: webContents interaction with draggable BrowserViews (#26744) 2020-12-01 16:03:33 -08:00
Shelley Vohr
5de766deb5 fix: renderer crash on setImmediate (#26747) 2020-12-01 15:42:17 -06:00
trop[bot]
70e41bcf43 fix: draggable regions calculation in BrowserWindow/BrowserView (#26753) 2020-12-01 11:30:08 -08:00
Milan Burda
f7a61c4592 fix: <webview> render-process-gone event dispatch (#26577)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2020-11-18 17:56:44 -06:00
trop[bot]
b19c549511 revert: disable rosetta as Electron does not run under rosetta
This reverts commit 4829b0f816.

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-11-18 11:18:55 -08:00
Electron Bot
de14497f1c Bump v10.1.6 2020-11-18 05:17:23 -08:00
trop[bot]
570f9827ce fix: LC_ALL env should not be changed (#26550)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-11-18 08:14:49 -05:00
Shelley Vohr
9900e697b5 fix: transparently package bundles as zip archives (#26555) 2020-11-18 08:13:57 -05:00
trop[bot]
c6979ca421 test: support for adding extra module paths (#26544)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2020-11-17 19:42:43 -08:00
Pedro Pontes
ace3f9d3e1 chore: cherry-pick c244270e23 from chromium. (#26473)
* chore: cherry-pick 244270e23 from chromium.

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2020-11-16 16:15:31 -05:00
trop[bot]
7bd2f0db23 fix: make draggable regions work when devtools is opened on macOS (#26394)
* fix: make draggable region work when devtools is open

* fix: update draggable regions when resizing

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-11-16 15:38:25 +09:00
Milan Burda
83db340eb3 fix: ensure that internal messages are sent from the main process (#26439) 2020-11-16 15:32:00 +09:00
Pedro Pontes
17d08c1557 chore: cherry-pick 633f67caa6d0 from v8 (#26455)
* chore: cherry-pick 633f67caa6d0 from v8

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2020-11-12 09:14:51 -05:00
trop[bot]
66e548333f build: fix usage of octokit/rest and make uploading better (#26388)
* build: fix usage of octokit/rest and make uploading better

* Update with change from #26414

* Update with changes from #26425

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2020-11-11 14:32:29 -05:00
trop[bot]
7558b5878b chore: synchronously destroy WebContents on event prevented (#26417)
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2020-11-11 10:07:02 -05:00
Jeremy Rose
3ad830c804 chore: cherry-pick bbb64b5c6916 from chromium (#26438)
* chore: cherry-pick bbb64b5c6916 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2020-11-11 09:27:22 -05:00
Jeremy Rose
2460b02e48 chore: cherry-pick 815b12dfb5ec from v8 (#26411) 2020-11-10 14:47:49 -08:00
Jeremy Rose
9012c3bb8b chore: cherry-pick 8c725f7b5bbf from v8 (#26408) 2020-11-10 14:23:01 -08:00
Jeremy Rose
90d72684fc chore: cherry-pick 2882e1afd982 from angle (#26405) 2020-11-10 13:50:27 -08:00
Jeremy Rose
529fbf53e1 chore: cherry-pick 146bd99e762b from v8 (#26399) 2020-11-10 13:50:10 -08:00
Jeremy Rose
4ef5c2666e chore: cherry-pick 8f24f935c903 from chromium (#26396) 2020-11-10 13:49:59 -08:00
Samuel Attard
4aa4d1914b build: auto-push patch file changes (#26235) (#26433)
* build: auto-push patch file changes

* chore: change patch for testing purposes

* build: remove stray log

* build: push as electron bot

* build: suppress all output of the push-patch script

* chore: fix linting
2020-11-10 13:47:56 -08:00
trop[bot]
16681be8fd chore: cleanup inline HTML in docs (#26391)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2020-11-10 10:48:22 -05:00
trop[bot]
0aef4d6a8d fix: Initialize logging for crashpad (#26266)
* fix: Initialize logging for crashpad

* chore: update mini_chromium

* conditionally access CommandLine because crashpad doesn't initialize one.

https://chromium-review.googlesource.com/c/chromium/src/+/2490880

* chore: update patches

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-11-10 10:44:50 -05:00
trop[bot]
ae3c79d6ce refactor: store <webview> attributes as typed Map (#26329)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-11-05 11:25:53 -05:00
trop[bot]
fee2655061 fix: window.open not accepting size values with "px" at the end (#26333)
* fix: use parseInt to parse sizes

* fix: pass radix to parseInt

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

Co-authored-by: Abhishek Shingane <abhisheks@iitbhilai.ac.in>
Co-authored-by: Cheng Zhao <github@zcbenz.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-11-04 10:59:54 -08:00
Shelley Vohr
a3c1866581 fix: draggable region edge calculation on resize (#26321) 2020-11-03 15:01:55 -08:00
Shelley Vohr
38f0916eea build: only check patch diffs in testing builds (#26284)
* build: only check patch diffs in testing builds

* Fixup patch indices
2020-11-02 18:56:35 +09:00
Shelley Vohr
6543acce1d fix: draggable regions exclusively on BrowserViews (#26260) 2020-11-02 16:07:45 +09:00
trop[bot]
15db70d661 chore: change some for loops to range-based (#26262)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2020-10-30 09:58:43 -07:00
trop[bot]
1b32fd2a9b fix: hover text only working when VO enabled (#26245)
* fix: hover text only working when VO enabled

* chore: simplify conditional

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-10-29 08:51:31 -07:00
David Sanders
6147bd77ac chore: use auto to avoid repeating type (#26255) 2020-10-29 08:50:29 -07:00
Charles Kerr
ffd1e9bad2 fix: nativeTheme.themeSource = 'dark' on windows (#26237)
Manually backports #25373.
2020-10-29 10:03:15 -04:00
Cheng Zhao
682b382aa3 fix: set app locale after user's script is loaded (#26241) 2020-10-28 21:42:28 -07:00
Jeremy Rose
3ad59397ae chore: cherry-pick f440137cd96a from chromium (#26209) 2020-10-28 15:42:57 -07:00
Jeremy Rose
6502e4e9cb chore: cherry-pick 229fdaf8fc05 from chromium (#26193) 2020-10-28 15:42:13 -07:00
Jeremy Rose
d5119c499c chore: cherry-pick 1ed869ad4bb3 from chromium (#26190) 2020-10-28 14:40:30 -07:00
Jeremy Rose
0fa84aef3b chore: cherry-pick 6a4cd97d6691 from v8 (#26206) 2020-10-28 14:39:40 -07:00
Jeremy Rose
fe28c5ba06 chore: cherry-pick 30261f9de11e from chromium (#26203) 2020-10-28 14:01:24 -07:00
Jeremy Rose
9242fff9c2 chore: cherry-pick 9591642a0896 from pdfium (#26212) 2020-10-28 13:59:02 -07:00
Jeremy Rose
a538755595 chore: cherry-pick 6aa1e71fbd09 from v8 (#26199) 2020-10-28 13:58:49 -07:00
Jeremy Rose
139cb2dea5 chore: cherry-pick 88f263f401b4 from chromium (#26196)
* chore: cherry-pick 88f263f401b4 from chromium

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-10-28 16:00:17 -04:00
Charles Kerr
831e84504d perf: improve heap snapshot performance (#26229)
Fixes #24509.

cherry-pick 2e2dc98 from v8
2020-10-28 12:07:52 -07:00
trop[bot]
ccbf615da0 fix: delay emitting powerMonitor events on windows (#26180)
* fix: delay emitting powerMonitor events

* Update electron_api_power_monitor_win.cc

* Update electron_api_power_monitor_win.cc

* syntax

* Update electron_api_power_monitor_win.cc

* Update electron_api_power_monitor_win.cc

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2020-10-28 12:38:31 -05:00
trop[bot]
d8fd2dca6d docs: fix app 'ready' event arguments (#26173)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-10-26 20:37:50 -07:00
trop[bot]
86d6aa75ad chore: tweak branch detection in release notes. (#26107)
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2020-10-27 10:30:18 +09:00
David Sanders
99df3b8147 chore: bump @electron/docs-parser version (#26156) 2020-10-26 11:48:32 -07:00
David Sanders
776f76c6f5 chore: prefer empty() check for readability (#26159) 2020-10-26 11:48:03 -07:00
Electron Bot
1df0ea58d5 Bump v10.1.5 2020-10-23 10:20:28 -07:00
trop[bot]
e50545db30 fix: setSimpleFullScreen shows traffic light in frameless window (#26126)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-10-23 09:17:24 -07:00
trop[bot]
4a312e9c6b fix: return early on promise rejection (#26110)
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2020-10-22 14:45:09 -05:00
trop[bot]
0992fb35ea docs: add discord link to docs community page (#26106)
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2020-10-22 14:42:48 -05:00
trop[bot]
904404d3c4 fix: release NSAlert properly (#26097)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-10-22 08:04:20 -07:00
Andrey Belenko
fa491d7e4b chore: cherry-pick b977dff8 from freetype (#26070)
Co-authored-by: Andrey Belenko <anbelen@microsoft.com>
2020-10-20 18:57:39 -07:00
Shelley Vohr
8a052c5537 fix: wasm code generation in the renderer (#26063) 2020-10-20 18:34:33 -07:00
Shelley Vohr
b3d89bd3bf fix: crash in printing on Windows (#26064) 2020-10-20 15:13:37 -05:00
trop[bot]
28f4c546ca perf: remove GC timer that fired once per minute. (#26052)
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2020-10-19 21:43:32 -07:00
196 changed files with 6789 additions and 827 deletions

View File

@@ -94,6 +94,7 @@ env-release-build: &env-release-build
STRIP_BINARIES: true
GENERATE_SYMBOLS: true
CHECK_DIST_MANIFEST: '1'
IS_RELEASE: true
env-headless-testing: &env-headless-testing
DISPLAY: ':99.0'
@@ -232,23 +233,34 @@ step-gclient-sync: &step-gclient-sync
"$CIRCLE_REPOSITORY_URL"
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags
# Re-export all the patches to check if there were changes.
python src/electron/script/export_all_patches.py src/electron/patches/config.json
cd src/electron
git update-index --refresh || true
if ! git diff-index --quiet HEAD --; then
# There are changes to the patches. Make a git commit with the updated patches
git add patches
GIT_COMMITTER_NAME="Electron Bot" GIT_COMMITTER_EMAIL="anonymous@electronjs.org" git commit -m "update patches" --author="Electron Bot <anonymous@electronjs.org>"
# Export it
mkdir -p ../../patches
git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
echo
echo "======================================================================"
echo "There were changes to the patches when applying."
echo "Check the CI artifacts for a patch you can apply to fix it."
echo "======================================================================"
exit 1
if [ "$IS_RELEASE" != "true" ]; then
# Re-export all the patches to check if there were changes.
python src/electron/script/export_all_patches.py src/electron/patches/config.json
cd src/electron
git update-index --refresh || true
if ! git diff-index --quiet HEAD --; then
# There are changes to the patches. Make a git commit with the updated patches
git add patches
GIT_COMMITTER_NAME="Electron Bot" GIT_COMMITTER_EMAIL="electron@github.com" git commit -m "update patches" --author="Electron Bot <electron@github.com>"
# Export it
mkdir -p ../../patches
git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
if (node ./script/push-patch.js 2> /dev/null > /dev/null); then
echo
echo "======================================================================"
echo "Changes to the patches when applying, we have auto-pushed the diff to the current branch"
echo "A new CI job will kick off shortly"
echo "======================================================================"
exit 1
else
echo
echo "======================================================================"
echo "There were changes to the patches when applying."
echo "Check the CI artifacts for a patch you can apply to fix it."
echo "======================================================================"
exit 1
fi
fi
fi
fi
@@ -275,10 +287,10 @@ step-setup-goma-for-build: &step-setup-goma-for-build
name: Setup Goma
command: |
echo 'export USE_GOMA=true' >> $BASH_ENV
if [ "`uname`" == "Linux" ]; then
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
else
echo 'export NUMBER_OF_NINJA_PROCESSES=25' >> $BASH_ENV
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
if [ "`uname`" == "Darwin" ]; then
echo 'ulimit -n 10000' >> $BASH_ENV
echo 'sudo launchctl limit maxfiles 65536 200000' >> $BASH_ENV
fi
if [ ! -z "$RAW_GOMA_AUTH" ]; then
echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
@@ -287,7 +299,7 @@ step-setup-goma-for-build: &step-setup-goma-for-build
cd build-tools
npm install
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
node -e "require('./src/utils/goma.js').ensure()"
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
@@ -296,15 +308,17 @@ step-setup-goma-for-build: &step-setup-goma-for-build
step-restore-brew-cache: &step-restore-brew-cache
restore_cache:
paths:
- /usr/local/Homebrew
- /usr/local/Cellar/gnu-tar
- /usr/local/bin/gtar
keys:
- v1-brew-cache-{{ arch }}
- v4-brew-cache-{{ arch }}
step-save-brew-cache: &step-save-brew-cache
save_cache:
paths:
- /usr/local/Homebrew
key: v1-brew-cache-{{ arch }}
- /usr/local/Cellar/gnu-tar
- /usr/local/bin/gtar
key: v4-brew-cache-{{ arch }}
name: Persisting brew cache
step-get-more-space-on-mac: &step-get-more-space-on-mac
@@ -380,8 +394,10 @@ step-install-gnutar-on-mac: &step-install-gnutar-on-mac
name: Install gnu-tar on macos
command: |
if [ "`uname`" == "Darwin" ]; then
brew update
brew install gnu-tar
if [ ! -d /usr/local/Cellar/gnu-tar/ ]; then
brew update
brew install gnu-tar
fi
ln -fs /usr/local/bin/gtar /usr/local/bin/tar
fi
@@ -550,10 +566,10 @@ step-electron-publish: &step-electron-publish
cd src/electron
if [ "$UPLOAD_TO_S3" == "1" ]; then
echo 'Uploading Electron release distribution to S3'
script/release/uploaders/upload.py --upload_to_s3
script/release/uploaders/upload.py --verbose --upload_to_s3
else
echo 'Uploading Electron release distribution to Github releases'
script/release/uploaders/upload.py
script/release/uploaders/upload.py --verbose
fi
step-persist-data-for-tests: &step-persist-data-for-tests
@@ -789,6 +805,8 @@ step-ninja-summary: &step-ninja-summary
run:
name: Print ninja summary
command: |
set +e
set +o pipefail
python depot_tools/post_build_ninja_summary.py -C src/out/Default
step-ninja-report: &step-ninja-report
@@ -993,7 +1011,6 @@ steps-checkout-and-save-cache: &steps-checkout-and-save-cache
- *step-maybe-early-exit-doc-only-change
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-restore-brew-cache
- *step-get-more-space-on-mac
- *step-install-gnutar-on-mac

View File

@@ -370,6 +370,7 @@ source_set("electron_lib") {
"//third_party/libyuv",
"//third_party/webrtc_overrides:webrtc_component",
"//third_party/widevine/cdm:headers",
"//third_party/zlib/google:zip",
"//ui/base/idle",
"//ui/events:dom_keycode_converter",
"//ui/gl",
@@ -675,6 +676,14 @@ source_set("electron_lib") {
"shell/browser/electron_pdf_web_contents_helper_client.h",
]
}
if (is_win && enable_win_dark_mode_window_ui) {
sources += [
"shell/browser/win/dark_mode.cc",
"shell/browser/win/dark_mode.h",
]
libs += [ "uxtheme.lib" ]
}
}
electron_paks("packed_resources") {

View File

@@ -1 +1 @@
10.1.4
10.3.0

View File

@@ -135,7 +135,7 @@ build_script:
cd build-tools
npm install
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
$env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
$env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
cd ..
@@ -220,10 +220,10 @@ deploy_script:
if (Test-Path Env:\ELECTRON_RELEASE) {
if (Test-Path Env:\UPLOAD_TO_S3) {
Write-Output "Uploading Electron release distribution to s3"
& python script\release\uploaders\upload.py --upload_to_s3
& python script\release\uploaders\upload.py --verbose --upload_to_s3
} else {
Write-Output "Uploading Electron release distribution to github releases"
& python script\release\uploaders\upload.py
& python script\release\uploaders\upload.py --verbose
}
} elseif (Test-Path Env:\TEST_WOA) {
node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH

View File

@@ -21,6 +21,7 @@ buildflag_header("buildflags") {
"ENABLE_ELECTRON_EXTENSIONS=$enable_electron_extensions",
"ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
"ENABLE_PICTURE_IN_PICTURE=$enable_picture_in_picture",
"ENABLE_WIN_DARK_MODE_WINDOW_UI=$enable_win_dark_mode_window_ui",
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
]
}

View File

@@ -36,4 +36,7 @@ declare_args() {
# Enable Spellchecker support
enable_builtin_spellchecker = true
# Undocumented Windows dark mode API
enable_win_dark_mode_window_ui = false
}

View File

@@ -826,10 +826,9 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
to_send.append(current_dir.value());
const std::vector<std::string>& argv = electron::ElectronCommandLine::argv();
for (std::vector<std::string>::const_iterator it = argv.begin();
it != argv.end(); ++it) {
for (const auto& arg : argv) {
to_send.push_back(kTokenDelimiter);
to_send.append(*it);
to_send.append(arg);
}
// Send the message

View File

@@ -122,8 +122,7 @@ void GlobalMenuBarRegistrarX11::OnNameOwnerChanged(GObject* /* ignored */,
GParamSpec* /* ignored */) {
// If the name owner changed, we need to reregister all the live x11::Window
// with the system.
for (std::set<x11::Window>::const_iterator it = live_windows_.begin();
it != live_windows_.end(); ++it) {
RegisterXWindow(*it);
for (const auto& window : live_windows_) {
RegisterXWindow(window);
}
}

View File

@@ -32,7 +32,8 @@ In most cases, you should do everything in the `ready` event handler.
Returns:
* `launchInfo` unknown _macOS_
* `event` Event
* `launchInfo` Record<string, any> _macOS_
Emitted once, when Electron has finished initializing. On macOS, `launchInfo`
holds the `userInfo` of the `NSUserNotification` that was used to open the
@@ -1267,7 +1268,7 @@ systems Application folder. Use in combination with `app.moveToApplicationsFolde
### `app.moveToApplicationsFolder([options])` _macOS_
* `options` Object (optional)
* `conflictHandler` Function<Boolean> (optional) - A handler for potential conflict in move failure.
* `conflictHandler` Function\<Boolean> (optional) - A handler for potential conflict in move failure.
* `conflictType` String - The type of move conflict encountered by the handler; can be `exists` or `existsAndRunning`, where `exists` means that an app of the same name is present in the Applications directory and `existsAndRunning` means both that it exists and that it's presently running.
Returns `Boolean` - Whether the move was successful. Please note that if

View File

@@ -114,3 +114,9 @@ The following methods of `chrome.management` are supported:
- `chrome.management.getPermissionWarningsByManifest`
- `chrome.management.onEnabled`
- `chrome.management.onDisabled`
### `chrome.webRequest`
All features of this API are supported.
> **NOTE:** Electron's [`webRequest`](web-request.md) module takes precedence over `chrome.webRequest` if there are conflicting handlers.

View File

@@ -9,7 +9,7 @@ with the operating system so that you can customize the operations for various
shortcuts.
**Note:** The shortcut is global; it will work even if the app does
not have the keyboard focus. You should not use this module until the `ready`
not have the keyboard focus. This module cannot be used before the `ready`
event of the app module is emitted.
```javascript

View File

@@ -91,7 +91,7 @@ Removes listeners of the specified `channel`.
### `ipcMain.handle(channel, listener)`
* `channel` String
* `listener` Function<Promise<void> | any>
* `listener` Function<Promise\<void> | any>
* `event` IpcMainInvokeEvent
* `...args` any[]
@@ -123,7 +123,7 @@ WebContents is the source of the invoke request.
### `ipcMain.handleOnce(channel, listener)`
* `channel` String
* `listener` Function<Promise<void> | any>
* `listener` Function<Promise\<void> | any>
* `event` IpcMainInvokeEvent
* `...args` any[]

View File

@@ -376,7 +376,7 @@ session.fromPartition('some-partition').setPermissionRequestHandler((webContents
#### `ses.setPermissionCheckHandler(handler)`
* `handler` Function<Boolean> | null
* `handler` Function\<Boolean> | null
* `webContents` [WebContents](web-contents.md) - WebContents checking the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
* `permission` String - Enum of 'media'.
* `requestingOrigin` String - The origin URL of the permission check

View File

@@ -1,5 +1,6 @@
# IpcMainEvent Object extends `Event`
* `processId` Integer - The internal ID of the renderer process that sent this message
* `frameId` Integer - The ID of the renderer frame that sent this message
* `returnValue` any - Set this to the value to be returned in a synchronous message
* `sender` WebContents - Returns the `webContents` that sent the message

View File

@@ -1,4 +1,5 @@
# IpcMainInvokeEvent Object extends `Event`
* `processId` Integer - The internal ID of the renderer process that sent this message
* `frameId` Integer - The ID of the renderer frame that sent this message
* `sender` WebContents - Returns the `webContents` that sent the message

View File

@@ -1586,7 +1586,9 @@ app.whenReady().then(() => {
#### `contents.sendToFrame(frameId, channel, ...args)`
* `frameId` Integer
* `frameId` Integer | [number, number] - the ID of the frame to send to, or a
pair of `[processId, frameId]` if the frame is in a different process to the
main frame.
* `channel` String
* `...args` any[]
@@ -1760,7 +1762,7 @@ Returns `Boolean` - If *offscreen rendering* is enabled returns whether it is cu
* `fps` Integer
If *offscreen rendering* is enabled sets the frame rate to the specified number.
Only values between 1 and 60 are accepted.
Only values between 1 and 240 are accepted.
#### `contents.getFrameRate()`
@@ -1858,7 +1860,7 @@ The zoom factor is the zoom percent divided by 100, so 300% = 3.0.
#### `contents.frameRate`
An `Integer` property that sets the frame rate of the web contents to the specified number.
Only values between 1 and 60 are accepted.
Only values between 1 and 240 are accepted.
Only applicable if *offscreen rendering* is enabled.

View File

@@ -186,6 +186,45 @@ you should plan to update your native modules to be context aware.
For more detailed information see [#18397](https://github.com/electron/electron/issues/18397).
### Deprecated: `BrowserWindow` extension APIs
The following extension APIs have been deprecated:
* `BrowserWindow.addExtension(path)`
* `BrowserWindow.addDevToolsExtension(path)`
* `BrowserWindow.removeExtension(name)`
* `BrowserWindow.removeDevToolsExtension(name)`
* `BrowserWindow.getExtensions()`
* `BrowserWindow.getDevToolsExtensions()`
Use the session APIs instead:
* `ses.loadExtension(path)`
* `ses.removeExtension(extension_id)`
* `ses.getAllExtensions()`
```js
// Deprecated in Electron 9
BrowserWindow.addExtension(path)
BrowserWindow.addDevToolsExtension(path)
// Replace with
session.defaultSession.loadExtension(path)
```
```js
// Deprecated in Electron 9
BrowserWindow.removeExtension(name)
BrowserWindow.removeDevToolsExtension(name)
// Replace with
session.defaultSession.removeExtension(extension_id)
```
```js
// Deprecated in Electron 9
BrowserWindow.getExtensions()
BrowserWindow.getDevToolsExtensions()
// Replace with
session.defaultSession.getAllExtensions()
```
### Removed: `<webview>.getWebContents()`
This API, which was deprecated in Electron 8.0, is now removed.
@@ -329,6 +368,52 @@ in Electron 8.x, and cease to exist in Electron 9.x. The layout zoom level
limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
### Deprecated events in `systemPreferences`
The following `systemPreferences` events have been deprecated:
* `inverted-color-scheme-changed`
* `high-contrast-color-scheme-changed`
Use the new `updated` event on the `nativeTheme` module instead.
```js
// Deprecated
systemPreferences.on('inverted-color-scheme-changed', () => { /* ... */ })
systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })
// Replace with
nativeTheme.on('updated', () => { /* ... */ })
```
### Deprecated: methods in `systemPreferences`
The following `systemPreferences` methods have been deprecated:
* `systemPreferences.isDarkMode()`
* `systemPreferences.isInvertedColorScheme()`
* `systemPreferences.isHighContrastColorScheme()`
Use the following `nativeTheme` properties instead:
* `nativeTheme.shouldUseDarkColors`
* `nativeTheme.shouldUseInvertedColorScheme`
* `nativeTheme.shouldUseHighContrastColors`
```js
// Deprecated
systemPreferences.isDarkMode()
// Replace with
nativeTheme.shouldUseDarkColors
// Deprecated
systemPreferences.isInvertedColorScheme()
// Replace with
nativeTheme.shouldUseInvertedColorScheme
// Deprecated
systemPreferences.isHighContrastColorScheme()
// Replace with
nativeTheme.shouldUseHighContrastColors
```
## Planned Breaking API Changes (7.0)
### Deprecated: Atom.io Node Headers URL

View File

@@ -173,12 +173,12 @@ $ gn gen out/Testing-x86 --args='... target_cpu = "x86"'
Not all combinations of source and target CPU/OS are supported by Chromium.
<table>
<tr><th>Host</th><th>Target</th><th>Status</th></tr>
<tr><td>Windows x64</td><td>Windows arm64</td><td>Experimental</td>
<tr><td>Windows x64</td><td>Windows x86</td><td>Automatically tested</td></tr>
<tr><td>Linux x64</td><td>Linux x86</td><td>Automatically tested</td></tr>
</table>
| Host | Target | Status |
|-------------|---------------|----------------------|
| Windows x64 | Windows arm64 | Experimental |
| Windows x64 | Windows x86 | Automatically tested |
| Linux x64 | Linux x86 | Automatically tested |
If you test other combinations and find them to work, please update this document :)

View File

@@ -43,8 +43,8 @@ SRV*c:\code\symbols\*https://msdl.microsoft.com/download/symbols;SRV*c:\code\sym
## Using the symbol server in Visual Studio
<img src='https://mdn.mozillademos.org/files/733/symbol-server-vc8express-menu.jpg'>
<img src='https://mdn.mozillademos.org/files/2497/2005_options.gif'>
![Tools -> Options](https://mdn.mozillademos.org/files/733/symbol-server-vc8express-menu.jpg)
![Symbols Settings](https://mdn.mozillademos.org/files/2497/2005_options.gif)
## Troubleshooting: Symbols will not load

View File

@@ -1,25 +1,28 @@
# DevTools Extension
Electron supports the [Chrome DevTools Extension][devtools-extension], which can
be used to extend the ability of devtools for debugging popular web frameworks.
Electron supports [Chrome DevTools extensions][devtools-extension], which can
be used to extend the ability of Chrome's developer tools for debugging
popular web frameworks.
## How to load a DevTools Extension
## Loading a DevTools extension with tooling
This document outlines the process for manually loading an extension.
You may also try
[electron-devtools-installer](https://github.com/GPMDP/electron-devtools-installer),
a third-party tool that downloads extensions directly from the Chrome WebStore.
The easiest way to load a DevTools extension is to use third-party tooling to automate the
process for you. [electron-devtools-installer][electron-devtools-installer] is a popular
NPM package that does just that.
To load an extension in Electron, you need to download it in Chrome browser,
locate its filesystem path, and then load it by calling the
`BrowserWindow.addDevToolsExtension(extension)` API.
## Manually loading a DevTools extension
Using the [React Developer Tools][react-devtools] as example:
If you don't want to use the tooling approach, you can also do all of the necessary
operations by hand. To load an extension in Electron, you need to download it via Chrome,
locate its filesystem path, and then load it into your [Session][session] by calling the
[`ses.loadExtension`] API.
1. Install it in Chrome browser.
Using the [React Developer Tools][react-devtools] as an example:
1. Install the extension in Google Chrome.
1. Navigate to `chrome://extensions`, and find its extension ID, which is a hash
string like `fmkadmapgofadopljbjfkapdkoienihi`.
1. Find out filesystem location used by Chrome for storing extensions:
1. Find out the filesystem location used by Chrome for storing extensions:
* on Windows it is `%LOCALAPPDATA%\Google\Chrome\User Data\Default\Extensions`;
* on Linux it could be:
* `~/.config/google-chrome/Default/Extensions/`
@@ -27,36 +30,48 @@ Using the [React Developer Tools][react-devtools] as example:
* `~/.config/google-chrome-canary/Default/Extensions/`
* `~/.config/chromium/Default/Extensions/`
* on macOS it is `~/Library/Application Support/Google/Chrome/Default/Extensions`.
1. Pass the location of the extension to `BrowserWindow.addDevToolsExtension`
API, for the React Developer Tools, it is something like:
1. Pass the location of the extension to the [`ses.loadExtension`][load-extension]
API. For React Developer Tools `v4.9.0`, it looks something like:
```javascript
const path = require('path')
const os = require('os')
const { app, session } = require('electron')
const path = require('path')
const os = require('os')
BrowserWindow.addDevToolsExtension(
path.join(os.homedir(), '/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/4.3.0_0')
)
// on macOS
const reactDevToolsPath = path.join(
os.homedir(),
'/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/4.9.0_0'
)
app.whenReady().then(async () => {
await session.defaultSession.loadExtension(reactDevToolsPath)
})
```
**Note:** The `BrowserWindow.addDevToolsExtension` API cannot be called before the
ready event of the app module is emitted.
**Notes:**
The extension will be remembered so you only need to call this API once per
extension. If you try to add an extension that has already been loaded, this method
will not return and instead log a warning to the console.
* `loadExtension` returns a Promise with an [Extension object][extension-structure],
which contains metadata about the extension that was loaded. This promise needs to
resolve (e.g. with an `await` expression) before loading a page. Otherwise, the
extension won't be guaranteed to load.
* `loadExtension` cannot be called before the `ready` event of the `app` module
is emitted, nor can it be called on in-memory (non-persistent) sessions.
* `loadExtension` must be called on every boot of your app if you want the
extension to be loaded.
### How to remove a DevTools Extension
### Removing a DevTools extension
You can pass the name of the extension to the `BrowserWindow.removeDevToolsExtension`
API to remove it. The name of the extension is returned by
`BrowserWindow.addDevToolsExtension` and you can get the names of all installed
DevTools Extensions using the `BrowserWindow.getDevToolsExtensions` API.
You can pass the extension's ID to the [`ses.removeExtension`][remove-extension] API to
remove it from your Session. Loaded extensions are not persisted between
app launches.
## Supported DevTools Extensions
## DevTools extension support
Electron only supports a limited set of `chrome.*` APIs, so some extensions
using unsupported `chrome.*` APIs for chrome extension features may not work.
Following Devtools Extensions are tested and guaranteed to work in Electron:
Electron only supports
[a limited set of `chrome.*` APIs][supported-extension-apis],
so extensions using unsupported `chrome.*` APIs under the hood may not work.
The following Devtools extensions have been tested to work in Electron:
* [Ember Inspector](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
* [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)
@@ -68,14 +83,22 @@ Following Devtools Extensions are tested and guaranteed to work in Electron:
* [Redux DevTools Extension](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd)
* [MobX Developer Tools](https://chrome.google.com/webstore/detail/mobx-developer-tools/pfgnfdagidkfgccljigdamigbcnndkod)
### What should I do if a DevTools Extension is not working?
### What should I do if a DevTools extension is not working?
First please make sure the extension is still being maintained, some extensions
can not even work for recent versions of Chrome browser, and we are not able to
do anything for them.
First, please make sure the extension is still being maintained and is compatible
with the latest version of Google Chrome. We cannot provide additional support for
unsupported extensions.
Then file a bug at Electron's issues list, and describe which part of the
extension is not working as expected.
If the extension works on Chrome but not on Electron, file a bug in Electron's
[issue tracker][issue-tracker] and describe which part
of the extension is not working as expected.
[devtools-extension]: https://developer.chrome.com/extensions/devtools
[session]: ../api/session.md
[react-devtools]: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
[load-extension]: ../api/session.md#sesloadextensionpath
[extension-structure]: ../api/structures/extension.md
[remove-extension]: ../api/session.md#sesremoveextensionextensionid
[electron-devtools-installer]: https://github.com/MarshallOfSound/electron-devtools-installer
[supported-extension-apis]: ../api/extensions.md
[issue-tracker]: https://github.com/electron/electron/issues

View File

@@ -9,7 +9,7 @@ Two modes of rendering can be used and only the dirty area is passed in the
`'paint'` event to be more efficient. The rendering can be stopped, continued
and the frame rate can be set. The specified frame rate is a top limit value,
when there is nothing happening on a webpage, no frames are generated. The
maximum frame rate is 60, because above that there is no benefit, only
maximum frame rate is 240, because above that there is no benefit, only
performance loss.
**Note:** An offscreen window is always created as a [Frameless Window](../api/frameless-window.md).

View File

@@ -9,8 +9,12 @@ If you're looking for programming help,
for answers to questions,
or to join in discussion with other developers who use Electron,
you can interact with the community in these locations:
- [`electron`](https://discuss.atom.io/c/electron) category on the Atom
forums
- [`Electron's Discord`](https://discord.com/invite/electron) has channels for:
- Getting help
- Ecosystem apps like [Electron Forge](https://github.com/electron-userland/electron-forge) and [Electron Fiddle](https://github.com/electron/fiddle)
- Sharing ideas with other Electron app developers
- And more!
- [`electron`](https://discuss.atom.io/c/electron) category on the Atom forums
- `#atom-shell` channel on Freenode
- `#electron` channel on [Atom's Slack](https://discuss.atom.io/t/join-us-on-slack/16638?source_topic_id=25406)
- [`electron-ru`](https://telegram.me/electron_ru) *(Russian)*

View File

@@ -184,8 +184,12 @@ filenames = {
"shell/browser/electron_web_ui_controller_factory.h",
"shell/browser/event_emitter_mixin.cc",
"shell/browser/event_emitter_mixin.h",
"shell/browser/extended_web_contents_observer.h",
"shell/browser/feature_list.cc",
"shell/browser/feature_list.h",
"shell/browser/file_select_helper.cc",
"shell/browser/file_select_helper.h",
"shell/browser/file_select_helper_mac.mm",
"shell/browser/font_defaults.cc",
"shell/browser/font_defaults.h",
"shell/browser/javascript_environment.cc",
@@ -345,6 +349,7 @@ filenames = {
"shell/browser/ui/devtools_manager_delegate.h",
"shell/browser/ui/devtools_ui.cc",
"shell/browser/ui/devtools_ui.h",
"shell/browser/ui/drag_util.cc",
"shell/browser/ui/drag_util.h",
"shell/browser/ui/drag_util_mac.mm",
"shell/browser/ui/drag_util_views.cc",

View File

@@ -16,7 +16,7 @@ if ('getAppLevelAppearance' in systemPreferences) {
}
if ('getEffectiveAppearance' in systemPreferences) {
const nativeEAGetter = systemPreferences.getAppLevelAppearance;
const nativeEAGetter = systemPreferences.getEffectiveAppearance;
Object.defineProperty(SystemPreferences.prototype, 'effectiveAppearance', {
get: () => nativeEAGetter.call(systemPreferences)
});

View File

@@ -167,29 +167,29 @@ WebContents.prototype._sendInternalToAll = function (channel, ...args) {
return this._send(internal, sendToAll, channel, args);
};
WebContents.prototype.sendToFrame = function (frameId, channel, ...args) {
WebContents.prototype.sendToFrame = function (frame, channel, ...args) {
if (typeof channel !== 'string') {
throw new Error('Missing required channel argument');
} else if (typeof frameId !== 'number') {
throw new Error('Missing required frameId argument');
} else if (!(typeof frame === 'number' || Array.isArray(frame))) {
throw new Error('Missing required frame argument (must be number or array)');
}
const internal = false;
const sendToAll = false;
return this._sendToFrame(internal, sendToAll, frameId, channel, args);
return this._sendToFrame(internal, sendToAll, frame, channel, args);
};
WebContents.prototype._sendToFrameInternal = function (frameId, channel, ...args) {
WebContents.prototype._sendToFrameInternal = function (frame, channel, ...args) {
if (typeof channel !== 'string') {
throw new Error('Missing required channel argument');
} else if (typeof frameId !== 'number') {
throw new Error('Missing required frameId argument');
} else if (!(typeof frame === 'number' || Array.isArray(frame))) {
throw new Error('Missing required frame argument (must be number or array)');
}
const internal = true;
const sendToAll = false;
return this._sendToFrame(internal, sendToAll, frameId, channel, args);
return this._sendToFrame(internal, sendToAll, frame, channel, args);
};
// Following methods are mapped to webFrame.
@@ -445,8 +445,9 @@ WebContents.prototype.loadFile = function (filePath, options = {}) {
};
const addReplyToEvent = (event) => {
const { processId, frameId } = event;
event.reply = (...args) => {
event.sender.sendToFrame(event.frameId, ...args);
event.sender.sendToFrame([processId, frameId], ...args);
};
};

View File

@@ -48,6 +48,9 @@ export const getSourcesImpl = (event: Electron.IpcMainEvent | null, args: Electr
}
// Remove from currentlyRunning once we resolve or reject
currentlyRunning = currentlyRunning.filter(running => running.options !== options);
if (event) {
event.sender.removeListener('destroyed', stopRunning);
}
};
capturer._onerror = (error: string) => {
@@ -66,7 +69,7 @@ export const getSourcesImpl = (event: Electron.IpcMainEvent | null, args: Electr
// reference to emit and the capturer itself so that it never dispatches
// back to the renderer
if (event) {
event.sender.once('destroyed', () => stopRunning());
event.sender.once('destroyed', stopRunning);
}
});

View File

@@ -276,7 +276,7 @@ const fakeConstructor = (constructor: Function, name: string) =>
});
// Convert array of meta data from renderer into array of real values.
const unwrapArgs = function (sender: electron.WebContents, frameId: number, contextId: string, args: any[]) {
const unwrapArgs = function (sender: electron.WebContents, frameId: [number, number], contextId: string, args: any[]) {
const metaToValue = function (meta: MetaTypeFromRenderer): any {
switch (meta.type) {
case 'nativeimage':
@@ -331,7 +331,7 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
v8Util.setHiddenValue(callIntoRenderer, 'location', meta.location);
Object.defineProperty(callIntoRenderer, 'length', { value: meta.length });
v8Util.setRemoteCallbackFreer(callIntoRenderer, frameId, contextId, meta.id, sender);
v8Util.setRemoteCallbackFreer(callIntoRenderer, frameId[0], frameId[1], contextId, meta.id, sender);
rendererFunctions.set(objectId, callIntoRenderer);
return callIntoRenderer;
}
@@ -480,7 +480,7 @@ handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, co
});
handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args);
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
const constructor = objectsRegistry.get(id);
if (constructor == null) {
@@ -491,7 +491,7 @@ handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId,
});
handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args);
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
const func = objectsRegistry.get(id);
if (func == null) {
@@ -508,7 +508,7 @@ handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId
});
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args);
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
const object = objectsRegistry.get(id);
if (object == null) {
@@ -519,7 +519,7 @@ handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, cont
});
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args);
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
const object = objectsRegistry.get(id);
if (object == null) {
@@ -536,7 +536,7 @@ handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId,
});
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args);
args = unwrapArgs(event.sender, [event.processId, event.frameId], contextId, args);
const obj = objectsRegistry.get(id);
if (obj == null) {

View File

@@ -38,7 +38,7 @@ const keysOfTypeNumber = ['top', 'left', ...Object.keys(keysOfTypeNumberCompileT
type CoercedValue = string | number | boolean;
function coerce (key: string, value: string): CoercedValue {
if (keysOfTypeNumber.includes(key)) {
return Number(value);
return parseInt(value, 10);
}
switch (value) {

View File

@@ -276,7 +276,7 @@ function metaToError (meta) {
}
function handleMessage (channel, handler) {
ipcRendererInternal.on(channel, (event, passedContextId, id, ...args) => {
ipcRendererInternal.onMessageFromMain(channel, (event, passedContextId, id, ...args) => {
if (passedContextId === contextId) {
handler(id, ...args);
} else {

View File

@@ -6,11 +6,11 @@ class WebNavigation {
private onCompleted = new Event()
constructor () {
ipcRendererInternal.on('CHROME_WEBNAVIGATION_ONBEFORENAVIGATE', (event: Electron.IpcRendererEvent, details: any) => {
ipcRendererInternal.onMessageFromMain('CHROME_WEBNAVIGATION_ONBEFORENAVIGATE', (event: Electron.IpcRendererEvent, details: any) => {
this.onBeforeNavigate.emit(details);
});
ipcRendererInternal.on('CHROME_WEBNAVIGATION_ONCOMPLETED', (event: Electron.IpcRendererEvent, details: any) => {
ipcRendererInternal.onMessageFromMain('CHROME_WEBNAVIGATION_ONCOMPLETED', (event: Electron.IpcRendererEvent, details: any) => {
this.onCompleted.emit(details);
});
}

View File

@@ -3,7 +3,7 @@ import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-in
type IPCHandler = (event: Electron.IpcRendererEvent, ...args: any[]) => any
export const handle = function <T extends IPCHandler> (channel: string, handler: T) {
ipcRendererInternal.on(channel, async (event, requestId, ...args) => {
ipcRendererInternal.onMessageFromMain(channel, async (event, requestId, ...args) => {
const replyChannel = `${channel}_RESPONSE_${requestId}`;
try {
event.sender.send(replyChannel, null, await handler(event, ...args));

View File

@@ -30,4 +30,27 @@ if (!ipcRendererInternal.send) {
}
return result;
};
ipcRendererInternal.onMessageFromMain = function (channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => void) {
return ipcRendererInternal.on(channel, (event, ...args) => {
if (event.senderId !== 0) {
console.error(`Message ${channel} sent by unexpected WebContents (${event.senderId})`);
return;
}
listener(event, ...args);
});
};
ipcRendererInternal.onceMessageFromMain = function (channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => void) {
return ipcRendererInternal.on(channel, function wrapper (event, ...args) {
if (event.senderId !== 0) {
console.error(`Message ${channel} sent by unexpected WebContents (${event.senderId})`);
return;
}
ipcRendererInternal.removeListener(channel, wrapper);
listener(event, ...args);
});
};
}

View File

@@ -179,7 +179,7 @@ const warnAboutInsecureCSP = function () {
console.warn('%cElectron Security Warning (Insecure Content-Security-Policy)',
'font-weight: bold;', warning);
});
}).catch(() => {});
};
/**

View File

@@ -27,6 +27,7 @@ const WEB_VIEW_EVENTS: Record<string, Array<string>> = {
'focus-change': ['focus', 'guestInstanceId'],
close: [],
crashed: [],
'render-process-gone': ['details'],
'plugin-crashed': ['name', 'version'],
destroyed: [],
'page-title-updated': ['title', 'explicitSet'],
@@ -66,18 +67,18 @@ const dispatchEvent = function (
};
export function registerEvents (webView: WebViewImpl, viewInstanceId: number) {
ipcRendererInternal.on(`ELECTRON_GUEST_VIEW_INTERNAL_DESTROY_GUEST-${viewInstanceId}`, function () {
ipcRendererInternal.onMessageFromMain(`ELECTRON_GUEST_VIEW_INTERNAL_DESTROY_GUEST-${viewInstanceId}`, function () {
webView.guestInstanceId = undefined;
webView.reset();
const domEvent = new Event('destroyed');
webView.dispatchEvent(domEvent);
});
ipcRendererInternal.on(`ELECTRON_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-${viewInstanceId}`, function (event, eventName, ...args) {
ipcRendererInternal.onMessageFromMain(`ELECTRON_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-${viewInstanceId}`, function (event, eventName, ...args) {
dispatchEvent(webView, eventName, eventName, ...args);
});
ipcRendererInternal.on(`ELECTRON_GUEST_VIEW_INTERNAL_IPC_MESSAGE-${viewInstanceId}`, function (event, channel, ...args) {
ipcRendererInternal.onMessageFromMain(`ELECTRON_GUEST_VIEW_INTERNAL_IPC_MESSAGE-${viewInstanceId}`, function (event, channel, ...args) {
const domEvent = new Event('ipc-message') as IpcMessageEvent;
domEvent.channel = channel;
domEvent.args = args;

View File

@@ -17,7 +17,7 @@ interface MutationHandler {
// Attribute objects.
// Default implementation of a WebView attribute.
class WebViewAttribute implements MutationHandler {
export class WebViewAttribute implements MutationHandler {
public value: any;
public ignoreMutation = false;
@@ -78,7 +78,7 @@ class BooleanAttribute extends WebViewAttribute {
}
// Attribute representing the state of the storage partition.
class PartitionAttribute extends WebViewAttribute {
export class PartitionAttribute extends WebViewAttribute {
public validPartitionId = true
constructor (public webViewImpl: WebViewImpl) {
@@ -102,7 +102,7 @@ class PartitionAttribute extends WebViewAttribute {
}
// Attribute that handles the location and navigation of the webview.
class SrcAttribute extends WebViewAttribute {
export class SrcAttribute extends WebViewAttribute {
public observer!: MutationObserver;
constructor (public webViewImpl: WebViewImpl) {
@@ -168,7 +168,7 @@ class SrcAttribute extends WebViewAttribute {
}
public parse () {
if (!this.webViewImpl.elementAttached || !this.webViewImpl.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION].validPartitionId || !this.getValue()) {
if (!this.webViewImpl.elementAttached || !(this.webViewImpl.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION) as PartitionAttribute).validPartitionId || !this.getValue()) {
return;
}
if (this.webViewImpl.guestInstanceId == null) {
@@ -182,12 +182,12 @@ class SrcAttribute extends WebViewAttribute {
// Navigate to |this.src|.
const opts: Record<string, string> = {};
const httpreferrer = this.webViewImpl.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER].getValue();
const httpreferrer = this.webViewImpl.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER)!.getValue();
if (httpreferrer) {
opts.httpReferrer = httpreferrer;
}
const useragent = this.webViewImpl.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT].getValue();
const useragent = this.webViewImpl.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT)!.getValue();
if (useragent) {
opts.userAgent = useragent;
}
@@ -274,19 +274,18 @@ class EnableRemoteModuleAttribute extends WebViewAttribute {
// Sets up all of the webview attributes.
WebViewImpl.prototype.setupWebViewAttributes = function () {
this.attributes = {};
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION] = new PartitionAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC] = new SrcAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER] = new HttpReferrerAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT] = new UserAgentAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION, this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES, this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS, this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY, this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS, this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_ENABLEREMOTEMODULE] = new EnableRemoteModuleAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PRELOAD] = new PreloadAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_BLINKFEATURES] = new BlinkFeaturesAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEBLINKFEATURES] = new DisableBlinkFeaturesAttribute(this);
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_WEBPREFERENCES] = new WebPreferencesAttribute(this);
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION, new PartitionAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC, new SrcAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER, new HttpReferrerAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT, new UserAgentAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION, this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES, this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS, this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY, this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS, this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_ENABLEREMOTEMODULE, new EnableRemoteModuleAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_PRELOAD, new PreloadAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_BLINKFEATURES, new BlinkFeaturesAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEBLINKFEATURES, new DisableBlinkFeaturesAttribute(this));
this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_WEBPREFERENCES, new WebPreferencesAttribute(this));
};

View File

@@ -16,9 +16,6 @@ export const enum WEB_VIEW_CONSTANTS {
ATTRIBUTE_DISABLEBLINKFEATURES = 'disableblinkfeatures',
ATTRIBUTE_WEBPREFERENCES = 'webpreferences',
// Internal attribute.
ATTRIBUTE_INTERNALINSTANCEID = 'internalinstanceid',
// Error messages.
ERROR_MSG_ALREADY_NAVIGATED = 'The object has already navigated, so its partition cannot be changed.',
ERROR_MSG_CANNOT_INJECT_SCRIPT = '<webview> = ' + 'Script cannot be injected into content until the page has loaded.',

View File

@@ -10,6 +10,7 @@
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants';
import { WebViewImpl as IWebViewImpl, webViewImplModule } from '@electron/internal/renderer/web-view/web-view-impl';
import type { SrcAttribute } from '@electron/internal/renderer/web-view/web-view-attributes';
// Return a WebViewElement class that is defined in this context.
const defineWebViewElement = (v8Util: NodeJS.V8UtilBinding, webViewImpl: typeof webViewImplModule) => {
@@ -49,7 +50,7 @@ const defineWebViewElement = (v8Util: NodeJS.V8UtilBinding, webViewImpl: typeof
if (!internal.elementAttached) {
guestViewInternal.registerEvents(internal, internal.viewInstanceId);
internal.elementAttached = true;
internal.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC].parse();
(internal.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC) as SrcAttribute).parse();
}
}

View File

@@ -5,6 +5,7 @@ import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-inte
import * as guestViewInternal from '@electron/internal/renderer/web-view/guest-view-internal';
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants';
import { syncMethods, asyncMethods, properties } from '@electron/internal/common/web-view-methods';
import type { WebViewAttribute, PartitionAttribute } from '@electron/internal/renderer/web-view/web-view-attributes';
import { deserialize } from '@electron/internal/common/type-utils';
const { webFrame } = electron;
@@ -33,7 +34,7 @@ export class WebViewImpl {
public internalElement: HTMLIFrameElement
// Replaced in web-view-attributes
public attributes: Record<string, any> = {}
public attributes = new Map<string, WebViewAttribute>();
public setupWebViewAttributes (): void {}
constructor (public webviewNode: HTMLElement) {
@@ -76,7 +77,7 @@ export class WebViewImpl {
}
this.beforeFirstNavigation = true;
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION].validPartitionId = true;
(this.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION) as PartitionAttribute).validPartitionId = true;
// Since attachment swaps a local frame for a remote frame, we need our
// internal iframe element to be local again before we can reattach.
@@ -95,12 +96,12 @@ export class WebViewImpl {
// attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more
// details.
handleWebviewAttributeMutation (attributeName: string, oldValue: any, newValue: any) {
if (!this.attributes[attributeName] || this.attributes[attributeName].ignoreMutation) {
if (!this.attributes.has(attributeName) || this.attributes.get(attributeName)!.ignoreMutation) {
return;
}
// Let the changed attribute handle its own mutation
this.attributes[attributeName].handleMutation(oldValue, newValue);
this.attributes.get(attributeName)!.handleMutation(oldValue, newValue);
}
onElementResize () {
@@ -149,7 +150,7 @@ export class WebViewImpl {
// Touching the src attribute triggers a navigation. To avoid
// triggering a page reload on every guest-initiated navigation,
// we do not handle this mutation.
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC].setValueIgnoreMutation(newValue);
this.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC)!.setValueIgnoreMutation(newValue);
}
}
@@ -163,7 +164,7 @@ export class WebViewImpl {
}
onAttach (storagePartitionId: number) {
return this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION].setValue(storagePartitionId);
return this.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION)!.setValue(storagePartitionId);
}
buildParams () {
@@ -172,10 +173,8 @@ export class WebViewImpl {
userAgentOverride: this.userAgentOverride
};
for (const attributeName in this.attributes) {
if (Object.prototype.hasOwnProperty.call(this.attributes, attributeName)) {
params[attributeName] = this.attributes[attributeName].getValue();
}
for (const [attributeName, attribute] of this.attributes) {
params[attributeName] = attribute.getValue();
}
return params;

View File

@@ -181,7 +181,7 @@ class BrowserWindowProxy {
this.guestId = guestId;
this._location = new LocationProxy(guestId);
ipcRendererInternal.once(`ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_${guestId}`, () => {
ipcRendererInternal.onceMessageFromMain(`ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_${guestId}`, () => {
removeProxy(guestId);
this.closed = true;
});
@@ -281,7 +281,7 @@ export const windowSetup = (
if (contextIsolationEnabled) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['prompt'], window.prompt);
if (!usesNativeWindowOpen || openerId != null) {
ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
ipcRendererInternal.onMessageFromMain('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
_event, sourceId: number, message: any, sourceOrigin: string
) {
// Manually dispatch event instead of using postMessage because we also need to
@@ -336,7 +336,7 @@ export const windowSetup = (
let cachedVisibilityState = isHiddenPage ? 'hidden' : 'visible';
// Subscribe to visibilityState changes.
ipcRendererInternal.on('ELECTRON_GUEST_INSTANCE_VISIBILITY_CHANGE', function (_event, visibilityState: VisibilityState) {
ipcRendererInternal.onMessageFromMain('ELECTRON_GUEST_INSTANCE_VISIBILITY_CHANGE', function (_event, visibilityState: VisibilityState) {
if (cachedVisibilityState !== visibilityState) {
cachedVisibilityState = visibilityState;
document.dispatchEvent(new Event('visibilitychange'));

View File

@@ -1,11 +1,12 @@
{
"name": "electron",
"version": "10.1.4",
"version": "10.3.0",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
"@electron/docs-parser": "^0.7.2",
"@electron/docs-parser": "^0.10.0",
"@electron/typescript-definitions": "^8.7.2",
"@octokit/auth-app": "^2.10.0",
"@octokit/rest": "^16.3.2",
"@primer/octicons": "^9.1.1",
"@types/basic-auth": "^1.1.3",

1
patches/angle/.patches Normal file
View File

@@ -0,0 +1 @@
cherry-pick-2882e1afd982.patch

View File

@@ -0,0 +1,65 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jamie Madill <jmadill@chromium.org>
Date: Tue, 20 Oct 2020 09:45:23 -0400
Subject: Fix missing validation cache update on VAO binding.
Bug: chromium:1139398
Change-Id: I85a0d7a72bc2c97b07ebc5f86effd8e36aefd544
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2485581
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index c2d3868ff04af0813d496432c0f34b4f4a134fda..a6fa42c33a36a3e83f1bf959cbb566c6160e551e 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -8666,6 +8666,7 @@ void StateCache::onVertexArrayBindingChange(Context *context)
updateActiveAttribsMask(context);
updateVertexElementLimits(context);
updateBasicDrawStatesError();
+ updateBasicDrawElementsError();
}
void StateCache::onProgramExecutableChange(Context *context)
diff --git a/src/libANGLE/Context.h b/src/libANGLE/Context.h
index 10fa566d0040b2abe8d7193d668198bc2e461e38..8f33d1db627ccadb8f4bb8755bb43713365a6c6d 100644
--- a/src/libANGLE/Context.h
+++ b/src/libANGLE/Context.h
@@ -203,6 +203,7 @@ class StateCache final : angle::NonCopyable
// 2. onVertexArrayBufferStateChange.
// 3. onBufferBindingChange.
// 4. onVertexArrayStateChange.
+ // 5. onVertexArrayBindingStateChange.
intptr_t getBasicDrawElementsError(const Context *context) const
{
if (mCachedBasicDrawElementsError != kInvalidPointer)
diff --git a/src/tests/gl_tests/StateChangeTest.cpp b/src/tests/gl_tests/StateChangeTest.cpp
index 7356edc230e0f067e47023d952cb18f41b154ada..1c886e9c66caaf7508867bf06c94b8910d5fd736 100644
--- a/src/tests/gl_tests/StateChangeTest.cpp
+++ b/src/tests/gl_tests/StateChangeTest.cpp
@@ -5206,6 +5206,25 @@ TEST_P(RobustBufferAccessWebGL2ValidationStateChangeTest, BindZeroSizeBufferThen
ASSERT_GL_NO_ERROR();
}
+// Tests DrawElements with an empty buffer using a VAO.
+TEST_P(WebGL2ValidationStateChangeTest, DrawElementsEmptyVertexArray)
+{
+ ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
+
+ glUseProgram(program);
+
+ // Draw with empty buffer. Out of range but valid.
+ GLBuffer buffer;
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
+ glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT, reinterpret_cast<const GLvoid *>(0x1000));
+
+ // Switch VAO. No buffer bound, should be an error.
+ GLVertexArray vao;
+ glBindVertexArray(vao);
+ glDrawElements(GL_LINE_STRIP, 0x1000, GL_UNSIGNED_SHORT,
+ reinterpret_cast<const GLvoid *>(0x1000));
+ EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
} // anonymous namespace
ANGLE_INSTANTIATE_TEST_ES2(StateChangeTest);

View File

@@ -74,7 +74,6 @@ add_trustedauthclient_to_urlloaderfactory.patch
feat_allow_disabling_blink_scheduler_throttling_per_renderview.patch
accessible_pane_view.patch
fix_use_the_new_mediaplaypause_key_listener_for_internal_chrome.patch
use_electron_resources_in_pdf_util.patch
hack_plugin_response_interceptor_to_point_to_electron.patch
fix_route_mouse_event_navigations_through_the_web_contents_delegate.patch
feat_add_support_for_overriding_the_base_spellchecker_download_url.patch
@@ -94,7 +93,6 @@ fix_swap_global_proxies_before_initializing_the_windows_proxies.patch
allow_setting_secondary_label_via_simplemenumodel.patch
refactor_expose_cursor_changes_to_the_webcontentsobserver.patch
disable_unnecessary_ischromefirstrun_check.patch
use_electron_resources_in_icon_reader_service.patch
fix_include_missing_header_file.patch
cherrypick_future_chrome_commit_to_remove_superfluous_dcheck.patch
worker_feat_add_hook_to_notify_script_ready.patch
@@ -105,3 +103,25 @@ fix_properly_honor_printing_page_ranges.patch
cherry-pick-8629cd7f8af3.patch
avoid_use-after-free.patch
don_t_create_providers_if_context_is_lost.patch
fix_use_electron_generated_resources.patch
chore_expose_v8_initialization_isolate_callbacks.patch
cherry-pick-f440137cd96a.patch
cherry-pick-30261f9de11e.patch
cherry-pick-88f263f401b4.patch
cherry-pick-229fdaf8fc05.patch
cherry-pick-1ed869ad4bb3.patch
cherry-pick-8f24f935c903.patch
crashpad-initialize-logging.patch
cherry-pick-bbb64b5c6916.patch
ignore_renderframehostimpl_detach_for_speculative_rfhs.patch
cherry-pick-eec5025668f8.patch
cherry-pick-bbc6ab5bb49c.patch
cherry-pick-3abc372c9c00.patch
cherry-pick-d8d64b7cd244.patch
cherry-pick-5ffbb7ed173a.patch
ui_check_that_unpremultiply_is_passed_a_32bpp_image.patch
cherry-pick-ecdec1fb0f42.patch
merge_m86_ensure_that_buffers_used_by_imagedecoder_haven_t_been.patch
cherry-pick-2d18de63acf1.patch
only_zero_out_cross-origin_audio_that_doesn_t_get_played_out.patch
fix_setparentacessibile_crash_win.patch

View File

@@ -0,0 +1,160 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Reilly Grant <reillyg@chromium.org>
Date: Wed, 7 Oct 2020 23:26:36 +0000
Subject: usb: Prevent parallel calls to UsbDevice::Open
This change adds a check to prevent a Mojo client from calling Open()
multiple times while the open is in progress.
Bug: 1135857
Change-Id: Ib467de9129673710b883d9e186c32c359f8592d8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2454846
Auto-Submit: Reilly Grant <reillyg@chromium.org>
Reviewed-by: Matt Reynolds <mattreynolds@chromium.org>
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#814940}
diff --git a/services/device/usb/mojo/device_impl.cc b/services/device/usb/mojo/device_impl.cc
index 1e7a6a798cf43d24a6dcb42e4ac676098908e0a1..bc7081486476045ed7d957ba8cdec8a52227c517 100644
--- a/services/device/usb/mojo/device_impl.cc
+++ b/services/device/usb/mojo/device_impl.cc
@@ -160,6 +160,7 @@ void DeviceImpl::OnOpen(base::WeakPtr<DeviceImpl> self,
return;
}
+ self->opening_ = false;
self->device_handle_ = std::move(handle);
if (self->device_handle_ && self->client_)
self->client_->OnDeviceOpened();
@@ -175,16 +176,19 @@ void DeviceImpl::OnPermissionGrantedForOpen(OpenCallback callback,
device_->Open(base::BindOnce(
&DeviceImpl::OnOpen, weak_factory_.GetWeakPtr(), std::move(callback)));
} else {
+ opening_ = false;
std::move(callback).Run(mojom::UsbOpenDeviceError::ACCESS_DENIED);
}
}
void DeviceImpl::Open(OpenCallback callback) {
- if (device_handle_) {
+ if (opening_ || device_handle_) {
std::move(callback).Run(mojom::UsbOpenDeviceError::ALREADY_OPEN);
return;
}
+ opening_ = true;
+
if (!device_->permission_granted()) {
device_->RequestPermission(
base::BindOnce(&DeviceImpl::OnPermissionGrantedForOpen,
diff --git a/services/device/usb/mojo/device_impl.h b/services/device/usb/mojo/device_impl.h
index ca3bffe4392f7607f7cf7445e2f21320fc02a82f..0965ca72663e14463aedfcff813c8307a1ebd447 100644
--- a/services/device/usb/mojo/device_impl.h
+++ b/services/device/usb/mojo/device_impl.h
@@ -106,7 +106,9 @@ class DeviceImpl : public mojom::UsbDevice, public device::UsbDevice::Observer {
ScopedObserver<device::UsbDevice, device::UsbDevice::Observer> observer_;
// The device handle. Will be null before the device is opened and after it
- // has been closed.
+ // has been closed. |opening_| is set to true while the asynchronous open is
+ // in progress.
+ bool opening_ = false;
scoped_refptr<UsbDeviceHandle> device_handle_;
mojo::SelfOwnedReceiverRef<mojom::UsbDevice> receiver_;
diff --git a/services/device/usb/mojo/device_impl_unittest.cc b/services/device/usb/mojo/device_impl_unittest.cc
index f0cd0eab4cf04d6f922c1748274d8f5f07a9452e..81045373bb3fa306b78f580f87424eacba36cd3d 100644
--- a/services/device/usb/mojo/device_impl_unittest.cc
+++ b/services/device/usb/mojo/device_impl_unittest.cc
@@ -22,6 +22,7 @@
#include "base/memory/ref_counted_memory.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
+#include "base/test/bind_test_util.h"
#include "base/test/task_environment.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/receiver.h"
@@ -265,7 +266,10 @@ class USBDeviceImplTest : public testing::Test {
void OpenMockHandle(UsbDevice::OpenCallback& callback) {
EXPECT_FALSE(is_device_open_);
is_device_open_ = true;
- std::move(callback).Run(mock_handle_);
+ // Simulate the asynchronous device opening process.
+ base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, base::BindOnce(std::move(callback), mock_handle_),
+ base::TimeDelta::FromMilliseconds(1));
}
void CloseMockHandle() {
@@ -515,17 +519,39 @@ TEST_F(USBDeviceImplTest, OpenFailure) {
GetMockDeviceProxy(device_client.CreateInterfacePtrAndBind());
EXPECT_CALL(mock_device(), OpenInternal(_))
- .WillOnce(Invoke([](UsbDevice::OpenCallback& callback) {
+ .WillOnce([](UsbDevice::OpenCallback& callback) {
std::move(callback).Run(nullptr);
- }));
+ });
EXPECT_CALL(device_client, OnDeviceOpened()).Times(0);
EXPECT_CALL(device_client, OnDeviceClosed()).Times(0);
- base::RunLoop loop;
- device->Open(base::BindOnce(&ExpectOpenAndThen,
- mojom::UsbOpenDeviceError::ACCESS_DENIED,
- loop.QuitClosure()));
- loop.Run();
+ {
+ base::RunLoop loop;
+ device->Open(
+ base::BindLambdaForTesting([&](mojom::UsbOpenDeviceError result) {
+ EXPECT_EQ(result, mojom::UsbOpenDeviceError::ACCESS_DENIED);
+ loop.Quit();
+ }));
+ loop.Run();
+ }
+
+ // A second attempt can succeed.
+ EXPECT_CALL(mock_device(), OpenInternal(_));
+ EXPECT_CALL(device_client, OnDeviceOpened());
+ EXPECT_CALL(device_client, OnDeviceClosed());
+
+ {
+ base::RunLoop loop;
+ device->Open(
+ base::BindLambdaForTesting([&](mojom::UsbOpenDeviceError result) {
+ EXPECT_EQ(result, mojom::UsbOpenDeviceError::OK);
+ loop.Quit();
+ }));
+ loop.Run();
+ }
+
+ device.reset();
+ base::RunLoop().RunUntilIdle();
}
TEST_F(USBDeviceImplTest, OpenDelayedFailure) {
@@ -549,6 +575,24 @@ TEST_F(USBDeviceImplTest, OpenDelayedFailure) {
std::move(saved_callback).Run(nullptr);
}
+TEST_F(USBDeviceImplTest, MultipleOpenNotAllowed) {
+ MockUsbDeviceClient device_client;
+ mojo::Remote<mojom::UsbDevice> device =
+ GetMockDeviceProxy(device_client.CreateInterfacePtrAndBind());
+
+ base::RunLoop loop;
+ device->Open(
+ base::BindLambdaForTesting([&](mojom::UsbOpenDeviceError result) {
+ EXPECT_EQ(result, mojom::UsbOpenDeviceError::OK);
+ }));
+ device->Open(
+ base::BindLambdaForTesting([&](mojom::UsbOpenDeviceError result) {
+ EXPECT_EQ(result, mojom::UsbOpenDeviceError::ALREADY_OPEN);
+ loop.Quit();
+ }));
+ loop.Run();
+}
+
TEST_F(USBDeviceImplTest, Close) {
MockUsbDeviceClient device_client;
mojo::Remote<mojom::UsbDevice> device =

View File

@@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Guido Urdaneta <guidou@chromium.org>
Date: Wed, 14 Oct 2020 19:40:12 +0000
Subject: Validate input of MediaStreamDispatcherHost::OpenDevice()
This method forwards to MediaStreamManager::OpenDevice(), which
DCHECKs for the stream type to be device video or audio capture
(i.e., webcam or mic). However, MSDH admits other stream types,
which cause MSM::OpenDevice to hit this DCHECK.
This CL ensures that a message containing an incorrect stream type,
which could be sent by a malicious renderer, results in killing the
renderer process.
Bug: 1135018
Change-Id: I3884dde95d92c41f44966a8ab1dd7bdfd4b23b9b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2472397
Auto-Submit: Guido Urdaneta <guidou@chromium.org>
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Reviewed-by: Avi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817151}
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h
index 0d5ef5f9d79dbc82a325f91b36350d01d760a064..ab0a195c2da772ea5825bb97e54743318bd06841 100644
--- a/content/browser/bad_message.h
+++ b/content/browser/bad_message.h
@@ -255,6 +255,7 @@ enum BadMessageReason {
RFH_INVALID_CALL_FROM_NOT_MAIN_FRAME = 227,
INPUT_ROUTER_INVALID_EVENT_SOURCE = 228,
RWH_CLOSE_PORTAL = 233,
+ MSDH_INVALID_STREAM_TYPE = 234,
// Please add new elements here. The naming convention is abbreviated class
// name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
index 3e43ba7ad5c9e7223df587f3126807618da17245..835c9be6981b0b0fa3548a4fa7629d19280aec76 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -196,6 +196,13 @@ void MediaStreamDispatcherHost::OpenDevice(int32_t page_request_id,
blink::mojom::MediaStreamType type,
OpenDeviceCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // OpenDevice is only supported for microphone or webcam capture.
+ if (type != blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE &&
+ type != blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE) {
+ bad_message::ReceivedBadMessage(
+ render_process_id_, bad_message::MDDH_INVALID_DEVICE_TYPE_REQUEST);
+ return;
+ }
base::PostTaskAndReplyWithResult(
GetUIThreadTaskRunner({}).get(), FROM_HERE,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index c394f02fb8d8150689109bc2c853f63af965fc29..e6c4aadf3dd94baec25aa3e6ce24aae191a6d145 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -6154,6 +6154,7 @@ Unknown properties are collapsed to zero. -->
<int value="227" label="RFH_INVALID_CALL_FROM_NOT_MAIN_FRAME"/>
<int value="228" label="INPUT_ROUTER_INVALID_EVENT_SOURCE"/>
<int value="233" label="RWH_CLOSE_PORTAL"/>
+ <int value="234" label="MSDH_INVALID_STREAM_TYPE"/>
</enum>
<enum name="BadMessageReasonExtensions">

View File

@@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: danakj <danakj@chromium.org>
Date: Tue, 17 Nov 2020 21:47:27 +0000
Subject: Convert strides with padding in skia::SkBitmapToN32OpaqueOrPremul().
Code using bitmaps converted with SkBitmapToN32OpaqueOrPremul() can
easily assume that the pixels are one contiguous (width*4*height)-sized
buffer. If it's not then out-of-bounds read/write can occur.
Also adds tests for SkBitmapToN32OpaqueOrPremul().
R=fmalita@chromium.org
Bug: 1147431, 1144462
Change-Id: I21f7a958a8c9231bf5f052f8ff246f2c249bd70b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2544032
Commit-Queue: danakj <danakj@chromium.org>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Cr-Commit-Position: refs/heads/master@{#828406}
diff --git a/skia/ext/skia_utils_base.cc b/skia/ext/skia_utils_base.cc
index 516ad7ea1e3a0acb1c8b207f98f6daf534262cbc..f9e622eff3ec6c3287138d7cdf68814b8535a338 100644
--- a/skia/ext/skia_utils_base.cc
+++ b/skia/ext/skia_utils_base.cc
@@ -85,7 +85,8 @@ void WriteSkFontStyle(base::Pickle* pickle, SkFontStyle style) {
bool SkBitmapToN32OpaqueOrPremul(const SkBitmap& in, SkBitmap* out) {
DCHECK(out);
const SkImageInfo& info = in.info();
- if (info.colorType() == kN32_SkColorType &&
+ const bool stride_matches_width = in.rowBytes() == info.minRowBytes();
+ if (stride_matches_width && info.colorType() == kN32_SkColorType &&
(info.alphaType() == kPremul_SkAlphaType ||
info.alphaType() == kOpaque_SkAlphaType)) {
// Shallow copy if the data is already in the right format.
diff --git a/skia/ext/skia_utils_base.h b/skia/ext/skia_utils_base.h
index 2a1eca124e91695ddec635e593ad1e9b650aa156..40401bb2fe0e484fae64490757d63f85e5c5ffea 100644
--- a/skia/ext/skia_utils_base.h
+++ b/skia/ext/skia_utils_base.h
@@ -42,9 +42,10 @@ SK_API void WriteSkFontIdentity(
// Writes style into the request pickle.
SK_API void WriteSkFontStyle(base::Pickle* pickle, SkFontStyle style);
-// Converts an SkBitmap to an Opaque or Premul N32 SkBitmap. If the input is in
-// the right format (N32 Opaque or Premul) already, points |out| directly at
-// |in|. |out| may or may not be GPU-backed.
+// Converts an SkBitmap to an Opaque or Premul N32 SkBitmap with stride matching
+// the width of each row. If the input is has the right format (N32 Opaque or
+// Premul) without stride padding already, this assigns `in` to `out`, sharing
+// the backing pixels. `out` may or may not be GPU-backed.
//
// If unsuccessful, returns false, but |out| may be modified.
SK_API bool SkBitmapToN32OpaqueOrPremul(const SkBitmap& in, SkBitmap* out);

View File

@@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lei Zhang <thestig@chromium.org>
Date: Thu, 1 Oct 2020 19:18:54 +0000
Subject: Check RF is alive In PrintRenderFrameHelper::PreviewPageRendered().
Do not take an accessibility snapshot if the RenderFrame is gone.
Bug: 1133983
Change-Id: I612cc72936a1dcedc5180c24eae067e47237b09b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2442375
Reviewed-by: Dominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812851}
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
index c0107f561f444d537735d4725c6dbecbcaf45226..1f7b7294aa5afb7f967ec260ab9f62d8b27d6827 100644
--- a/components/printing/renderer/print_render_frame_helper.cc
+++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -2463,6 +2463,10 @@ bool PrintRenderFrameHelper::PreviewPageRendered(
"page_number", page_number);
#if BUILDFLAG(ENABLE_TAGGED_PDF)
+ // Make sure the RenderFrame is alive before taking the snapshot.
+ if (render_frame_gone_)
+ snapshotter_.reset();
+
// For tagged PDF exporting, send a snapshot of the accessibility tree
// along with page 0. The accessibility tree contains the content for
// all of the pages of the main frame.

View File

@@ -0,0 +1,61 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Xiaocheng Hu <xiaochengh@chromium.org>
Date: Tue, 3 Nov 2020 23:00:29 +0000
Subject: Apply markup sanitizer in CompositeEditCommand::MoveParagraphs()
CompositeEditCommand::MoveParagraphs() serailizes part of the DOM and
then re-parse it and insert it at some other place of the document. This
is essentially a copy-and-paste, and can be exploited in the same way
how copy-and-paste is exploited. So we should also sanitize markup in
the function.
(cherry picked from commit c529cbcc1bb0f72af944c30f03c2b3b435317bc7)
Bug: 1141350
Change-Id: I25c1dfc61c20b9134b23e057c5a3a0f56c190b5c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2500633
Commit-Queue: Yoshifumi Inoue <yosin@chromium.org>
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#821098}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2518088
Reviewed-by: Xiaocheng Hu <xiaochengh@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/branch-heads/4280@{#1099}
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
diff --git a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
index 08a19440da1bff652481c3cedae2f1edb2b58246..0ba9af6cff6dd6eaa373a0f4dca37226aee85ca0 100644
--- a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
@@ -1507,19 +1507,18 @@ void CompositeEditCommand::MoveParagraphs(
// FIXME: This is an inefficient way to preserve style on nodes in the
// paragraph to move. It shouldn't matter though, since moved paragraphs will
// usually be quite small.
- DocumentFragment* fragment =
- start_of_paragraph_to_move.DeepEquivalent() !=
- end_of_paragraph_to_move.DeepEquivalent()
- ? CreateFragmentFromMarkup(
- GetDocument(),
- CreateMarkup(start.ParentAnchoredEquivalent(),
- end.ParentAnchoredEquivalent(),
- CreateMarkupOptions::Builder()
- .SetShouldConvertBlocksToInlines(true)
- .SetConstrainingAncestor(constraining_ancestor)
- .Build()),
- "", kDisallowScriptingAndPluginContent)
- : nullptr;
+ DocumentFragment* fragment = nullptr;
+ if (start_of_paragraph_to_move.DeepEquivalent() !=
+ end_of_paragraph_to_move.DeepEquivalent()) {
+ const String paragraphs_markup = CreateMarkup(
+ start.ParentAnchoredEquivalent(), end.ParentAnchoredEquivalent(),
+ CreateMarkupOptions::Builder()
+ .SetShouldConvertBlocksToInlines(true)
+ .SetConstrainingAncestor(constraining_ancestor)
+ .Build());
+ fragment = CreateSanitizedFragmentFromMarkupWithContext(
+ GetDocument(), paragraphs_markup, 0, paragraphs_markup.length(), "");
+ }
// A non-empty paragraph's style is moved when we copy and move it. We don't
// move anything if we're given an empty paragraph, but an empty paragraph can

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Darwin Huang <huangdarwin@chromium.org>
Date: Fri, 13 Nov 2020 10:07:05 +0000
Subject: Pepper: Ensure weak pointer is still valid before use (M86).
TBR=bbudge@chromium.org
(cherry picked from commit f24c213293752250db05e11c5e4b77adce002d38)
Bug: 1146675
Change-Id: I382dcb5c0b09a26e3c397ebef46947f626e2aef9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2527065
Reviewed-by: Bill Budge <bbudge@chromium.org>
Commit-Queue: Darwin Huang <huangdarwin@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#825558}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2536757
Reviewed-by: Darwin Huang <huangdarwin@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1448}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/content/browser/renderer_host/pepper/pepper_file_io_host.cc b/content/browser/renderer_host/pepper/pepper_file_io_host.cc
index 28fba2fc56ddb7f42f3390db99999998ba912867..74bb7c539f8f05971b020e1d370098f5825e0ac2 100644
--- a/content/browser/renderer_host/pepper/pepper_file_io_host.cc
+++ b/content/browser/renderer_host/pepper/pepper_file_io_host.cc
@@ -248,7 +248,12 @@ void PepperFileIOHost::GotUIThreadStuffForInternalFileSystems(
return;
}
- DCHECK(file_system_host_.get());
+ if (!file_system_host_.get()) {
+ reply_context.params.set_result(PP_ERROR_FAILED);
+ SendOpenErrorReply(reply_context);
+ return;
+ }
+
DCHECK(file_system_host_->GetFileSystemOperationRunner());
file_system_host_->GetFileSystemOperationRunner()->OpenFile(

View File

@@ -0,0 +1,315 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Will Cassella <cassew@google.com>
Date: Thu, 24 Sep 2020 22:54:27 +0000
Subject: Add callback to WebMediaPlayerImpl to notify when a redirect occurs
(cherry picked from commit 8b18bcfd9aa8096c4551ec34c0225b6017cd211e)
Bug: 1128657
Change-Id: I9548e1f3bfe5693871a56e23c3373f45147e52e0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2422091
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#809217}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2425223
Commit-Queue: Will Cassella <cassew@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#993}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/media/blink/multibuffer_data_source.cc b/media/blink/multibuffer_data_source.cc
index 0f6ae1fb8b4ff9f24ce3f407b7359e016fc6de5f..4ec77cf8a6b56002e601fb89eb0dee059f3ab31b 100644
--- a/media/blink/multibuffer_data_source.cc
+++ b/media/blink/multibuffer_data_source.cc
@@ -145,7 +145,7 @@ MultibufferDataSource::MultibufferDataSource(
DCHECK(url_data_.get());
url_data_->Use();
url_data_->OnRedirect(
- base::BindOnce(&MultibufferDataSource::OnRedirect, weak_ptr_));
+ base::BindOnce(&MultibufferDataSource::OnRedirected, weak_ptr_));
}
MultibufferDataSource::~MultibufferDataSource() {
@@ -219,10 +219,10 @@ void MultibufferDataSource::Initialize(InitializeCB init_cb) {
}
}
-void MultibufferDataSource::OnRedirect(
- const scoped_refptr<UrlData>& destination) {
- if (!destination) {
- // A failure occured.
+void MultibufferDataSource::OnRedirected(
+ const scoped_refptr<UrlData>& new_destination) {
+ if (!new_destination) {
+ // A failure occurred.
failed_ = true;
if (init_cb_) {
render_task_runner_->PostTask(
@@ -235,38 +235,39 @@ void MultibufferDataSource::OnRedirect(
StopLoader();
return;
}
- if (url_data_->url().GetOrigin() != destination->url().GetOrigin()) {
+ if (url_data_->url().GetOrigin() != new_destination->url().GetOrigin()) {
single_origin_ = false;
}
SetReader(nullptr);
- url_data_ = std::move(destination);
+ url_data_ = std::move(new_destination);
- if (url_data_) {
- url_data_->OnRedirect(
- base::BindOnce(&MultibufferDataSource::OnRedirect, weak_ptr_));
+ url_data_->OnRedirect(
+ base::BindOnce(&MultibufferDataSource::OnRedirected, weak_ptr_));
- if (init_cb_) {
- CreateResourceLoader(0, kPositionNotSpecified);
- if (reader_->Available()) {
- render_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&MultibufferDataSource::StartCallback, weak_ptr_));
- } else {
- reader_->Wait(1, base::BindOnce(&MultibufferDataSource::StartCallback,
- weak_ptr_));
- }
- } else if (read_op_) {
- CreateResourceLoader(read_op_->position(), kPositionNotSpecified);
- if (reader_->Available()) {
- render_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&MultibufferDataSource::ReadTask, weak_ptr_));
- } else {
- reader_->Wait(
- 1, base::BindOnce(&MultibufferDataSource::ReadTask, weak_ptr_));
- }
+ if (init_cb_) {
+ CreateResourceLoader(0, kPositionNotSpecified);
+ if (reader_->Available()) {
+ render_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&MultibufferDataSource::StartCallback, weak_ptr_));
+ } else {
+ reader_->Wait(
+ 1, base::BindOnce(&MultibufferDataSource::StartCallback, weak_ptr_));
+ }
+ } else if (read_op_) {
+ CreateResourceLoader(read_op_->position(), kPositionNotSpecified);
+ if (reader_->Available()) {
+ render_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&MultibufferDataSource::ReadTask, weak_ptr_));
+ } else {
+ reader_->Wait(
+ 1, base::BindOnce(&MultibufferDataSource::ReadTask, weak_ptr_));
}
}
+
+ if (redirect_cb_)
+ redirect_cb_.Run();
}
void MultibufferDataSource::SetPreload(Preload preload) {
@@ -287,6 +288,10 @@ bool MultibufferDataSource::IsCorsCrossOrigin() const {
return url_data_->is_cors_cross_origin();
}
+void MultibufferDataSource::OnRedirect(RedirectCB callback) {
+ redirect_cb_ = std::move(callback);
+}
+
bool MultibufferDataSource::HasAccessControl() const {
return url_data_->has_access_control();
}
diff --git a/media/blink/multibuffer_data_source.h b/media/blink/multibuffer_data_source.h
index 3da5a7bba5e7cc0f54998a81649f4dd9d78aa7be..da316964ff1543086865d7c85597f381ca8a3296 100644
--- a/media/blink/multibuffer_data_source.h
+++ b/media/blink/multibuffer_data_source.h
@@ -38,6 +38,7 @@ class MultiBufferReader;
class MEDIA_BLINK_EXPORT MultibufferDataSource : public DataSource {
public:
using DownloadingCB = base::RepeatingCallback<void(bool)>;
+ using RedirectCB = base::RepeatingCallback<void()>;
// Used to specify video preload states. They are "hints" to the browser about
// how aggressively the browser should load and buffer data.
@@ -82,6 +83,9 @@ class MEDIA_BLINK_EXPORT MultibufferDataSource : public DataSource {
// This must be called after the response arrives.
bool IsCorsCrossOrigin() const;
+ // Provides a callback to be run when the underlying url is redirected.
+ void OnRedirect(RedirectCB callback);
+
// Returns true if the response includes an Access-Control-Allow-Origin
// header (that is not "null").
bool HasAccessControl() const;
@@ -128,7 +132,7 @@ class MEDIA_BLINK_EXPORT MultibufferDataSource : public DataSource {
bool cancel_on_defer_for_testing() const { return cancel_on_defer_; }
protected:
- void OnRedirect(const scoped_refptr<UrlData>& destination);
+ void OnRedirected(const scoped_refptr<UrlData>& new_destination);
// A factory method to create a BufferedResourceLoader based on the read
// parameters.
@@ -243,6 +247,9 @@ class MEDIA_BLINK_EXPORT MultibufferDataSource : public DataSource {
// go between different origins.
bool single_origin_;
+ // Callback used when a redirect occurs.
+ RedirectCB redirect_cb_;
+
// Close the connection when we have enough data.
bool cancel_on_defer_;
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 8c769e69efad504f15a0fc79a2efc0cecf91f0a8..b234635ad78f6a22c91ecf854e7ae2f468315cc4 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -799,6 +799,8 @@ void WebMediaPlayerImpl::DoLoad(LoadType load_type,
base::BindRepeating(&WebMediaPlayerImpl::NotifyDownloading,
weak_this_));
data_source_.reset(mb_data_source_);
+ mb_data_source_->OnRedirect(base::BindRepeating(
+ &WebMediaPlayerImpl::OnDataSourceRedirected, weak_this_));
mb_data_source_->SetPreload(preload_);
mb_data_source_->SetIsClientAudioElement(client_->IsAudioElement());
mb_data_source_->Initialize(
@@ -2642,6 +2644,16 @@ void WebMediaPlayerImpl::DataSourceInitialized(bool success) {
StartPipeline();
}
+void WebMediaPlayerImpl::OnDataSourceRedirected() {
+ DVLOG(1) << __func__;
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(mb_data_source_);
+
+ if (WouldTaintOrigin()) {
+ audio_source_provider_->TaintOrigin();
+ }
+}
+
void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) {
DVLOG(1) << __func__ << "(" << is_downloading << ")";
if (!is_downloading && network_state_ == WebMediaPlayer::kNetworkStateLoading)
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h
index f4e48c46f6217b218f39b96d40220f040bdb556b..d2ee61bae7e1b30d0eac4a14437e00bbdc8a6e68 100644
--- a/media/blink/webmediaplayer_impl.h
+++ b/media/blink/webmediaplayer_impl.h
@@ -382,6 +382,9 @@ class MEDIA_BLINK_EXPORT WebMediaPlayerImpl
// Called after asynchronous initialization of a data source completed.
void DataSourceInitialized(bool success);
+ // Called if the |MultiBufferDataSource| is redirected.
+ void OnDataSourceRedirected();
+
// Called when the data source is downloading or paused.
void NotifyDownloading(bool is_downloading);
diff --git a/third_party/blink/public/platform/webaudiosourceprovider_impl.h b/third_party/blink/public/platform/webaudiosourceprovider_impl.h
index 5383074dcbffbb77a102de6fb551628ff5b964b8..bbf2a0b3d28282587625d6a5cd0103f6a5378b54 100644
--- a/third_party/blink/public/platform/webaudiosourceprovider_impl.h
+++ b/third_party/blink/public/platform/webaudiosourceprovider_impl.h
@@ -75,6 +75,7 @@ class BLINK_PLATFORM_EXPORT WebAudioSourceProviderImpl
bool CurrentThreadIsRenderingThread() override;
void SwitchOutputDevice(const std::string& device_id,
media::OutputDeviceStatusCB callback) override;
+ void TaintOrigin();
// These methods allow a client to get a copy of the rendered audio.
void SetCopyAudioCallback(CopyAudioCB callback);
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc b/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc
index 48092cc09148886bf74e544f640fb373bb374102..2ffaca2d399daba2d59f6dd218ce84e5b9c6d880 100644
--- a/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc
+++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc
@@ -102,7 +102,7 @@ class HTMLAudioElementCapturerSourceTest : public testing::Test {
media_stream_component_ = MakeGarbageCollected<MediaStreamComponent>(
media_stream_source_->Id(), media_stream_source_);
- // |media_stream_source_| takes wnership of
+ // |media_stream_source_| takes ownership of
// HtmlAudioElementCapturerSource.
auto capture_source = std::make_unique<HtmlAudioElementCapturerSource>(
audio_source_, blink::scheduler::GetSingleThreadTaskRunnerForTesting());
@@ -183,4 +183,36 @@ TEST_F(HTMLAudioElementCapturerSourceTest,
track()->RemoveSink(&sink);
}
+TEST_F(HTMLAudioElementCapturerSourceTest, TaintedPlayerDeliversMutedAudio) {
+ testing::InSequence s;
+
+ base::RunLoop run_loop;
+ base::OnceClosure quit_closure = run_loop.QuitClosure();
+
+ MockMediaStreamAudioSink sink;
+ track()->AddSink(&sink);
+ EXPECT_CALL(sink, OnSetFormat(testing::_)).Times(1);
+ EXPECT_CALL(
+ sink,
+ OnData(testing::AllOf(
+ testing::Property(&media::AudioBus::channels,
+ kNumChannelsForTest),
+ testing::Property(&media::AudioBus::frames,
+ kAudioTrackSamplesPerBuffer),
+ testing::Property(&media::AudioBus::AreFramesZero, true)),
+ testing::_))
+ .Times(1)
+ .WillOnce([&](const auto&, auto) { std::move(quit_closure).Run(); });
+
+ audio_source_->TaintOrigin();
+
+ std::unique_ptr<media::AudioBus> bus =
+ media::AudioBus::Create(kNumChannelsForTest, kAudioTrackSamplesPerBuffer);
+ InjectAudio(bus.get());
+ run_loop.Run();
+
+ track()->Stop();
+ track()->RemoveSink(&sink);
+}
+
} // namespace blink
diff --git a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
index a1e014ceb2ebc1496dd5712f2ed863a56e455af6..c54e1768886a7d2d922f13596a9fb3b456ba6611 100644
--- a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
+++ b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
@@ -81,6 +81,10 @@ class WebAudioSourceProviderImpl::TeeFilter
const int num_rendered_frames = renderer_->Render(
delay, delay_timestamp, prior_frames_skipped, audio_bus);
+ // Zero out frames after rendering
+ if (origin_tainted_.IsSet())
+ audio_bus->Zero();
+
// Avoid taking the copy lock for the vast majority of cases.
if (copy_required_) {
base::AutoLock auto_lock(copy_lock_);
@@ -114,11 +118,18 @@ class WebAudioSourceProviderImpl::TeeFilter
copy_audio_bus_callback_ = std::move(callback);
}
+ void TaintOrigin() { origin_tainted_.Set(); }
+
private:
AudioRendererSink::RenderCallback* renderer_ = nullptr;
int channels_ = 0;
int sample_rate_ = 0;
+ // Indicates whether the audio source is tainted, and output should be muted.
+ // This can happen if the media element source is a cross-origin source which
+ // the page is not allowed to access due to CORS restrictions.
+ base::AtomicFlag origin_tainted_;
+
// The vast majority of the time we're operating in passthrough mode. So only
// acquire a lock to read |copy_audio_bus_callback_| when necessary.
std::atomic<bool> copy_required_;
@@ -318,6 +329,10 @@ void WebAudioSourceProviderImpl::SwitchOutputDevice(
sink_->SwitchOutputDevice(device_id, std::move(callback));
}
+void WebAudioSourceProviderImpl::TaintOrigin() {
+ tee_filter_->TaintOrigin();
+}
+
void WebAudioSourceProviderImpl::SetCopyAudioCallback(CopyAudioCB callback) {
DCHECK(!callback.is_null());
tee_filter_->SetCopyAudioCallback(std::move(callback));

View File

@@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Adrian Taylor <adetaylor@chromium.org>
Date: Thu, 5 Nov 2020 08:50:39 +0000
Subject: Prevent overflow of drag image on Windows.
(cherry picked from commit 236b1a349111fc945c741f85e1b1e2e04d9c42ff)
(cherry picked from commit 5f61af8f3af5efd0d915a51da6df822678d959b9)
Bug: 1144489
Change-Id: I130adffc1c69073295537aaff3ce7054260064fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2513345
Reviewed-by: Krishna Govind <govind@chromium.org>
Cr-Original-Original-Commit-Position: refs/branch-heads/4310@{#4}
Cr-Original-Original-Branched-From: 3e31ebb7467fdc4295f123385825b8c95ef13332-refs/heads/master@{#822916}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2513349
Reviewed-by: Adrian Taylor <adetaylor@chromium.org>
Commit-Queue: Krishna Govind <govind@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4240@{#1373}
Cr-Original-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2517728
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/4240_112@{#18}
Cr-Branched-From: 427c00d3874b6abcf4c4c2719768835fc3ef26d6-refs/branch-heads/4240@{#1291}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/ui/base/dragdrop/os_exchange_data_provider_win.cc b/ui/base/dragdrop/os_exchange_data_provider_win.cc
index b51a0161fdf028ac2a4f079b813d6622602f980c..41f163a3424e89a9370faebb77ac0058da9b01f6 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_win.cc
+++ b/ui/base/dragdrop/os_exchange_data_provider_win.cc
@@ -714,7 +714,7 @@ void OSExchangeDataProviderWin::SetDragImage(
int width = unpremul_bitmap.width();
int height = unpremul_bitmap.height();
size_t rowbytes = unpremul_bitmap.rowBytes();
- DCHECK_EQ(rowbytes, static_cast<size_t>(width) * 4u);
+ CHECK_EQ(rowbytes, static_cast<size_t>(width) * 4u);
void* bits;
HBITMAP hbitmap;

View File

@@ -0,0 +1,81 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Cheng <dcheng@chromium.org>
Date: Sat, 7 Nov 2020 19:07:34 +0000
Subject: Prevent UB if a WeakPtr to an already-destroyed object is
dereferenced.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If a WeakPtr references an already-destroyed object, operator-> and
operator* end up simply dereferencing nullptr. However, dereferencing
nullptr is undefined behavior and can be optimized in surprising ways
by compilers. To prevent this from happening, add a defence of last
resort and CHECK that the WeakPtr is still valid.
(cherry picked from commit 0b308a0e37b9d14a335c3b487511b7117c98d74b)
Bug: 817982
Change-Id: Ib3a025c18fbd9d5db88770fced2063135086847b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2463857
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Wez <wez@chromium.org>
Reviewed-by: Jan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#816701}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2524521
Reviewed-by: Adrian Taylor <adetaylor@chromium.org>
Reviewed-by: Krishna Govind <govind@chromium.org>
Commit-Queue: Krishna Govind <govind@chromium.org>
Commit-Queue: Adrian Taylor <adetaylor@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1410}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/base/memory/weak_ptr.h b/base/memory/weak_ptr.h
index 42aa3412c5ed13c8cdf94584e65e2549548ed125..63508a6043dd55572f0683681f01b238751c360f 100644
--- a/base/memory/weak_ptr.h
+++ b/base/memory/weak_ptr.h
@@ -248,11 +248,11 @@ class WeakPtr : public internal::WeakPtrBase {
}
T& operator*() const {
- DCHECK(get() != nullptr);
+ CHECK(ref_.IsValid());
return *get();
}
T* operator->() const {
- DCHECK(get() != nullptr);
+ CHECK(ref_.IsValid());
return get();
}
diff --git a/base/memory/weak_ptr_unittest.cc b/base/memory/weak_ptr_unittest.cc
index 6b1e9bf3c50d3da276c0d9d9de5322355719a61e..6425a88a36f716c58951f0bd52ef1979f598e895 100644
--- a/base/memory/weak_ptr_unittest.cc
+++ b/base/memory/weak_ptr_unittest.cc
@@ -798,4 +798,26 @@ TEST(WeakPtrDeathTest, NonOwnerThreadReferencesObjectAfterDeletion) {
ASSERT_DCHECK_DEATH(arrow.target.get());
}
+TEST(WeakPtrDeathTest, ArrowOperatorChecksOnBadDereference) {
+ // The default style "fast" does not support multi-threaded tests
+ // (introduces deadlock on Linux).
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+
+ auto target = std::make_unique<Target>();
+ WeakPtr<Target> weak = target->AsWeakPtr();
+ target.reset();
+ EXPECT_CHECK_DEATH(weak->AsWeakPtr());
+}
+
+TEST(WeakPtrDeathTest, StarOperatorChecksOnBadDereference) {
+ // The default style "fast" does not support multi-threaded tests
+ // (introduces deadlock on Linux).
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+
+ auto target = std::make_unique<Target>();
+ WeakPtr<Target> weak = target->AsWeakPtr();
+ target.reset();
+ EXPECT_CHECK_DEATH((*weak).AsWeakPtr());
+}
+
} // namespace base

View File

@@ -0,0 +1,187 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Adam Rice <ricea@chromium.org>
Date: Wed, 2 Dec 2020 20:26:52 +0000
Subject: Add ports 5060 and 5061 to the restricted list
Some NAT devices examine traffic on port 5060 to look for a valid SIP
message. If they find one, they will forward a port back to the origin
host. A carefully crafted HTTP request can trick these NAT devices into
forwarding an arbitrary port. See https://samy.pl/slipstream for more
details on the attack and sample code.
Block port 5060 for HTTP. Out of an abundance of caution, and to match
the Fetch standard (https://github.com/whatwg/fetch/pull/1109), also
block port 5061 (SIP over TLS).
Also reduce the whitespace before protocol description comments. This
was insisted on by clang-format and is not worth fighting.
BUG=1145680
(cherry picked from commit 90d1302aec437166b383eabc08af741bf24f7ea8)
(cherry picked from commit dbb0452e69a49e803e0e4cbb6921d5ccad338716)
Change-Id: I3a556fbbb4dc6099caa4418addaf1e89bf254ae3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2519174
Reviewed-by: Matt Menke <mmenke@chromium.org>
Commit-Queue: Adam Rice <ricea@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#824254}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2525474
Reviewed-by: Adam Rice <ricea@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4280@{#1247}
Cr-Original-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2560585
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1474}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/net/base/port_util.cc b/net/base/port_util.cc
index a10a4b4038171b317a2a9ae6cd42aeb1166f5552..72af86dd6acf2db65a14b2f1bb2e3a241a1d043d 100644
--- a/net/base/port_util.cc
+++ b/net/base/port_util.cc
@@ -20,73 +20,75 @@ namespace {
// The general list of blocked ports. Will be blocked unless a specific
// protocol overrides it. (Ex: ftp can use ports 20 and 21)
const int kRestrictedPorts[] = {
- 1, // tcpmux
- 7, // echo
- 9, // discard
- 11, // systat
- 13, // daytime
- 15, // netstat
- 17, // qotd
- 19, // chargen
- 20, // ftp data
- 21, // ftp access
- 22, // ssh
- 23, // telnet
- 25, // smtp
- 37, // time
- 42, // name
- 43, // nicname
- 53, // domain
- 77, // priv-rjs
- 79, // finger
- 87, // ttylink
- 95, // supdup
- 101, // hostriame
- 102, // iso-tsap
- 103, // gppitnp
- 104, // acr-nema
- 109, // pop2
- 110, // pop3
- 111, // sunrpc
- 113, // auth
- 115, // sftp
- 117, // uucp-path
- 119, // nntp
- 123, // NTP
- 135, // loc-srv /epmap
- 139, // netbios
- 143, // imap2
- 179, // BGP
- 389, // ldap
- 427, // SLP (Also used by Apple Filing Protocol)
- 465, // smtp+ssl
- 512, // print / exec
- 513, // login
- 514, // shell
- 515, // printer
- 526, // tempo
- 530, // courier
- 531, // chat
- 532, // netnews
- 540, // uucp
- 548, // AFP (Apple Filing Protocol)
- 556, // remotefs
- 563, // nntp+ssl
- 587, // smtp (rfc6409)
- 601, // syslog-conn (rfc3195)
- 636, // ldap+ssl
- 993, // ldap+ssl
- 995, // pop3+ssl
- 2049, // nfs
- 3659, // apple-sasl / PasswordServer
- 4045, // lockd
- 6000, // X11
- 6665, // Alternate IRC [Apple addition]
- 6666, // Alternate IRC [Apple addition]
- 6667, // Standard IRC [Apple addition]
- 6668, // Alternate IRC [Apple addition]
- 6669, // Alternate IRC [Apple addition]
- 6697, // IRC + TLS
+ 1, // tcpmux
+ 7, // echo
+ 9, // discard
+ 11, // systat
+ 13, // daytime
+ 15, // netstat
+ 17, // qotd
+ 19, // chargen
+ 20, // ftp data
+ 21, // ftp access
+ 22, // ssh
+ 23, // telnet
+ 25, // smtp
+ 37, // time
+ 42, // name
+ 43, // nicname
+ 53, // domain
+ 77, // priv-rjs
+ 79, // finger
+ 87, // ttylink
+ 95, // supdup
+ 101, // hostriame
+ 102, // iso-tsap
+ 103, // gppitnp
+ 104, // acr-nema
+ 109, // pop2
+ 110, // pop3
+ 111, // sunrpc
+ 113, // auth
+ 115, // sftp
+ 117, // uucp-path
+ 119, // nntp
+ 123, // NTP
+ 135, // loc-srv /epmap
+ 139, // netbios
+ 143, // imap2
+ 179, // BGP
+ 389, // ldap
+ 427, // SLP (Also used by Apple Filing Protocol)
+ 465, // smtp+ssl
+ 512, // print / exec
+ 513, // login
+ 514, // shell
+ 515, // printer
+ 526, // tempo
+ 530, // courier
+ 531, // chat
+ 532, // netnews
+ 540, // uucp
+ 548, // AFP (Apple Filing Protocol)
+ 556, // remotefs
+ 563, // nntp+ssl
+ 587, // smtp (rfc6409)
+ 601, // syslog-conn (rfc3195)
+ 636, // ldap+ssl
+ 993, // ldap+ssl
+ 995, // pop3+ssl
+ 2049, // nfs
+ 3659, // apple-sasl / PasswordServer
+ 4045, // lockd
+ 5060, // sip
+ 5061, // sips
+ 6000, // X11
+ 6665, // Alternate IRC [Apple addition]
+ 6666, // Alternate IRC [Apple addition]
+ 6667, // Standard IRC [Apple addition]
+ 6668, // Alternate IRC [Apple addition]
+ 6669, // Alternate IRC [Apple addition]
+ 6697, // IRC + TLS
};
// FTP overrides the following restricted port.

View File

@@ -0,0 +1,132 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Xianzhu Wang <wangxianzhu@chromium.org>
Date: Mon, 16 Nov 2020 17:26:33 +0000
Subject: Ensure change type for OverflowControlsClip is returned
This at least ensures that we will update the paint properites for the
composited overflow control layers in pre-CompositeAfterPaint to avoid
stale properties on the layers.
The test doesn't actually reproduce the bug because any test simpler
than the bug case couldn't reproduce the bug as the update would be
triggered in other code paths (any style change, layout change, etc.).
Anyway this CL does fix the bug case.
TBR=wangxianzhu@chromium.org
(cherry picked from commit c20bb9897ef6d26a46391a4dc1658c5d33e0c100)
(cherry picked from commit cfb81e677a508871f56d8bec958d0b585298ae0c)
Bug: 1137603
Change-Id: I5cca970bcf8cda6085527f79a97f269c4e3e9986
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2500264
Reviewed-by: Stefan Zager <szager@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#820986}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2536910
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4240@{#1446}
Cr-Original-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2540592
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Jana Grill <janagrill@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240_112@{#26}
Cr-Branched-From: 427c00d3874b6abcf4c4c2719768835fc3ef26d6-refs/branch-heads/4240@{#1291}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc
index e991dfac93cfa90f46b92e00c4f29318736bc7ba..b42f1d6bd9b04f293034ee97c8eaa7aa10390ac9 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater_test.cc
@@ -174,4 +174,56 @@ TEST_F(CompositingLayerPropertyUpdaterTest,
}
}
+TEST_F(CompositingLayerPropertyUpdaterTest, OverflowControlsClip) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ ::-webkit-scrollbar { width: 20px; }
+ #container {
+ width: 5px;
+ height: 100px;
+ }
+ #target {
+ overflow: scroll;
+ will-change: transform;
+ width: 100%;
+ height: 100%;
+ }
+ </style>
+ <div id="container">
+ <div id="target"></div>
+ </div>
+ )HTML");
+
+ // Initially the vertical scrollbar overflows the narrow border box.
+ auto* container = GetDocument().getElementById("container");
+ auto* target = ToLayoutBox(GetLayoutObjectByElementId("target"));
+ auto* scrollbar_layer =
+ target->GetScrollableArea()->GraphicsLayerForVerticalScrollbar();
+ auto target_state = target->FirstFragment().LocalBorderBoxProperties();
+ auto scrollbar_state = target_state;
+ auto* overflow_controls_clip =
+ target->FirstFragment().PaintProperties()->OverflowControlsClip();
+ ASSERT_TRUE(overflow_controls_clip);
+ scrollbar_state.SetClip(*overflow_controls_clip);
+ EXPECT_EQ(scrollbar_state, scrollbar_layer->GetPropertyTreeState());
+
+ // Widen target to make the vertical scrollbar contained by the border box.
+ container->setAttribute(html_names::kStyleAttr, "width: 100px");
+ UpdateAllLifecyclePhasesForTest();
+ LOG(ERROR) << target->Size();
+ EXPECT_FALSE(
+ target->FirstFragment().PaintProperties()->OverflowControlsClip());
+ EXPECT_EQ(target_state, scrollbar_layer->GetPropertyTreeState());
+
+ // Narrow down target back.
+ container->removeAttribute(html_names::kStyleAttr);
+ UpdateAllLifecyclePhasesForTest();
+ scrollbar_state = target_state;
+ overflow_controls_clip =
+ target->FirstFragment().PaintProperties()->OverflowControlsClip();
+ ASSERT_TRUE(overflow_controls_clip);
+ scrollbar_state.SetClip(*overflow_controls_clip);
+ EXPECT_EQ(scrollbar_state, scrollbar_layer->GetPropertyTreeState());
+}
+
} // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index 0702a0fc65a69ab1da2cceeb4e6dcb9be30c8d3b..527024f5b1e9c71d7ad5311805c81c3587a7dc32 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -1554,21 +1554,21 @@ void FragmentPaintPropertyTreeBuilder::UpdateOverflowControlsClip() {
if (NeedsOverflowControlsClip()) {
// Clip overflow controls to the border box rect. Not wrapped with
- // OnUpdateClip() because this clip doesn't affect descendants.
+ // OnUpdateClip() because this clip doesn't affect descendants. Wrap with
+ // OnUpdate() to let PrePaintTreeWalk see the change. This may cause
+ // unnecessary subtree update, but is not a big deal because it is rare.
const auto& clip_rect = PhysicalRect(context_.current.paint_offset,
ToLayoutBox(object_).Size());
- properties_->UpdateOverflowControlsClip(
+ OnUpdate(properties_->UpdateOverflowControlsClip(
*context_.current.clip,
ClipPaintPropertyNode::State(context_.current.transform,
FloatRoundedRect(FloatRect(clip_rect)),
- ToSnappedClipRect(clip_rect)));
+ ToSnappedClipRect(clip_rect))));
} else {
- properties_->ClearOverflowControlsClip();
+ OnClear(properties_->ClearOverflowControlsClip());
}
- // No need to set force_subtree_update_reasons and clip_changed because
- // OverflowControlsClip applies to overflow controls only, not descendants.
- // We also don't walk into custom scrollbars in PrePaintTreeWalk and
+ // We don't walk into custom scrollbars in PrePaintTreeWalk because
// LayoutObjects under custom scrollbars don't support paint properties.
}

View File

@@ -0,0 +1,70 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Etienne Bergeron <etienneb@chromium.org>
Date: Fri, 13 Nov 2020 17:40:59 +0000
Subject: Fix text eliding for single-codepoint text with BiDi
This CL is fixing a corner case where RenderText::Elide(...) may
produce a text with more codepoints than the original one. This is
an issue since the breaklists are not resized and the overflow
will lead the render_text code to perfoarm an out-of-bound memory
access by deferencing breaks_.end() while rendering the text. This
is causing chrome to crash.
See crbug/1142020 for details.
The bug was happening when:
1) The text to elide was a single codepoint
2) The width of the glyph of the codepoint is larger than the width
of the ellipsis glyph
3) Eliding is set to ELIDING_TAIL
4) The display_rect width will trigger eliding
(smaller than codepoint width, but larger than ellipsis width)
5) The render text is set to RTL
A possible solution is to adjust the breaklist but this required
larger refactoring and cannot be a minimal patch to be merge on
other channels.
TBR=msw@chromium.org
(cherry picked from commit e54920751871321474e0b953329c8aedcc8702c3)
Bug: 1142020
Change-Id: I9854651175562ec5f0d0bf7083a8da99fede0e29
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2522892
Commit-Queue: Etienne Bergeron <etienneb@chromium.org>
Reviewed-by: Michael Wasserman <msw@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#824878}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2537931
Reviewed-by: Etienne Bergeron <etienneb@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1450}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index 383943809398a59380518f00d84275f493f008c3..2887ea638e3843e61ca2a2935f52d08fe2bbe45e 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -2060,8 +2060,10 @@ base::string16 RenderText::Elide(const base::string16& text,
}
// Append the ellipsis and the optional directional marker characters.
+ // Do not append the BiDi marker if the only codepoint in the text is
+ // an ellipsis.
new_text.append(ellipsis);
- if (trailing_text_direction != text_direction) {
+ if (new_text.size() != 1 && trailing_text_direction != text_direction) {
if (trailing_text_direction == base::i18n::LEFT_TO_RIGHT)
new_text += base::i18n::kLeftToRightMark;
else
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
index 2fd63b1b75fc0fdec9772a9d6b74a13423bf7221..42827f318c8b1896c021f30895072e1add742d32 100644
--- a/ui/gfx/render_text_unittest.cc
+++ b/ui/gfx/render_text_unittest.cc
@@ -1901,7 +1901,7 @@ const ElideTextCase kElideTailTextCases[] = {
{"ltr_0", L"abc", L""},
{"rtl_3", L"\u05d0\u05d1\u05d2", L"\u05d0\u05d1\u05d2"},
{"rtl_2", L"\u05d0\u05d1\u05d2", L"\u05d0\u2026"},
- {"rtl_1", L"\u05d0\u05d1\u05d2", L"\u2026\x200E"},
+ {"rtl_1", L"\u05d0\u05d1\u05d2", L"\u2026"},
{"rtl_0", L"\u05d0\u05d1\u05d2", L""},
{"ltr_rtl_5", L"abc\u05d0\u05d1\u05d2", L"abc\u05d0\u2026\x200F"},
{"ltr_rtl_4", L"abc\u05d0\u05d1\u05d2", L"abc\u2026"},

View File

@@ -0,0 +1,77 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bill Budge <bbudge@chromium.org>
Date: Fri, 13 Nov 2020 09:02:09 +0000
Subject: Merged: [wasm][code cache] Match response to cached raw resource
- Verifies that the retrieved resource has the same response time, and
that the source matches (i.e. both are from service worker, or both
are not).
Bug: chromium:1146673
(cherry picked from commit a8b46244ecaa1647ee2d70304878c0365ee04087)
Change-Id: I6243ec9017b2405687056aa6ea199c67b1c16063
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2526802
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Commit-Queue: Bill Budge <bbudge@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#826277}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2537531
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Auto-Submit: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1447}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc b/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc
index 1010b8be1364fc500b1bb20338e8959d683df5e8..0fffec5084a09cb1af18e619cbad7cc1dd73c447 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc
@@ -210,7 +210,8 @@ class ExceptionToAbortStreamingScope {
};
RawResource* GetRawResource(ScriptState* script_state,
- const String& url_string) {
+ const String& url_string,
+ Response* response) {
ExecutionContext* execution_context = ExecutionContext::From(script_state);
if (!execution_context)
return nullptr;
@@ -224,6 +225,18 @@ RawResource* GetRawResource(ScriptState* script_state,
if (!resource)
return nullptr;
+ // Make sure the resource matches the |response|. To check that, we make sure
+ // the response times match, and the response sources match.
+ const ResourceResponse& resource_response = resource->GetResponse();
+ const FetchResponseData* fetch_response_data =
+ response->GetResponse()->InternalResponse();
+ if (resource_response.ResponseTime() != fetch_response_data->ResponseTime())
+ return nullptr;
+ bool from_service_worker = fetch_response_data->ResponseSource() ==
+ network::mojom::FetchResponseSource::kUnspecified;
+ if (resource_response.WasFetchedViaServiceWorker() != from_service_worker)
+ return nullptr;
+
// Wasm modules should be fetched as raw resources.
DCHECK_EQ(ResourceType::kRaw, resource->GetType());
return ToRawResource(resource);
@@ -347,13 +360,12 @@ void StreamFromResponseCallback(
String url = response->url();
const std::string& url_utf8 = url.Utf8();
streaming->SetUrl(url_utf8.c_str(), url_utf8.size());
- RawResource* raw_resource = GetRawResource(script_state, url);
- if (raw_resource) {
- SingleCachedMetadataHandler* cache_handler =
- raw_resource->ScriptCacheHandler();
+ RawResource* resource = GetRawResource(script_state, url, response);
+ if (resource) {
+ SingleCachedMetadataHandler* cache_handler = resource->ScriptCacheHandler();
if (cache_handler) {
auto client = std::make_shared<WasmStreamingClient>(
- url, raw_resource->GetResponse().ResponseTime());
+ url, resource->GetResponse().ResponseTime());
streaming->SetClient(client);
scoped_refptr<CachedMetadata> cached_module =
cache_handler->GetCachedMetadata(kWasmModuleTag);

View File

@@ -0,0 +1,155 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Stephen Chenney <schenney@chromium.org>
Date: Wed, 14 Oct 2020 02:52:47 +0000
Subject: Implement WebGL image-orientation
M-86 merge.
When creating textures for WebGL, always orient images
with EXIF orientation data.
This change also corrects the transposed size reported by
ImageBitmap. And it removes superfluous arguments from
CopyImageData.
(cherry picked from commit f373458c504c2d115c42f31b29ff5c19674acbbc)
Bug: 1100470, 1125337
Change-Id: I79aa798327a3582939aa574723926b3325c80e7c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2459400
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Commit-Queue: Stephen Chenney <schenney@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#815359}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2469776
Reviewed-by: Stephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1237}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
index b1cdb23186256ca2b4082d2acf556d98c910f145..3e2b5373fdba7bcd0abe866644e17fcb3cee167e 100644
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
@@ -189,14 +189,16 @@ SkImageInfo GetSkImageInfo(const scoped_refptr<Image>& input) {
// This function results in a readback due to using SkImage::readPixels().
// Returns transparent black pixels if the input SkImageInfo.bounds() does
-// not intersect with the input image boundaries.
+// not intersect with the input image boundaries. When apply_orientation
+// is true this method will orient the data according to the source's EXIF
+// information.
Vector<uint8_t> CopyImageData(const scoped_refptr<StaticBitmapImage>& input,
const SkImageInfo& info,
- const unsigned x = 0,
- const unsigned y = 0) {
+ bool apply_orientation = true) {
if (info.isEmpty())
return {};
- sk_sp<SkImage> sk_image = input->PaintImageForCurrentFrame().GetSkImage();
+ PaintImage paint_image = input->PaintImageForCurrentFrame();
+ sk_sp<SkImage> sk_image = paint_image.GetSkImage();
if (sk_image->bounds().isEmpty())
return {};
@@ -205,16 +207,30 @@ Vector<uint8_t> CopyImageData(const scoped_refptr<StaticBitmapImage>& input,
Vector<uint8_t> dst_buffer(byte_length);
bool read_pixels_successful =
- sk_image->readPixels(info, dst_buffer.data(), info.minRowBytes(), x, y);
+ sk_image->readPixels(info, dst_buffer.data(), info.minRowBytes(), 0, 0);
DCHECK(read_pixels_successful);
if (!read_pixels_successful)
return {};
+
+ // Orient the data, and re-read the pixels.
+ if (apply_orientation && !input->HasDefaultOrientation()) {
+ paint_image = Image::ResizeAndOrientImage(
+ paint_image, input->CurrentFrameOrientation(), FloatSize(1, 1), 1,
+ kInterpolationNone);
+ sk_image = paint_image.GetSkImage();
+ read_pixels_successful = sk_image->readPixels(info, dst_buffer.data(),
+ info.minRowBytes(), 0, 0);
+ DCHECK(read_pixels_successful);
+ if (!read_pixels_successful)
+ return {};
+ }
+
return dst_buffer;
}
Vector<uint8_t> CopyImageData(const scoped_refptr<StaticBitmapImage>& input) {
SkImageInfo info = GetSkImageInfo(input);
- return CopyImageData(std::move(input), info);
+ return CopyImageData(std::move(input), info, false);
}
static inline bool ShouldAvoidPremul(
@@ -1053,12 +1069,13 @@ Vector<uint8_t> ImageBitmap::CopyBitmapData(AlphaDisposition alpha_op,
auto color_type = info.colorType();
if (color_type == kN32_SkColorType && u8_color_type == kRGBAColorType)
color_type = kRGBA_8888_SkColorType;
+ // Note that width() and height() here apply EXIF orientation
info =
SkImageInfo::Make(width(), height(), color_type,
(alpha_op == kPremultiplyAlpha) ? kPremul_SkAlphaType
: kUnpremul_SkAlphaType,
info.refColorSpace());
- return CopyImageData(image_, info);
+ return CopyImageData(image_, info, true);
}
Vector<uint8_t> ImageBitmap::CopyBitmapData() {
@@ -1090,7 +1107,7 @@ IntSize ImageBitmap::Size() const {
return IntSize();
DCHECK_GT(image_->width(), 0);
DCHECK_GT(image_->height(), 0);
- return IntSize(image_->width(), image_->height());
+ return image_->SizeRespectingOrientation();
}
ScriptPromise ImageBitmap::CreateImageBitmap(ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index 457b7c3d2bef75bb378f8dfc5b61b932b6941fb6..d7445bf31a391bea3742327c34dc3eb46c72513b 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -5307,10 +5307,12 @@ void WebGLRenderingContextBase::TexImageHelperHTMLImageElement(
return;
scoped_refptr<Image> image_for_render = image->CachedImage()->GetImage();
- if (IsA<SVGImage>(image_for_render.get())) {
- if (canvas()) {
+ bool have_svg_image = IsA<SVGImage>(image_for_render.get());
+ if (have_svg_image || !image_for_render->HasDefaultOrientation()) {
+ if (have_svg_image && canvas()) {
UseCounter::Count(canvas()->GetDocument(), WebFeature::kSVGInWebGL);
}
+ // DrawImageIntoBuffer always respects orientation
image_for_render =
DrawImageIntoBuffer(std::move(image_for_render), image->width(),
image->height(), func_name);
@@ -5846,6 +5848,7 @@ void WebGLRenderingContextBase::TexImageHelperImageBitmap(
level, internalformat, width, height, depth, 0, format,
type, xoffset, yoffset, zoffset))
return;
+
scoped_refptr<StaticBitmapImage> image = bitmap->BitmapImage();
DCHECK(image);
@@ -5872,9 +5875,16 @@ void WebGLRenderingContextBase::TexImageHelperImageBitmap(
return;
}
+ // Apply orientation if necessary
+ PaintImage paint_image = bitmap->BitmapImage()->PaintImageForCurrentFrame();
+ if (!image->HasDefaultOrientation()) {
+ paint_image = Image::ResizeAndOrientImage(
+ paint_image, image->CurrentFrameOrientation(), FloatSize(1, 1), 1,
+ kInterpolationNone);
+ }
+
// TODO(kbr): refactor this away to use TexImageImpl on image.
- sk_sp<SkImage> sk_image =
- bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage();
+ sk_sp<SkImage> sk_image = paint_image.GetSkImage();
if (!sk_image) {
SynthesizeGLError(GL_OUT_OF_MEMORY, func_name,
"ImageBitmap unexpectedly empty");

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Mon, 5 Oct 2020 13:43:59 -0700
Subject: chore: expose v8 initialization isolate callbacks
This commit is necessary in order to ensure consistent behavior from
v8 Isolate callbacks in contexts which Node.js does not control. If
we're running with contextIsolation enabled, we should be falling back
to Blink's logic. This will be upstreamed in some form.
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
index 21504ce01403d20067c8439c0c61ee0d71de84a5..13855078e4e9531304d30ec46cd2bb79798623ad 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -452,7 +452,7 @@ CodeGenerationCheckCallbackInMainThread(v8::Local<v8::Context> context,
return {true, std::move(stringified_source)};
}
-static bool WasmCodeGenerationCheckCallbackInMainThread(
+bool V8Initializer::WasmCodeGenerationCheckCallbackInMainThread(
v8::Local<v8::Context> context,
v8::Local<v8::String> source) {
if (ExecutionContext* execution_context = ToExecutionContext(context)) {
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.h b/third_party/blink/renderer/bindings/core/v8/v8_initializer.h
index e7cbc5db7d15aa0fcfb37ba261673b973827296a..6b93aa449a005e06862a99ea0c9b751ffff2d6ec 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.h
+++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.h
@@ -67,6 +67,9 @@ class CORE_EXPORT V8Initializer {
v8::Local<v8::Value>);
static void MessageHandlerInWorker(v8::Local<v8::Message>,
v8::Local<v8::Value>);
+ static bool WasmCodeGenerationCheckCallbackInMainThread(
+ v8::Local<v8::Context> context,
+ v8::Local<v8::String> source);
};
} // namespace blink

View File

@@ -0,0 +1,146 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Joshua Peraza <jperaza@chromium.org>
Date: Wed, 21 Oct 2020 11:10:25 -0700
Subject: Initialize logging for crashpad
Although logging to files is not yet supported by mini_chromium, it is
the default behavior for OS_WIN in chromium. This change should
cause crashpad to log via OutputDebugString() on Windows, instead of
debug.log files. Future work (crbug.com/crashpad/26) should arrange for
logs to be uploaded with reports, embedded in associated minidumps or as
file attachments.
Bug: chromium:711159
Change-Id: I0f9004f7de94dd29d555cc7d23c48a63da6b4bba
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2425108
Reviewed-by: Mark Mentovai <mark@chromium.org>
diff --git a/base/logging.cc b/base/logging.cc
index 2da71c73819b34a45911131e2cc8bff861178789..6b701b7a8dee0d015758e11771c5c1f3a6b8d13b 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -421,21 +421,23 @@ bool BaseInitLoggingImpl(const LoggingSettings& settings) {
0u);
#endif
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- // Don't bother initializing |g_vlog_info| unless we use one of the
- // vlog switches.
- if (command_line->HasSwitch(switches::kV) ||
- command_line->HasSwitch(switches::kVModule)) {
- // NOTE: If |g_vlog_info| has already been initialized, it might be in use
- // by another thread. Don't delete the old VLogInfo, just create a second
- // one. We keep track of both to avoid memory leak warnings.
- CHECK(!g_vlog_info_prev);
- g_vlog_info_prev = g_vlog_info;
-
- g_vlog_info =
- new VlogInfo(command_line->GetSwitchValueASCII(switches::kV),
- command_line->GetSwitchValueASCII(switches::kVModule),
- &g_min_log_level);
+ if (base::CommandLine::InitializedForCurrentProcess()) {
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ // Don't bother initializing |g_vlog_info| unless we use one of the
+ // vlog switches.
+ if (command_line->HasSwitch(switches::kV) ||
+ command_line->HasSwitch(switches::kVModule)) {
+ // NOTE: If |g_vlog_info| has already been initialized, it might be in use
+ // by another thread. Don't delete the old VLogInfo, just create a second
+ // one. We keep track of both to avoid memory leak warnings.
+ CHECK(!g_vlog_info_prev);
+ g_vlog_info_prev = g_vlog_info;
+
+ g_vlog_info =
+ new VlogInfo(command_line->GetSwitchValueASCII(switches::kV),
+ command_line->GetSwitchValueASCII(switches::kVModule),
+ &g_min_log_level);
+ }
}
g_logging_destination = settings.logging_dest;
@@ -446,7 +448,10 @@ bool BaseInitLoggingImpl(const LoggingSettings& settings) {
config.min_severity = FX_LOG_INFO;
config.console_fd = -1;
config.log_service_channel = ZX_HANDLE_INVALID;
- std::string log_tag = command_line->GetProgram().BaseName().AsUTF8Unsafe();
+ std::string log_tag = base::CommandLine::ForCurrentProcess()
+ ->GetProgram()
+ .BaseName()
+ .AsUTF8Unsafe();
const char* log_tag_data = log_tag.data();
config.tags = &log_tag_data;
config.num_tags = 1;
diff --git a/third_party/crashpad/crashpad/DEPS b/third_party/crashpad/crashpad/DEPS
index ccb447cde9a9ee3c1fe29419abfa8aa63d777455..6ee9db5400cf12ae4812a261e78234581b036c25 100644
--- a/third_party/crashpad/crashpad/DEPS
+++ b/third_party/crashpad/crashpad/DEPS
@@ -42,7 +42,7 @@ deps = {
'7bde79cc274d06451bf65ae82c012a5d3e476b5a',
'crashpad/third_party/mini_chromium/mini_chromium':
Var('chromium_git') + '/chromium/mini_chromium@' +
- 'ae14a14ab4cea36db9c446741581d427a7fc7f89',
+ '5fc64bfbf1c000161445c586de45e40464ff2314',
'crashpad/third_party/libfuzzer/src':
Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' +
'fda403cf93ecb8792cb1d061564d89a6553ca020',
diff --git a/third_party/crashpad/crashpad/handler/handler_main.cc b/third_party/crashpad/crashpad/handler/handler_main.cc
index d56857ff9042a0e4ed55bb101e419948f4028305..579a7c364077d2b6a78803fa75f7180109b37c89 100644
--- a/third_party/crashpad/crashpad/handler/handler_main.cc
+++ b/third_party/crashpad/crashpad/handler/handler_main.cc
@@ -494,16 +494,26 @@ class ScopedStoppable {
DISALLOW_COPY_AND_ASSIGN(ScopedStoppable);
};
+void InitCrashpadLogging() {
+ logging::LoggingSettings settings;
+#if defined(OS_CHROMEOS)
+ settings.logging_dest = logging::LOG_TO_FILE;
+ settings.log_file_path = "/var/log/chrome/chrome";
+#elif defined(OS_WIN)
+ settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
+#else
+ settings.logging_dest =
+ logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR;
+#endif
+ logging::InitLogging(settings);
+}
+
} // namespace
int HandlerMain(int argc,
char* argv[],
const UserStreamDataSources* user_stream_sources) {
-#if defined(OS_CHROMEOS)
- if (freopen("/var/log/chrome/chrome", "a", stderr) == nullptr) {
- PLOG(ERROR) << "Failed to redirect stderr to /var/log/chrome/chrome";
- }
-#endif
+ InitCrashpadLogging();
InstallCrashHandler();
CallMetricsRecordNormalExit metrics_record_normal_exit;
diff --git a/third_party/crashpad/crashpad/test/gtest_main.cc b/third_party/crashpad/crashpad/test/gtest_main.cc
index 67cfa0d72d7eb469775201f3a9df906f27c302a9..c67b8e24bb940935d5da88428ed3058a135f5a57 100644
--- a/third_party/crashpad/crashpad/test/gtest_main.cc
+++ b/third_party/crashpad/crashpad/test/gtest_main.cc
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "base/logging.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/main_arguments.h"
@@ -99,6 +100,12 @@ int main(int argc, char* argv[]) {
#endif // CRASHPAD_IS_IN_CHROMIUM
+ // base::TestSuite initializes logging when using Chromium's test launcher.
+ logging::LoggingSettings settings;
+ settings.logging_dest =
+ logging::LOG_TO_STDERR | logging::LOG_TO_SYSTEM_DEBUG_LOG;
+ logging::InitLogging(settings);
+
#if defined(CRASHPAD_TEST_LAUNCHER_GOOGLEMOCK)
testing::InitGoogleMock(&argc, argv);
#elif defined(CRASHPAD_TEST_LAUNCHER_GOOGLETEST)

View File

@@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Biru Mohanathas <birunthan@mohanathas.com>
Date: Thu, 10 Dec 2020 19:02:37 +0200
Subject: fix crash in NativeViewHost::SetParentAccessible
This fixes random crashes on Windows 10. It presumably started happening
after the changes in
https://chromium.googlesource.com/chromium/src.git/+/5c6c8e994bce2bfb867279ae5068e9f9134e70c3%5E!/#F15
For context, see: https://github.com/electron/electron/issues/26905
This patch can likely be upstreamed. The crash cannot be fixed without
patching something in Chromium - this is the least invasive change.
diff --git a/ui/views/controls/native/native_view_host.cc b/ui/views/controls/native/native_view_host.cc
index 4779e4f07d923b5af9ba05c2765cf294e75dcc14..6112217d532251f7f6850c23be5c312a908df1e2 100644
--- a/ui/views/controls/native/native_view_host.cc
+++ b/ui/views/controls/native/native_view_host.cc
@@ -54,6 +54,9 @@ void NativeViewHost::Detach() {
}
void NativeViewHost::SetParentAccessible(gfx::NativeViewAccessible accessible) {
+ if (!native_wrapper_.get())
+ return;
+
native_wrapper_->SetParentAccessible(accessible);
}

View File

@@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Thu, 24 Sep 2020 11:10:41 -0700
Subject: fix: use electron generated resources
This patch fixes a few instances where we need to use Electron generated
resources for IDS strings, or the IDs will be wrong and cause DCHECKS
as they will loaded as empty strings.
* IDS_UTILITY_PROCESS_UTILITY_WIN_NAME on Windows
* IDR_PDF_MANIFEST on Linux
* IDS_UTILITY_PROCESS_PRINTING_SERVICE_NAME on Windows
diff --git a/chrome/browser/pdf/pdf_extension_util.cc b/chrome/browser/pdf/pdf_extension_util.cc
index 9fd9791fd923d6c5e741cb7dc064ababf9a7995a..0a5534f2f09224196971076794daa3c805c91606 100644
--- a/chrome/browser/pdf/pdf_extension_util.cc
+++ b/chrome/browser/pdf/pdf_extension_util.cc
@@ -8,7 +8,7 @@
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/chrome_content_client.h"
-#include "chrome/grit/browser_resources.h"
+#include "electron/grit/electron_resources.h"
#include "components/strings/grit/components_strings.h"
#include "components/zoom/page_zoom_constants.h"
#include "pdf/pdf_features.h"
diff --git a/chrome/browser/printing/printing_service.cc b/chrome/browser/printing/printing_service.cc
index 2b73b110049b5e8d28b52656bbd2423e18ba07a0..8fd868b39d64c74aa189b8ca3e24c8537d91b1ba 100644
--- a/chrome/browser/printing/printing_service.cc
+++ b/chrome/browser/printing/printing_service.cc
@@ -6,7 +6,7 @@
#include "base/no_destructor.h"
#include "chrome/browser/service_sandbox_type.h"
-#include "chrome/grit/generated_resources.h"
+#include "electron/grit/electron_resources.h"
#include "content/public/browser/service_process_host.h"
const mojo::Remote<printing::mojom::PrintingService>& GetPrintingService() {
diff --git a/chrome/browser/win/icon_reader_service.cc b/chrome/browser/win/icon_reader_service.cc
index 721e1a863cc6925908f8343002df056f2373bf0b..10b2a95162541a8ff4d010c7be864f3f41dae378 100644
--- a/chrome/browser/win/icon_reader_service.cc
+++ b/chrome/browser/win/icon_reader_service.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/win/icon_reader_service.h"
#include "chrome/browser/service_sandbox_type.h"
-#include "chrome/grit/generated_resources.h"
+#include "electron/grit/electron_resources.h"
#include "content/public/browser/service_process_host.h"
mojo::Remote<chrome::mojom::UtilReadIcon> LaunchIconReaderInstance() {

View File

@@ -0,0 +1,163 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Cheng <dcheng@chromium.org>
Date: Wed, 11 Nov 2020 00:54:41 +0000
Subject: Ignore RenderFrameHostImpl::Detach() for speculative RFHs.
Currently, this all happens to work by chance, because the speculative
RFH or the entire FTN happens to be torn down before the browser process
ever processes a Detach() IPC for a speculative RFH.
However, there are a number of followup CLs that restructure how
provisional RenderFrames are managed and owned in the renderer process.
To simplify those CLs, explicitly branch in Detach() based on whether or
not the RFH is speculative. In the future, additional logic may be added
to the speculative branch (e.g. cancelling the navigation, if
appropriate).
(cherry picked from commit cf054220a2e1570a9149220494de8826c2e9d4db)
Bug: 1146709
Change-Id: I6490a90f7b447422d698676665b52f6f3a6f8ffd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2524280
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Nasko Oskov <nasko@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#825903}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2530189
Reviewed-by: Adrian Taylor <adetaylor@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1430}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index c1d7a3052516c6c8ac5a8e65c9688d04b8edec70..ab54a32a17f29e9b5ea9365e92de563737a1e513 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2625,6 +2625,9 @@ void RenderFrameHostImpl::UpdateRenderProcessHostFramePriorities() {
}
void RenderFrameHostImpl::OnDetach() {
+ if (lifecycle_state() == LifecycleState::kSpeculative)
+ return;
+
if (!parent_) {
bad_message::ReceivedBadMessage(GetProcess(),
bad_message::RFH_DETACH_MAIN_FRAME);
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 7c9902648ab0465f4e0a7b4778b328ad8c1f2fcd..d81076da5ef7701475ef1158b528d02d3992ff0d 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -10333,6 +10333,37 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
EXPECT_EQ("opener-ping-reply", response);
}
+IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
+ DetachSpeculativeRenderFrameHost) {
+ // Commit a page with one iframe.
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(a)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ // Start a cross-site navigation.
+ GURL cross_site_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
+ TestNavigationManager nav_manager(shell()->web_contents(), cross_site_url);
+ BeginNavigateIframeToURL(web_contents(), "child-0", cross_site_url);
+
+ // Wait for the request, but don't commit it yet. This should create a
+ // speculative RenderFrameHost.
+ ASSERT_TRUE(nav_manager.WaitForRequestStart());
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+ RenderFrameHostImpl* speculative_rfh = root->current_frame_host()
+ ->child_at(0)
+ ->render_manager()
+ ->speculative_frame_host();
+ EXPECT_TRUE(speculative_rfh);
+
+ // Currently, the browser process never handles an explicit Detach() for a
+ // speculative RFH, since the speculative RFH or the entire FTN is always
+ // destroyed before the renderer sends this IPC.
+ speculative_rfh->Detach();
+
+ // Passes if there is no crash.
+}
+
+
#if defined(OS_ANDROID)
namespace {
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index cbc62fef825815309f417baee931a6c450500f32..d3fa4eb639f58c6eafe01651e643545897dcabcc 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -603,15 +603,21 @@ bool NavigateToURL(WebContents* web_contents,
bool NavigateIframeToURL(WebContents* web_contents,
const std::string& iframe_id,
const GURL& url) {
+ TestNavigationObserver load_observer(web_contents);
+ bool result = BeginNavigateIframeToURL(web_contents, iframe_id, url);
+ load_observer.Wait();
+ return result;
+}
+
+bool BeginNavigateIframeToURL(WebContents* web_contents,
+ const std::string& iframe_id,
+ const GURL& url) {
std::string script = base::StringPrintf(
"setTimeout(\""
"var iframes = document.getElementById('%s');iframes.src='%s';"
"\",0)",
iframe_id.c_str(), url.spec().c_str());
- TestNavigationObserver load_observer(web_contents);
- bool result = ExecuteScript(web_contents, script);
- load_observer.Wait();
- return result;
+ return ExecuteScript(web_contents, script);
}
void NavigateToURLBlockUntilNavigationsComplete(WebContents* web_contents,
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index 275684ba6cf6b6a9f8e5f5b24951d8fb07969767..bc23592ce9b7eab268465fb0e171e8351aa25549 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -138,6 +138,12 @@ bool NavigateIframeToURL(WebContents* web_contents,
const std::string& iframe_id,
const GURL& url);
+// Similar to |NavigateIframeToURL()| but returns as soon as the navigation is
+// initiated.
+bool BeginNavigateIframeToURL(WebContents* web_contents,
+ const std::string& iframe_id,
+ const GURL& url);
+
// Generate a URL for a file path including a query string.
GURL GetFileUrlWithQuery(const base::FilePath& path,
const std::string& query_string);
diff --git a/content/test/data/cross_site_iframe_factory.html b/content/test/data/cross_site_iframe_factory.html
index 0893a2063585a04520d9bc8f87ee0c1cb726c0d7..78f8126c9cf7f8ae9f2b0d34e17d76ad51784811 100644
--- a/content/test/data/cross_site_iframe_factory.html
+++ b/content/test/data/cross_site_iframe_factory.html
@@ -10,12 +10,12 @@ Example usage in a browsertest, explained:
When you navigate to the above URL, the outer document (on a.com) will create a
single iframe:
- <iframe src="http://b.com:1234/cross_site_iframe_factory.html?b(c(),d())">
+ <iframe id="child-0" src="http://b.com:1234/cross_site_iframe_factory.html?b(c(),d())">
Inside of which, then, are created the two leaf iframes:
- <iframe src="http://c.com:1234/cross_site_iframe_factory.html?c()">
- <iframe src="http://d.com:1234/cross_site_iframe_factory.html?d()">
+ <iframe id="child-0" src="http://c.com:1234/cross_site_iframe_factory.html?c()">
+ <iframe id="child-1" src="http://d.com:1234/cross_site_iframe_factory.html?d()">
Add iframe options by enclosing them in '{' and '}' characters after the
hostname (multiple options can be separated with commas):
@@ -24,8 +24,8 @@ hostname (multiple options can be separated with commas):
Will create two iframes:
- <iframe src="http://a.com:1234/cross_site_iframe_factory.html?b()" allowfullscreen>
- <iframe src="http://c.com:1234/cross_site_iframe_factory.html?c{sandbox-allow-scripts}(d())" sandbox="allow-scripts">
+ <iframe id="child-0" src="http://a.com:1234/cross_site_iframe_factory.html?b()" allowfullscreen>
+ <iframe id="child-1" src="http://c.com:1234/cross_site_iframe_factory.html?c{sandbox-allow-scripts}(d())" sandbox="allow-scripts">
To specify the site for each iframe, you can use a simple identifier like "a"
or "b", and ".com" will be automatically appended. You can also specify a port

View File

@@ -0,0 +1,179 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Fri, 13 Nov 2020 21:06:58 +0000
Subject: Merge M86: "Ensure that buffers used by ImageDecoder haven't been
neutered."
Since JavaScript may detach the underlying buffers, we need to check
to ensure they're still valid before using them for decoding.
TBR=sandersd
(cherry picked from commit fa93fba6a28d384b0a0cddd63e85eb10cb97bb53)
Test: Updated unittests. Manual test case breaks.
Change-Id: Iefe5f8adf619cd6afdfedcb08a13c2996bfe0d32
Fixed: 1146761
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2527542
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Dan Sanders <sandersd@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#825615}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2537781
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1453}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc
index e42ceaf37038b58e53d11bfb63b7a27aa414a87b..780fdbef3afb9cca322002f736fc3d9b87f834b3 100644
--- a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc
+++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc
@@ -99,9 +99,8 @@ ImageDecoderExternal::ImageDecoderExternal(ScriptState* script_state,
return;
}
- // TODO: Data is owned by the caller who may be free to manipulate it. We will
- // probably need to make a copy to our own internal data or neuter the buffers
- // as seen by JS.
+ // Since data is owned by the caller who may be free to manipulate it, we must
+ // check HasValidEncodedData() before attempting to access |decoder_|.
segment_reader_ = SegmentReader::CreateFromSkData(
SkData::MakeWithoutCopy(buffer.Data(), buffer.ByteLengthAsSizeT()));
if (!segment_reader_) {
@@ -206,6 +205,7 @@ void ImageDecoderExternal::Trace(Visitor* visitor) const {
void ImageDecoderExternal::CreateImageDecoder() {
DCHECK(!decoder_);
+ DCHECK(HasValidEncodedData());
// TODO: We should probably call ImageDecoder::SetMemoryAllocator() so that
// we can recycle frame buffers for decoded images.
@@ -260,6 +260,13 @@ void ImageDecoderExternal::MaybeSatisfyPendingDecodes() {
continue;
}
+ if (!HasValidEncodedData()) {
+ request->resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kInvalidStateError,
+ "Source data has been neutered"));
+ continue;
+ }
+
auto* image = decoder_->DecodeFrameBufferAtIndex(request->frame_index);
if (decoder_->Failed() || !image) {
request->complete = true;
@@ -326,6 +333,7 @@ void ImageDecoderExternal::MaybeSatisfyPendingDecodes() {
}
void ImageDecoderExternal::MaybeSatisfyPendingMetadataDecodes() {
+ DCHECK(HasValidEncodedData());
DCHECK(decoder_);
DCHECK(decoder_->Failed() || decoder_->IsDecodedSizeAvailable());
for (auto& resolver : pending_metadata_decodes_)
@@ -334,6 +342,9 @@ void ImageDecoderExternal::MaybeSatisfyPendingMetadataDecodes() {
}
void ImageDecoderExternal::MaybeUpdateMetadata() {
+ if (!HasValidEncodedData())
+ return;
+
const size_t decoded_frame_count = decoder_->FrameCount();
if (decoder_->Failed()) {
MaybeSatisfyPendingMetadataDecodes();
@@ -358,4 +369,22 @@ void ImageDecoderExternal::MaybeUpdateMetadata() {
MaybeSatisfyPendingMetadataDecodes();
}
+bool ImageDecoderExternal::HasValidEncodedData() const {
+ // If we keep an internal copy of the data, it's always valid.
+ if (stream_buffer_)
+ return true;
+
+ if (init_data_->data().IsArrayBuffer() &&
+ init_data_->data().GetAsArrayBuffer()->IsDetached()) {
+ return false;
+ }
+
+ if (init_data_->data().IsArrayBufferView() &&
+ !init_data_->data().GetAsArrayBufferView()->BaseAddress()) {
+ return false;
+ }
+
+ return true;
+}
+
} // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc.rej b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc.rej
new file mode 100644
index 0000000000000000000000000000000000000000..68d0eae0c7cd414f8cbe90aee79417d2a4ffe98b
--- /dev/null
+++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc.rej
@@ -0,0 +1,53 @@
+diff a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc (rejected hunks)
+@@ -120,9 +120,8 @@
+ return;
+ }
+
+- // TODO(crbug.com/1073995): Data is owned by the caller who may be free to
+- // manipulate it. We will probably need to make a copy to our own internal
+- // data or neuter the buffers as seen by JS.
++ // Since data is owned by the caller who may be free to manipulate it, we must
++ // check HasValidEncodedData() before attempting to access |decoder_|.
+ segment_reader_ = SegmentReader::CreateFromSkData(
+ SkData::MakeWithoutCopy(buffer.Data(), buffer.ByteLengthAsSizeT()));
+ if (!segment_reader_) {
+@@ -266,6 +265,7 @@
+
+ void ImageDecoderExternal::CreateImageDecoder() {
+ DCHECK(!decoder_);
++ DCHECK(HasValidEncodedData());
+
+ // TODO(crbug.com/1073995): We should probably call
+ // ImageDecoder::SetMemoryAllocator() so that we can recycle frame buffers for
+@@ -320,6 +320,13 @@
+ continue;
+ }
+
++ if (!HasValidEncodedData()) {
++ request->exception = MakeGarbageCollected<DOMException>(
++ DOMExceptionCode::kInvalidStateError,
++ "Source data has been neutered");
++ continue;
++ }
++
+ auto* image = decoder_->DecodeFrameBufferAtIndex(request->frame_index);
+ if (decoder_->Failed() || !image) {
+ // TODO(crbug.com/1073995): Include frameIndex in rejection?
+@@ -398,6 +405,7 @@
+ }
+
+ void ImageDecoderExternal::MaybeSatisfyPendingMetadataDecodes() {
++ DCHECK(HasValidEncodedData());
+ DCHECK(decoder_);
+ if (!decoder_->IsSizeAvailable() && !decoder_->Failed())
+ return;
+@@ -409,6 +417,9 @@
+ }
+
+ void ImageDecoderExternal::MaybeUpdateMetadata() {
++ if (!HasValidEncodedData())
++ return;
++
+ // Since we always create the decoder at construction, we need to wait until
+ // at least the size is available before signaling that metadata has been
+ // retrieved.
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h
index 1b4ac0ce7eade63c06c1030c29fc90a8551aa7c2..7d9d534ce14d07e49fca99f11297e74b1311363e 100644
--- a/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h
+++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h
@@ -61,6 +61,10 @@ class MODULES_EXPORT ImageDecoderExternal final : public ScriptWrappable,
void MaybeSatisfyPendingMetadataDecodes();
void MaybeUpdateMetadata();
+ // Returns false if the decoder was constructed with an ArrayBuffer or
+ // ArrayBufferView that has since been neutered.
+ bool HasValidEncodedData() const;
+
Member<ScriptState> script_state_;
// Used when a ReadableStream is provided.

View File

@@ -0,0 +1,206 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Mon, 5 Oct 2020 22:14:12 +0000
Subject: Only zero out cross-origin audio that doesn't get played out.
Cross-origin audio is still allowed to play out, it just can't be
captured by the containing page.
Bug: 1128657, 1134679
Test: Unit tests added.
Change-Id: Id4c73e315072b8683e45a2ddf929d534f1da9928
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2450390
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Will Cassella <cassew@google.com>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#813956}
diff --git a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
index c54e1768886a7d2d922f13596a9fb3b456ba6611..5cc64a4ae790f8b0b72520f1b8d2b89617bd22e2 100644
--- a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
+++ b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
@@ -81,10 +81,6 @@ class WebAudioSourceProviderImpl::TeeFilter
const int num_rendered_frames = renderer_->Render(
delay, delay_timestamp, prior_frames_skipped, audio_bus);
- // Zero out frames after rendering
- if (origin_tainted_.IsSet())
- audio_bus->Zero();
-
// Avoid taking the copy lock for the vast majority of cases.
if (copy_required_) {
base::AutoLock auto_lock(copy_lock_);
@@ -93,7 +89,11 @@ class WebAudioSourceProviderImpl::TeeFilter
media::AudioTimestampHelper::TimeToFrames(delay, sample_rate_);
std::unique_ptr<media::AudioBus> bus_copy =
media::AudioBus::Create(audio_bus->channels(), audio_bus->frames());
- audio_bus->CopyTo(bus_copy.get());
+ // Disable copying when origin is tainted.
+ if (origin_tainted_.IsSet())
+ bus_copy->Zero();
+ else
+ audio_bus->CopyTo(bus_copy.get());
copy_audio_bus_callback_.Run(std::move(bus_copy),
static_cast<uint32_t>(frames_delayed),
sample_rate_);
@@ -119,6 +119,7 @@ class WebAudioSourceProviderImpl::TeeFilter
}
void TaintOrigin() { origin_tainted_.Set(); }
+ bool is_tainted() const { return origin_tainted_.IsSet(); }
private:
AudioRendererSink::RenderCallback* renderer_ = nullptr;
@@ -220,6 +221,13 @@ void WebAudioSourceProviderImpl::ProvideInput(
DCHECK_EQ(tee_filter_->channels(), bus_wrapper_->channels());
const int frames = tee_filter_->Render(
base::TimeDelta(), base::TimeTicks::Now(), 0, bus_wrapper_.get());
+
+ // Zero out frames after rendering for tainted origins.
+ if (tee_filter_->is_tainted()) {
+ bus_wrapper_->Zero();
+ return;
+ }
+
if (frames < incoming_number_of_frames)
bus_wrapper_->ZeroFramesPartial(frames, incoming_number_of_frames - frames);
diff --git a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
index 1f0c69d7143c06af3127a3f4b8dea6bd416d949f..db319bcc4f2fce940b5269da994e61a9978772f0 100644
--- a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
+++ b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
@@ -22,6 +22,11 @@ using ::testing::_;
namespace blink {
namespace {
+
+MATCHER(IsMuted, std::string(negation ? "isn't" : "is") + " muted") {
+ return arg->AreFramesZero();
+}
+
const float kTestVolume = 0.25;
const int kTestSampleRate = 48000;
} // namespace
@@ -89,17 +94,10 @@ class WebAudioSourceProviderImplTest : public testing::Test,
// WebAudioSourceProviderClient implementation.
MOCK_METHOD2(SetFormat, void(uint32_t numberOfChannels, float sampleRate));
-
- // CopyAudioCB. Added forwarder method due to GMock troubles with scoped_ptr.
MOCK_METHOD3(DoCopyAudioCB,
- void(media::AudioBus*,
+ void(std::unique_ptr<media::AudioBus> bus,
uint32_t frames_delayed,
int sample_rate));
- void OnAudioBus(std::unique_ptr<media::AudioBus> bus,
- uint32_t frames_delayed,
- int sample_rate) {
- DoCopyAudioCB(bus.get(), frames_delayed, sample_rate);
- }
int Render(media::AudioBus* audio_bus) {
return wasp_impl_->RenderForTesting(audio_bus);
@@ -163,6 +161,35 @@ TEST_F(WebAudioSourceProviderImplTest, SinkMethods) {
CallAllSinkMethodsAndVerify(false);
}
+// Test tainting effects on Render().
+TEST_F(WebAudioSourceProviderImplTest, RenderTainted) {
+ auto bus = media::AudioBus::Create(params_);
+ bus->Zero();
+
+ // Point the WebVector into memory owned by |bus|.
+ WebVector<float*> audio_data(static_cast<size_t>(bus->channels()));
+ for (size_t i = 0; i < audio_data.size(); ++i)
+ audio_data[i] = bus->channel(static_cast<int>(i));
+
+ wasp_impl_->Initialize(params_, &fake_callback_);
+
+ EXPECT_CALL(*mock_sink_, Start());
+ wasp_impl_->Start();
+ EXPECT_CALL(*mock_sink_, Play());
+ wasp_impl_->Play();
+
+ Render(bus.get());
+ ASSERT_FALSE(bus->AreFramesZero());
+
+ // Normal audio output should be unaffected by tainting.
+ wasp_impl_->TaintOrigin();
+ Render(bus.get());
+ ASSERT_FALSE(bus->AreFramesZero());
+
+ EXPECT_CALL(*mock_sink_, Stop());
+ wasp_impl_->Stop();
+}
+
// Test the AudioRendererSink state machine and its effects on provideInput().
TEST_F(WebAudioSourceProviderImplTest, ProvideInput) {
auto bus1 = media::AudioBus::Create(params_);
@@ -249,12 +276,37 @@ TEST_F(WebAudioSourceProviderImplTest, ProvideInput) {
ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get()));
}
+// Test tainting effects on ProvideInput().
+TEST_F(WebAudioSourceProviderImplTest, ProvideInputTainted) {
+ auto bus = media::AudioBus::Create(params_);
+ bus->Zero();
+
+ // Point the WebVector into memory owned by |bus|.
+ WebVector<float*> audio_data(static_cast<size_t>(bus->channels()));
+ for (size_t i = 0; i < audio_data.size(); ++i)
+ audio_data[i] = bus->channel(static_cast<int>(i));
+
+ wasp_impl_->Initialize(params_, &fake_callback_);
+ SetClient(this);
+
+ wasp_impl_->Start();
+ wasp_impl_->Play();
+ wasp_impl_->ProvideInput(audio_data, params_.frames_per_buffer());
+ ASSERT_FALSE(bus->AreFramesZero());
+
+ wasp_impl_->TaintOrigin();
+ wasp_impl_->ProvideInput(audio_data, params_.frames_per_buffer());
+ ASSERT_TRUE(bus->AreFramesZero());
+
+ wasp_impl_->Stop();
+}
+
// Verify CopyAudioCB is called if registered.
TEST_F(WebAudioSourceProviderImplTest, CopyAudioCB) {
testing::InSequence s;
wasp_impl_->Initialize(params_, &fake_callback_);
wasp_impl_->SetCopyAudioCallback(WTF::BindRepeating(
- &WebAudioSourceProviderImplTest::OnAudioBus, base::Unretained(this)));
+ &WebAudioSourceProviderImplTest::DoCopyAudioCB, base::Unretained(this)));
const auto bus1 = media::AudioBus::Create(params_);
EXPECT_CALL(*this, DoCopyAudioCB(_, 0, params_.sample_rate())).Times(1);
@@ -267,6 +319,27 @@ TEST_F(WebAudioSourceProviderImplTest, CopyAudioCB) {
testing::Mock::VerifyAndClear(mock_sink_.get());
}
+// Verify CopyAudioCB is zero when tainted.
+TEST_F(WebAudioSourceProviderImplTest, CopyAudioCBTainted) {
+ testing::InSequence s;
+ wasp_impl_->Initialize(params_, &fake_callback_);
+ wasp_impl_->SetCopyAudioCallback(WTF::BindRepeating(
+ &WebAudioSourceProviderImplTest::DoCopyAudioCB, base::Unretained(this)));
+
+ const auto bus1 = media::AudioBus::Create(params_);
+ EXPECT_CALL(*this,
+ DoCopyAudioCB(testing::Not(IsMuted()), 0, params_.sample_rate()))
+ .Times(1);
+ Render(bus1.get());
+
+ wasp_impl_->TaintOrigin();
+ EXPECT_CALL(*this, DoCopyAudioCB(IsMuted(), 0, params_.sample_rate()))
+ .Times(1);
+ Render(bus1.get());
+
+ testing::Mock::VerifyAndClear(mock_sink_.get());
+}
+
TEST_F(WebAudioSourceProviderImplTest, MultipleInitializeWithSetClient) {
// setClient() with a nullptr client should do nothing if no client is set.
wasp_impl_->SetClient(nullptr);

View File

@@ -10,10 +10,10 @@ kinds of utility windows. Similarly for `disableAutoHideCursor`.
Additionally, disables usage of some private APIs in MAS builds.
diff --git a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
index f872e4ec47c157288980caafa11104af2d205abb..8cf97e1a4aa6ed95bbc6427877ec96c6200dc7f2 100644
index f872e4ec47c157288980caafa11104af2d205abb..4f5c251da5904e1e478f3420a571b2edd8427486 100644
--- a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
+++ b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
@@ -154,6 +154,11 @@ void ExtractUnderlines(NSAttributedString* string,
@@ -154,6 +154,15 @@ void ExtractUnderlines(NSAttributedString* string,
} // namespace
@@ -21,11 +21,15 @@ index f872e4ec47c157288980caafa11104af2d205abb..8cf97e1a4aa6ed95bbc6427877ec96c6
+- (BOOL)acceptsFirstMouse;
+- (BOOL)disableAutoHideCursor;
+@end
+
+@interface NSView (ElectronCustomMethods)
+- (BOOL)shouldIgnoreMouseEvent;
+@end
+
// These are not documented, so use only after checking -respondsToSelector:.
@interface NSApplication (UndocumentedSpeechMethods)
- (void)speakString:(NSString*)string;
@@ -573,6 +578,9 @@ void ExtractUnderlines(NSAttributedString* string,
@@ -573,6 +582,9 @@ void ExtractUnderlines(NSAttributedString* string,
}
- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent {
@@ -35,7 +39,16 @@ index f872e4ec47c157288980caafa11104af2d205abb..8cf97e1a4aa6ed95bbc6427877ec96c6
return [self acceptsMouseEventsWhenInactive];
}
@@ -990,6 +998,10 @@ void ExtractUnderlines(NSAttributedString* string,
@@ -648,6 +660,8 @@ void ExtractUnderlines(NSAttributedString* string,
// its parent view.
BOOL hitSelf = NO;
while (view) {
+ if ([view respondsToSelector:@selector(shouldIgnoreMouseEvent)] && ![view shouldIgnoreMouseEvent])
+ return NO;
if (view == self)
hitSelf = YES;
if ([view isKindOfClass:[self class]] && ![view isEqual:self] &&
@@ -990,6 +1004,10 @@ void ExtractUnderlines(NSAttributedString* string,
eventType == NSKeyDown &&
!(modifierFlags & NSCommandKeyMask);
@@ -46,7 +59,7 @@ index f872e4ec47c157288980caafa11104af2d205abb..8cf97e1a4aa6ed95bbc6427877ec96c6
// We only handle key down events and just simply forward other events.
if (eventType != NSKeyDown) {
_hostHelper->ForwardKeyboardEvent(event, latency_info);
@@ -1766,9 +1778,11 @@ void ExtractUnderlines(NSAttributedString* string,
@@ -1766,9 +1784,11 @@ void ExtractUnderlines(NSAttributedString* string,
// Since this implementation doesn't have to wait any IPC calls, this doesn't
// make any key-typing jank. --hbono 7/23/09
//
@@ -58,7 +71,7 @@ index f872e4ec47c157288980caafa11104af2d205abb..8cf97e1a4aa6ed95bbc6427877ec96c6
- (NSArray*)validAttributesForMarkedText {
// This code is just copied from WebKit except renaming variables.
@@ -1777,7 +1791,10 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
@@ -1777,7 +1797,10 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
initWithObjects:NSUnderlineStyleAttributeName,
NSUnderlineColorAttributeName,
NSMarkedClauseSegmentAttributeName,

View File

@@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Scott Violet <sky@chromium.org>
Date: Fri, 13 Nov 2020 20:47:38 +0000
Subject: ui: CHECK that UnPremultiply is passed a 32bpp image
To do otherwise results in accessing random data.
BUG=1147430
TEST=none
(cherry picked from commit 1f673896837ab8c687d93fec604c96c78c7f679b)
Change-Id: Icedacbaac64cad3fc903e6423c6f9aad8c1e8cb5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2531118
Commit-Queue: danakj <danakj@chromium.org>
Reviewed-by: danakj <danakj@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#826300}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2538047
Reviewed-by: Scott Violet <sky@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1452}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/ui/gfx/skbitmap_operations.cc b/ui/gfx/skbitmap_operations.cc
index c08079f585b033849c744838c1db7a05ef729450..30372e849213d0446ac7edd72452782606bf938f 100644
--- a/ui/gfx/skbitmap_operations.cc
+++ b/ui/gfx/skbitmap_operations.cc
@@ -630,6 +630,8 @@ SkBitmap SkBitmapOperations::UnPreMultiply(const SkBitmap& bitmap) {
return bitmap;
if (bitmap.isOpaque())
return bitmap;
+ // It's expected this code is called with a 32bpp image.
+ CHECK_EQ(kN32_SkColorType, bitmap.colorType());
const SkImageInfo& opaque_info =
bitmap.info().makeAlphaType(kOpaque_SkAlphaType);

View File

@@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Deepak Mohan <hop2deep@gmail.com>
Date: Wed, 24 Jun 2020 21:00:00 -0700
Subject: use electron resources in icon_reader_service
Without this, the ID for IDS_UTILITY_PROCESS_UTILITY_WIN_NAME will be wrong on windows
and cause a DCHECK() failure
diff --git a/chrome/browser/win/icon_reader_service.cc b/chrome/browser/win/icon_reader_service.cc
index 721e1a863cc6925908f8343002df056f2373bf0b..10b2a95162541a8ff4d010c7be864f3f41dae378 100644
--- a/chrome/browser/win/icon_reader_service.cc
+++ b/chrome/browser/win/icon_reader_service.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/win/icon_reader_service.h"
#include "chrome/browser/service_sandbox_type.h"
-#include "chrome/grit/generated_resources.h"
+#include "electron/grit/electron_resources.h"
#include "content/public/browser/service_process_host.h"
mojo::Remote<chrome::mojom::UtilReadIcon> LaunchIconReaderInstance() {

View File

@@ -1,22 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Apthorp <nornagon@nornagon.net>
Date: Mon, 10 Feb 2020 10:37:48 -0800
Subject: use electron resources in pdf_util
Without this, the ID for IDR_PDF_MANIFEST will be wrong on linux
and cause a DCHECK(), since the resource will be loaded as an empty
string.
diff --git a/chrome/browser/pdf/pdf_extension_util.cc b/chrome/browser/pdf/pdf_extension_util.cc
index 9fd9791fd923d6c5e741cb7dc064ababf9a7995a..0a5534f2f09224196971076794daa3c805c91606 100644
--- a/chrome/browser/pdf/pdf_extension_util.cc
+++ b/chrome/browser/pdf/pdf_extension_util.cc
@@ -8,7 +8,7 @@
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/chrome_content_client.h"
-#include "chrome/grit/browser_resources.h"
+#include "electron/grit/electron_resources.h"
#include "components/strings/grit/components_strings.h"
#include "components/zoom/page_zoom_constants.h"
#include "pdf/pdf_features.h"

View File

@@ -7,5 +7,13 @@
"src/electron/patches/node": "src/third_party/electron_node",
"src/electron/patches/usrsctp": "src/third_party/usrsctp/usrsctplib"
"src/electron/patches/usrsctp": "src/third_party/usrsctp/usrsctplib",
"src/electron/patches/freetype": "src/third_party/freetype/src",
"src/electron/patches/pdfium": "src/third_party/pdfium",
"src/electron/patches/angle": "src/third_party/angle",
"src/electron/patches/skia": "src/third_party/skia"
}

View File

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

View File

@@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrey Belenko <anbelen@microsoft.com>
Date: Tue, 20 Oct 2020 21:39:54 +0200
Subject: Test early to prevent overflow.
Bug: chromium:1139963
diff --git a/src/sfnt/pngshim.c b/src/sfnt/pngshim.c
index 2e64e58463ad04c65424b2386e4a5a0d4ed7ca18..0bf2b4321752fc1526ca10d8fe0c96d5576128bd 100644
--- a/src/sfnt/pngshim.c
+++ b/src/sfnt/pngshim.c
@@ -332,6 +332,13 @@
if ( populate_map_and_metrics )
{
+ /* reject too large bitmaps similarly to the rasterizer */
+ if ( imgWidth > 0x7FFF || imgHeight > 0x7FFF )
+ {
+ error = FT_THROW( Array_Too_Large );
+ goto DestroyExit;
+ }
+
metrics->width = (FT_UShort)imgWidth;
metrics->height = (FT_UShort)imgHeight;
@@ -340,13 +347,6 @@
map->pixel_mode = FT_PIXEL_MODE_BGRA;
map->pitch = (int)( map->width * 4 );
map->num_grays = 256;
-
- /* reject too large bitmaps similarly to the rasterizer */
- if ( map->rows > 0x7FFF || map->width > 0x7FFF )
- {
- error = FT_THROW( Array_Too_Large );
- goto DestroyExit;
- }
}
/* convert palette/gray image to rgb */

View File

@@ -49,3 +49,5 @@ lib_use_non-symbols_in_isurlinstance_check.patch
fix_enable_tls_renegotiation.patch
crypto_update_certdata_to_nss_3_56.patch
n-api_src_provide_asynchronous_cleanup_hooks.patch
chore_expose_v8_initialization_isolate_callbacks.patch
fix_add_safeforterminationscopes_for_sigint_interruptions.patch

View File

@@ -0,0 +1,89 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Mon, 5 Oct 2020 16:05:45 -0700
Subject: chore: expose v8 initialization isolate callbacks
Exposes v8 initializer callbacks to Electron so that we can call them
directly. We expand upon and adapt their behavior, so allows us to
ensure that we stay in sync with Node.js default behavior.
This will be upstreamed.
diff --git a/src/api/environment.cc b/src/api/environment.cc
index 7b370579d365204b2bd40a25e740bbc83726c376..be58db8d2bebd1e1e5a0e6eb35c09b459d5d56e6 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -25,14 +25,16 @@ using v8::Private;
using v8::String;
using v8::Value;
-static bool AllowWasmCodeGenerationCallback(Local<Context> context,
+// static
+bool Environment::AllowWasmCodeGenerationCallback(Local<Context> context,
Local<String>) {
Local<Value> wasm_code_gen =
context->GetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration);
return wasm_code_gen->IsUndefined() || wasm_code_gen->IsTrue();
}
-static bool ShouldAbortOnUncaughtException(Isolate* isolate) {
+// static
+bool Environment::ShouldAbortOnUncaughtException(Isolate* isolate) {
DebugSealHandleScope scope(isolate);
Environment* env = Environment::GetCurrent(isolate);
return env != nullptr &&
@@ -41,7 +43,8 @@ static bool ShouldAbortOnUncaughtException(Isolate* isolate) {
!env->inside_should_not_abort_on_uncaught_scope();
}
-static MaybeLocal<Value> PrepareStackTraceCallback(Local<Context> context,
+// static
+MaybeLocal<Value> Environment::PrepareStackTraceCallback(Local<Context> context,
Local<Value> exception,
Local<Array> trace) {
Environment* env = Environment::GetCurrent(context);
@@ -195,7 +198,7 @@ void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s) {
auto* abort_callback = s.should_abort_on_uncaught_exception_callback ?
s.should_abort_on_uncaught_exception_callback :
- ShouldAbortOnUncaughtException;
+ Environment::ShouldAbortOnUncaughtException;
isolate->SetAbortOnUncaughtExceptionCallback(abort_callback);
auto* fatal_error_cb = s.fatal_error_callback ?
@@ -203,7 +206,7 @@ void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s) {
isolate->SetFatalErrorHandler(fatal_error_cb);
auto* prepare_stack_trace_cb = s.prepare_stack_trace_callback ?
- s.prepare_stack_trace_callback : PrepareStackTraceCallback;
+ s.prepare_stack_trace_callback : Environment::PrepareStackTraceCallback;
isolate->SetPrepareStackTraceCallback(prepare_stack_trace_cb);
}
@@ -211,7 +214,7 @@ void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s) {
isolate->SetMicrotasksPolicy(s.policy);
auto* allow_wasm_codegen_cb = s.allow_wasm_code_generation_callback ?
- s.allow_wasm_code_generation_callback : AllowWasmCodeGenerationCallback;
+ s.allow_wasm_code_generation_callback : Environment::AllowWasmCodeGenerationCallback;
isolate->SetAllowWasmCodeGenerationCallback(allow_wasm_codegen_cb);
auto* promise_reject_cb = s.promise_reject_callback ?
diff --git a/src/env.h b/src/env.h
index e269c47ae3814b42fdd2792360c1acb1995e98d2..e251eb1bb478b61b6b5a679f311c00d4310ff5ce 100644
--- a/src/env.h
+++ b/src/env.h
@@ -908,6 +908,13 @@ class Environment : public MemoryRetainer {
void Exit(int code);
void ExitEnv();
+ static bool AllowWasmCodeGenerationCallback(v8::Local<v8::Context> context,
+ v8::Local<v8::String>);
+ static bool ShouldAbortOnUncaughtException(v8::Isolate* isolate);
+ static v8::MaybeLocal<v8::Value> PrepareStackTraceCallback(v8::Local<v8::Context> context,
+ v8::Local<v8::Value> exception,
+ v8::Local<v8::Array> trace);
+
// Register clean-up cb to be called on environment destruction.
inline void RegisterHandleCleanup(uv_handle_t* handle,
HandleCleanupCb cb,

View File

@@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Thu, 10 Dec 2020 14:39:33 -0800
Subject: fix: add SafeForTerminationScopes for SIGINT interruptions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We start Node.js with only_terminate_in_safe_scope set to true becuase
it's set by gins IsolateHolder. In those cases, parts of the API that
expect execution termination to happen need to be marked as able to
receive those events.
Upstreamed at https://github.com/nodejs/node/pull/36344.
diff --git a/src/module_wrap.cc b/src/module_wrap.cc
index 29078bf6e58ce1782c08946dae760e7d62de486d..592cdedaa427393296ae5d9cd7c3a0d124b52673 100644
--- a/src/module_wrap.cc
+++ b/src/module_wrap.cc
@@ -313,6 +313,7 @@ void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) {
ShouldNotAbortOnUncaughtScope no_abort_scope(env);
TryCatchScope try_catch(env);
+ Isolate::SafeForTerminationScope safe_for_termination(env->isolate());
bool timed_out = false;
bool received_signal = false;
diff --git a/src/node_contextify.cc b/src/node_contextify.cc
index 2d30e0b8038ce473d1c8740861e13c5eabc2a0be..0902ac29b6f48c86302954a22a6e3318dc29836e 100644
--- a/src/node_contextify.cc
+++ b/src/node_contextify.cc
@@ -902,6 +902,7 @@ bool ContextifyScript::EvalMachine(Environment* env,
return false;
}
TryCatchScope try_catch(env);
+ Isolate::SafeForTerminationScope safe_for_termination(env->isolate());
ContextifyScript* wrapped_script;
ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.Holder(), false);
Local<UnboundScript> unbound_script =

1
patches/pdfium/.patches Normal file
View File

@@ -0,0 +1 @@
cherry-pick-9591642a0896.patch

View File

@@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Mon, 19 Oct 2020 17:07:57 +0000
Subject: Reverse order of CPWL_ListCtrl and CPWL_List_Notify cleanup
(Speculative) fix for the crash in 1137630, since it only reproduces
sporadically on my system, but hasn't re-occured since applying the
patch.
TBR: thestig@chromium.org
Bug: chromium:1137630
Change-Id: I4f52c7109eca00dfa8faee9bc6341cd94c25b60c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/75090
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
(cherry picked from commit 7dd9dbd6dd4959a568e7701da19871f859f8dce2)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/75350
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/pwl/cpwl_list_box.h b/fpdfsdk/pwl/cpwl_list_box.h
index 48b53e514dcb5a307b099b4ae427f83e9311f20c..1e56697f86318a5d371a6690fce9ec50c60e5150 100644
--- a/fpdfsdk/pwl/cpwl_list_box.h
+++ b/fpdfsdk/pwl/cpwl_list_box.h
@@ -97,8 +97,8 @@ class CPWL_ListBox : public CPWL_Wnd {
protected:
bool m_bMouseDown = false;
bool m_bHoverSel = false;
+ std::unique_ptr<CPWL_List_Notify> m_pListNotify; // Must outlive |m_pList|.
std::unique_ptr<CPWL_ListCtrl> m_pList;
- std::unique_ptr<CPWL_List_Notify> m_pListNotify;
UnownedPtr<IPWL_Filler_Notify> m_pFillerNotify;
private:

1
patches/skia/.patches Normal file
View File

@@ -0,0 +1 @@
cherry-pick-6763a713f957.patch

View File

@@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brian Osman <brianosman@google.com>
Date: Thu, 3 Sep 2020 15:19:14 -0400
Subject: Limit morphology radius to 100 pixels
This limit is arbitrary, but hopefully prevents pathological (or
malicious) SVG content from consuming huge amounts of CPU/GPU time,
without impacting any legitimate uses of feMorphology. (Typical usage
has a much smaller radius).
Bug: chromium:1123035
Change-Id: I4405bc595128e9a6287eb5efa1be14621baa3a00
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/315219
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/effects/imagefilters/SkMorphologyImageFilter.cpp b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
index 35f35d7f8d6bb3c9b4aca8057d5b876c237dbb22..a9a617f648e2fa229d6a555610fac4c737dd1459 100644
--- a/src/effects/imagefilters/SkMorphologyImageFilter.cpp
+++ b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
@@ -663,7 +663,9 @@ sk_sp<SkSpecialImage> SkMorphologyImageFilterImpl::onFilterImage(const Context&
int height = SkScalarRoundToInt(radius.height());
// Width (or height) must fit in a signed 32-bit int to avoid UBSAN issues (crbug.com/1018190)
- constexpr int kMaxRadius = (std::numeric_limits<int>::max() - 1) / 2;
+ // Further, we limit the radius to something much smaller, to avoid extremely slow draw calls:
+ // (crbug.com/1123035):
+ constexpr int kMaxRadius = 100; // (std::numeric_limits<int>::max() - 1) / 2;
if (width < 0 || height < 0 || width > kMaxRadius || height > kMaxRadius) {
return nullptr;

View File

@@ -7,3 +7,11 @@ workaround_an_undefined_symbol_error.patch
do_not_export_private_v8_symbols_on_windows.patch
revert_cleanup_switch_offset_of_to_offsetof_where_possible.patch
fix_build_deprecated_attirbute_for_older_msvc_versions.patch
cherry-pick-6aa1e71fbd09.patch
perf_make_getpositioninfoslow_faster.patch
cherry-pick-6a4cd97d6691.patch
cherry-pick-815b12dfb5ec.patch
cherry-pick-8c725f7b5bbf.patch
cherry-pick-146bd99e762b.patch
cherry-pick-633f67caa6d0.patch
cherry-pick-290fe9c6e245.patch

View File

@@ -0,0 +1,299 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "ishell@chromium.org" <ishell@chromium.org>
Date: Tue, 3 Nov 2020 12:42:43 +0100
Subject: Merged: Squashed multiple commits.
Merged: [map] Try to in-place transition during map update
Revision: 8e3ae62d294818733a0322d8e8abd53d4e410f19
Merged: [map] Skip loading the field owner before GeneralizeField
Revision: a928f5fcc2a67c2c8d621ece48f76deb0d36637b
BUG=chromium:1143772
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
R=verwaest@chromium.org
Change-Id: I78628cb697b21caa2098cc5948e226af5fcd020c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2516474
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/branch-heads/8.7@{#31}
Cr-Branched-From: 0d81cd72688512abcbe1601015baee390c484a6a-refs/heads/8.7.220@{#1}
Cr-Branched-From: 942c2ef85caef00fcf02517d049f05e9a3d4b440-refs/heads/master@{#70196}
diff --git a/src/objects/map-updater.cc b/src/objects/map-updater.cc
index e51bcfc76010a8c616dccc0af5daff5d498b7e81..b4b158749381efcf780d5c8ba07c286be6ba6b30 100644
--- a/src/objects/map-updater.cc
+++ b/src/objects/map-updater.cc
@@ -232,10 +232,7 @@ MapUpdater::State MapUpdater::TryReconfigureToDataFieldInplace() {
handle(old_descriptors_->GetFieldType(modified_descriptor_), isolate_),
MaybeHandle<Object>(), new_field_type_, MaybeHandle<Object>());
}
- Handle<Map> field_owner(
- old_map_->FindFieldOwner(isolate_, modified_descriptor_), isolate_);
-
- GeneralizeField(field_owner, modified_descriptor_, new_constness_,
+ GeneralizeField(old_map_, modified_descriptor_, new_constness_,
new_representation_, new_field_type_);
// Check that the descriptor array was updated.
DCHECK(old_descriptors_->GetDetails(modified_descriptor_)
@@ -401,7 +398,13 @@ MapUpdater::State MapUpdater::FindTargetMap() {
}
Representation tmp_representation = tmp_details.representation();
if (!old_details.representation().fits_into(tmp_representation)) {
- break;
+ // Try updating the field in-place to a generalized type.
+ Representation generalized =
+ tmp_representation.generalize(old_details.representation());
+ if (!tmp_representation.CanBeInPlaceChangedTo(generalized)) {
+ break;
+ }
+ tmp_representation = generalized;
}
if (tmp_details.location() == kField) {
diff --git a/src/objects/map.cc b/src/objects/map.cc
index d85d5893c43798a6ee643da46267c77eacd49c0e..cc98acd0e2840da52cc84b076fdea987bf96a047 100644
--- a/src/objects/map.cc
+++ b/src/objects/map.cc
@@ -611,6 +611,7 @@ void Map::DeprecateTransitionTree(Isolate* isolate) {
transitions.GetTarget(i).DeprecateTransitionTree(isolate);
}
DCHECK(!constructor_or_backpointer().IsFunctionTemplateInfo());
+ DCHECK(CanBeDeprecated());
set_is_deprecated(true);
if (FLAG_trace_maps) {
LOG(isolate, MapEvent("Deprecate", handle(*this, isolate), Handle<Map>()));
diff --git a/test/cctest/test-field-type-tracking.cc b/test/cctest/test-field-type-tracking.cc
index a8ef298fb0d2a7da15a4b58e5088dcec7e88b426..740ae05c1eaf8104ad5c3c443b2e39429fc7fca5 100644
--- a/test/cctest/test-field-type-tracking.cc
+++ b/test/cctest/test-field-type-tracking.cc
@@ -1038,7 +1038,8 @@ namespace {
// where "p2A" and "p2B" differ only in the attributes.
//
void TestReconfigureDataFieldAttribute_GeneralizeField(
- const CRFTData& from, const CRFTData& to, const CRFTData& expected) {
+ const CRFTData& from, const CRFTData& to, const CRFTData& expected,
+ bool expected_deprecation) {
Isolate* isolate = CcTest::i_isolate();
Expectations expectations(isolate);
@@ -1107,24 +1108,29 @@ void TestReconfigureDataFieldAttribute_GeneralizeField(
CHECK_NE(*map2, *new_map);
CHECK(expectations2.Check(*map2));
- // |map| should be deprecated and |new_map| should match new expectations.
for (int i = kSplitProp; i < kPropCount; i++) {
expectations.SetDataField(i, expected.constness, expected.representation,
expected.type);
}
- CHECK(map->is_deprecated());
- CHECK(!code_field_type->marked_for_deoptimization());
- CHECK(!code_field_repr->marked_for_deoptimization());
- CHECK(!code_field_const->marked_for_deoptimization());
- CHECK_NE(*map, *new_map);
+ if (expected_deprecation) {
+ // |map| should be deprecated and |new_map| should match new expectations.
+ CHECK(map->is_deprecated());
+ CHECK(!code_field_type->marked_for_deoptimization());
+ CHECK(!code_field_repr->marked_for_deoptimization());
+ CHECK(!code_field_const->marked_for_deoptimization());
+ CHECK_NE(*map, *new_map);
- CHECK(!new_map->is_deprecated());
- CHECK(expectations.Check(*new_map));
+ CHECK(!new_map->is_deprecated());
+ CHECK(expectations.Check(*new_map));
- // Update deprecated |map|, it should become |new_map|.
- Handle<Map> updated_map = Map::Update(isolate, map);
- CHECK_EQ(*new_map, *updated_map);
- CheckMigrationTarget(isolate, *map, *updated_map);
+ // Update deprecated |map|, it should become |new_map|.
+ Handle<Map> updated_map = Map::Update(isolate, map);
+ CHECK_EQ(*new_map, *updated_map);
+ CheckMigrationTarget(isolate, *map, *updated_map);
+ } else {
+ CHECK(!map->is_deprecated());
+ CHECK(expectations.Check(*map));
+ }
}
// This test ensures that trivial field generalization (from HeapObject to
@@ -1240,22 +1246,22 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeSmiFieldToDouble) {
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kConst, Representation::Smi(), any_type},
{PropertyConstness::kConst, Representation::Double(), any_type},
- {PropertyConstness::kConst, Representation::Double(), any_type});
+ {PropertyConstness::kConst, Representation::Double(), any_type}, true);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kConst, Representation::Smi(), any_type},
{PropertyConstness::kMutable, Representation::Double(), any_type},
- {PropertyConstness::kMutable, Representation::Double(), any_type});
+ {PropertyConstness::kMutable, Representation::Double(), any_type}, true);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::Smi(), any_type},
{PropertyConstness::kConst, Representation::Double(), any_type},
- {PropertyConstness::kMutable, Representation::Double(), any_type});
+ {PropertyConstness::kMutable, Representation::Double(), any_type}, true);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::Smi(), any_type},
{PropertyConstness::kMutable, Representation::Double(), any_type},
- {PropertyConstness::kMutable, Representation::Double(), any_type});
+ {PropertyConstness::kMutable, Representation::Double(), any_type}, true);
}
TEST(ReconfigureDataFieldAttribute_GeneralizeSmiFieldToTagged) {
@@ -1270,22 +1276,26 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeSmiFieldToTagged) {
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kConst, Representation::Smi(), any_type},
{PropertyConstness::kConst, Representation::HeapObject(), value_type},
- {PropertyConstness::kConst, Representation::Tagged(), any_type});
+ {PropertyConstness::kConst, Representation::Tagged(), any_type},
+ !FLAG_modify_field_representation_inplace);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kConst, Representation::Smi(), any_type},
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ !FLAG_modify_field_representation_inplace);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::Smi(), any_type},
{PropertyConstness::kConst, Representation::HeapObject(), value_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ !FLAG_modify_field_representation_inplace);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::Smi(), any_type},
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ !FLAG_modify_field_representation_inplace);
}
TEST(ReconfigureDataFieldAttribute_GeneralizeDoubleFieldToTagged) {
@@ -1300,22 +1310,26 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeDoubleFieldToTagged) {
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kConst, Representation::Double(), any_type},
{PropertyConstness::kConst, Representation::HeapObject(), value_type},
- {PropertyConstness::kConst, Representation::Tagged(), any_type});
+ {PropertyConstness::kConst, Representation::Tagged(), any_type},
+ FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kConst, Representation::Double(), any_type},
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::Double(), any_type},
{PropertyConstness::kConst, Representation::HeapObject(), value_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::Double(), any_type},
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace);
}
TEST(ReconfigureDataFieldAttribute_GeneralizeHeapObjFieldToHeapObj) {
@@ -1401,7 +1415,8 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeHeapObjectFieldToTagged) {
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
{PropertyConstness::kMutable, Representation::Smi(), any_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ !FLAG_modify_field_representation_inplace);
}
// Checks that given |map| is deprecated and that it updates to given |new_map|
diff --git a/test/mjsunit/regress/regress-1143772.js b/test/mjsunit/regress/regress-1143772.js
new file mode 100644
index 0000000000000000000000000000000000000000..40bc494d458afec816fd72e3fbb36b20a7942649
--- /dev/null
+++ b/test/mjsunit/regress/regress-1143772.js
@@ -0,0 +1,71 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --allow-natives-syntax
+
+(function() {
+ // Only run this test if doubles are transitioned in-place to tagged.
+ let x = {};
+ x.a = 0.1;
+ let y = {};
+ y.a = {};
+ if (!%HaveSameMap(x, y)) return;
+
+ // m1: {}
+ let m1 = {};
+
+ // m2: {a:d}
+ let m2 = {};
+ assertTrue(%HaveSameMap(m2, m1));
+ m2.a = 13.37;
+
+ // m3: {a:d, b:s}
+ let m3 = {};
+ m3.a = 13.37;
+ assertTrue(%HaveSameMap(m3, m2));
+ m3.b = 1;
+
+ // m4: {a:d, b:s, c:h}
+ let m4 = {};
+ m4.a = 13.37;
+ m4.b = 1;
+ assertTrue(%HaveSameMap(m4, m3));
+ m4.c = {};
+
+ // m4_2 == m4
+ let m4_2 = {};
+ m4_2.a = 13.37;
+ m4_2.b = 1;
+ m4_2.c = {};
+ assertTrue(%HaveSameMap(m4_2, m4));
+
+ // m5: {a:d, b:d}
+ let m5 = {};
+ m5.a = 13.37;
+ assertTrue(%HaveSameMap(m5, m2));
+ m5.b = 13.37;
+ assertFalse(%HaveSameMap(m5, m3));
+
+ // At this point, Map3 and Map4 are both deprecated. Map2 transitions to
+ // Map5. Map5 is the migration target for Map3.
+ assertFalse(%HaveSameMap(m5, m3));
+
+ // m6: {a:d, b:d, c:d}
+ let m6 = {};
+ m6.a = 13.37;
+ assertTrue(%HaveSameMap(m6, m2));
+ m6.b = 13.37;
+ assertTrue(%HaveSameMap(m6, m5));
+ m6.c = 13.37
+
+ // Make m7: {a:d, b:d, c:t}
+ let m7 = m4_2;
+ assertTrue(%HaveSameMap(m7, m4));
+ // Map4 is deprecated, so this property access triggers a Map migration.
+ // With in-place map updates and no double unboxing, this should end up
+ // migrating to Map6, and updating it in-place.
+ m7.c;
+ assertFalse(%HaveSameMap(m7, m4));
+ assertTrue(%HaveSameMap(m6, m7));
+})();

View File

@@ -0,0 +1,97 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Georg Neis <neis@chromium.org>
Date: Tue, 24 Nov 2020 14:43:35 +0100
Subject: Merged: [compiler] Fix a bug in SimplifiedLowering
Revision: ba1b2cc09ab98b51ca3828d29d19ae3b0a7c3a92
BUG=chromium:1150649
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
TBR=tebbi@chromium.org
Change-Id: I3600d25ebc255b0e58a7db1ca8d025424f6ad3f5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2557983
Reviewed-by: Georg Neis <neis@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/branch-heads/8.7@{#55}
Cr-Branched-From: 0d81cd72688512abcbe1601015baee390c484a6a-refs/heads/8.7.220@{#1}
Cr-Branched-From: 942c2ef85caef00fcf02517d049f05e9a3d4b440-refs/heads/master@{#70196}
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
index dd297d0b121e9997b6d4f76266c1f6e16e4ae72b..307ad5333869d4d80e59c115a486ed2f07f1798b 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -1411,7 +1411,6 @@ class RepresentationSelector {
IsSomePositiveOrderedNumber(input1_type)
? CheckForMinusZeroMode::kDontCheckForMinusZero
: CheckForMinusZeroMode::kCheckForMinusZero;
-
NodeProperties::ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode));
}
@@ -1455,6 +1454,13 @@ class RepresentationSelector {
Type left_feedback_type = TypeOf(node->InputAt(0));
Type right_feedback_type = TypeOf(node->InputAt(1));
+
+ // Using Signed32 as restriction type amounts to promising there won't be
+ // signed overflow. This is incompatible with relying on a Word32
+ // truncation in order to skip the overflow check.
+ Type const restriction =
+ truncation.IsUsedAsWord32() ? Type::Any() : Type::Signed32();
+
// Handle the case when no int32 checks on inputs are necessary (but
// an overflow check is needed on the output). Note that we do not
// have to do any check if at most one side can be minus zero. For
@@ -1468,7 +1474,7 @@ class RepresentationSelector {
right_upper.Is(Type::Signed32OrMinusZero()) &&
(left_upper.Is(Type::Signed32()) || right_upper.Is(Type::Signed32()))) {
VisitBinop<T>(node, UseInfo::TruncatingWord32(),
- MachineRepresentation::kWord32, Type::Signed32());
+ MachineRepresentation::kWord32, restriction);
} else {
// If the output's truncation is identify-zeros, we can pass it
// along. Moreover, if the operation is addition and we know the
@@ -1488,8 +1494,9 @@ class RepresentationSelector {
UseInfo right_use = CheckedUseInfoAsWord32FromHint(hint, FeedbackSource(),
kIdentifyZeros);
VisitBinop<T>(node, left_use, right_use, MachineRepresentation::kWord32,
- Type::Signed32());
+ restriction);
}
+
if (lower<T>()) {
if (truncation.IsUsedAsWord32() ||
!CanOverflowSigned32(node->op(), left_feedback_type,
diff --git a/test/mjsunit/compiler/regress-1150649.js b/test/mjsunit/compiler/regress-1150649.js
new file mode 100644
index 0000000000000000000000000000000000000000..a193481a3a20dc18dab7270a7686f6328bb79538
--- /dev/null
+++ b/test/mjsunit/compiler/regress-1150649.js
@@ -0,0 +1,24 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function foo(a) {
+ var y = 0x7fffffff; // 2^31 - 1
+
+ // Widen the static type of y (this condition never holds).
+ if (a == NaN) y = NaN;
+
+ // The next condition holds only in the warmup run. It leads to Smi
+ // (SignedSmall) feedback being collected for the addition below.
+ if (a) y = -1;
+
+ const z = (y + 1)|0;
+ return z < 0;
+}
+
+%PrepareFunctionForOptimization(foo);
+assertFalse(foo(true));
+%OptimizeFunctionOnNextCall(foo);
+assertTrue(foo(false));

View File

@@ -0,0 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andreas Haas <ahaas@chromium.org>
Date: Wed, 28 Oct 2020 07:55:24 +0100
Subject: Add missing HasValue check in BitfieldCheck::Detect
The value of a node was accessed without prior HasValue check. With
WebAssembly this node is not guaranteed to be a value.
R=mslekova@chromium.org
Change-Id: I62170183f3940a04b0550dfbb78cb49d2f5d7f72
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2504250
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70833}
diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc
index 127c7681099537c453a9ec08bc0af1d896e9717c..dbe4eae299468a33768656ef17836c04bbcfae7e 100644
--- a/src/compiler/machine-operator-reducer.cc
+++ b/src/compiler/machine-operator-reducer.cc
@@ -1616,7 +1616,7 @@ struct BitfieldCheck {
Uint32BinopMatcher eq(node);
if (eq.left().IsWord32And()) {
Uint32BinopMatcher mand(eq.left().node());
- if (mand.right().HasValue()) {
+ if (mand.right().HasValue() && eq.right().HasValue()) {
BitfieldCheck result{mand.left().node(), mand.right().Value(),
eq.right().Value(), false};
if (mand.left().IsTruncateInt64ToInt32()) {
diff --git a/test/unittests/compiler/machine-operator-reducer-unittest.cc b/test/unittests/compiler/machine-operator-reducer-unittest.cc
index 53342cbd212e561bc98cd559b139696fac291143..d789c5646bde8be423dabed3a64417019067ab60 100644
--- a/test/unittests/compiler/machine-operator-reducer-unittest.cc
+++ b/test/unittests/compiler/machine-operator-reducer-unittest.cc
@@ -837,6 +837,16 @@ TEST_F(MachineOperatorReducerTest, Word32AndWithBitFields) {
}
}
+TEST_F(MachineOperatorReducerTest, Word32AndWithIncorrectBitField) {
+ Reduction const r = Reduce(graph()->NewNode(
+ machine()->Word32And(), Parameter(0),
+ graph()->NewNode(machine()->Word32Equal(),
+ graph()->NewNode(machine()->Word32And(), Parameter(0),
+ Int32Constant(4)),
+ Parameter(0))));
+ ASSERT_FALSE(r.Changed());
+}
+
// -----------------------------------------------------------------------------
// Word32Or

View File

@@ -0,0 +1,90 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leszek Swirski <leszeks@chromium.org>
Date: Wed, 30 Sep 2020 15:19:13 +0200
Subject: Merged: [parser] Fix AST func reindexing for function fields
AST reindexing has to skip visiting fields that are already in the
member initializer, as they will have already been visited when
visiting said initializer. This is the case for private fields and
fields with computed names.
However, the reindexer was incorrectly assuming that all properties
with a FunctionLiteral value are methods (and thus not fields, and
can safely be visited). This is not the case for fields with
function expression values.
Now, we correctly use the class property's "kind" when making this
visitation decision.
(cherry picked from commit a769ea7a4462115579ba87bc16fbffbae01310c1)
Bug: chromium:1132111
Tbr: leszeks@chromium.org
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Change-Id: I33ac5664bb5334e964d351de1ba7e2c57f3398f8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2465056
Commit-Queue: Adam Klein <adamk@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/branch-heads/8.6@{#24}
Cr-Branched-From: a64aed2333abf49e494d2a5ce24bbd14fff19f60-refs/heads/8.6.395@{#1}
Cr-Branched-From: a626bc036236c9bf92ac7b87dc40c9e538b087e3-refs/heads/master@{#69472}
diff --git a/src/ast/ast-function-literal-id-reindexer.cc b/src/ast/ast-function-literal-id-reindexer.cc
index b583b5e4214ad469848844923ef03dba06b6554c..8c9318bfe7475d3c9b8cc2bdb50786b9118fd4a0 100644
--- a/src/ast/ast-function-literal-id-reindexer.cc
+++ b/src/ast/ast-function-literal-id-reindexer.cc
@@ -54,10 +54,10 @@ void AstFunctionLiteralIdReindexer::VisitClassLiteral(ClassLiteral* expr) {
// Private fields have their key and value present in
// instance_members_initializer_function, so they will
// already have been visited.
- if (prop->value()->IsFunctionLiteral()) {
- Visit(prop->value());
- } else {
+ if (prop->kind() == ClassLiteralProperty::Kind::FIELD) {
CheckVisited(prop->value());
+ } else {
+ Visit(prop->value());
}
}
ZonePtrList<ClassLiteral::Property>* props = expr->public_members();
@@ -67,7 +67,8 @@ void AstFunctionLiteralIdReindexer::VisitClassLiteral(ClassLiteral* expr) {
// Public fields with computed names have their key
// and value present in instance_members_initializer_function, so they will
// already have been visited.
- if (prop->is_computed_name() && !prop->value()->IsFunctionLiteral()) {
+ if (prop->is_computed_name() &&
+ prop->kind() == ClassLiteralProperty::Kind::FIELD) {
if (!prop->key()->IsLiteral()) {
CheckVisited(prop->key());
}
diff --git a/test/mjsunit/regress/regress-1132111.js b/test/mjsunit/regress/regress-1132111.js
new file mode 100644
index 0000000000000000000000000000000000000000..1dd1b58806862aaf6c0847f107377095105dcab1
--- /dev/null
+++ b/test/mjsunit/regress/regress-1132111.js
@@ -0,0 +1,23 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Public function field with computed name
+eval(`
+ buggy = ((bug = new class { [0] = x => 1337.0; }) => bug);
+`);
+
+// Public method with computed name
+eval(`
+ buggy = ((bug = new class { [0](x) { return 1337.0}; }) => bug);
+`);
+
+// Private function field with computed name
+eval(`
+ buggy = ((bug = new class { #foo = x => 1337.0; }) => bug);
+`);
+
+// Private method with computed name
+eval(`
+ buggy = ((bug = new class { #foo(x) { return 1337.0; } }) => bug);
+`);

View File

@@ -0,0 +1,70 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andreas Haas <ahaas@chromium.org>
Date: Tue, 25 Aug 2020 11:46:46 +0200
Subject: Merged: [wasm][streaming] Avoid aborting the stream after it finished
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
With WebAssembly streaming compilation it is possible that FinishStream
indirectly calls AbortStream. This had the effect that while
FinishStream fulfilled the promise, AbortStream disposed the promise
by removing the compile job from the wasm engine and thereby deallocated
AsyncCompileJob and all the state that belongs to it. Without that
state, FinishStream could not finish fulfilling the promise correctly.
With this CL the streaming decoder remembers that the stream has
already been finished. When the stream has been finished, all calls to
Abort get ignored.
The regression test for this issue requires the Chrome embedding, see
https://crrev.com/c/2368359
R=clemensb@chromium.org
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
(cherry picked from commit 32dd54709cd2ecdfc553aff3f7ab5377ff7c91a2)
Bug: chromium:1117258
Change-Id: Ifc28a1ee38c228b051c4d7d85b305fe2a721fa1f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2367858
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#69549}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2465830
Cr-Commit-Position: refs/branch-heads/8.6@{#22}
Cr-Branched-From: a64aed2333abf49e494d2a5ce24bbd14fff19f60-refs/heads/8.6.395@{#1}
Cr-Branched-From: a626bc036236c9bf92ac7b87dc40c9e538b087e3-refs/heads/master@{#69472}
diff --git a/src/wasm/streaming-decoder.cc b/src/wasm/streaming-decoder.cc
index eb2978070074981f20b0e2f27401bce39e0029d9..88f40b9a00df75231b9938a4691c1330d047b070 100644
--- a/src/wasm/streaming-decoder.cc
+++ b/src/wasm/streaming-decoder.cc
@@ -214,6 +214,7 @@ class V8_EXPORT_PRIVATE AsyncStreamingDecoder : public StreamingDecoder {
bool code_section_processed_ = false;
uint32_t module_offset_ = 0;
size_t total_size_ = 0;
+ bool stream_finished_ = false;
// We need wire bytes in an array for deserializing cached modules.
std::vector<uint8_t> wire_bytes_for_deserializing_;
@@ -258,6 +259,8 @@ size_t AsyncStreamingDecoder::DecodingState::ReadBytes(
void AsyncStreamingDecoder::Finish() {
TRACE_STREAMING("Finish\n");
+ DCHECK(!stream_finished_);
+ stream_finished_ = true;
if (!ok()) return;
if (deserializing()) {
@@ -298,6 +301,8 @@ void AsyncStreamingDecoder::Finish() {
void AsyncStreamingDecoder::Abort() {
TRACE_STREAMING("Abort\n");
+ if (stream_finished_) return;
+ stream_finished_ = true;
if (!ok()) return; // Failed already.
processor_->OnAbort();
Fail();

View File

@@ -0,0 +1,819 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "ishell@chromium.org" <ishell@chromium.org>
Date: Tue, 27 Oct 2020 13:13:08 +0100
Subject: Merged: [runtime] Fix sorted order of DescriptorArray entries
Revision: 518d67ad652fc24b7eb03e48bb342f952d4ccf74
BUG=chromium:1133527
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
R=verwaest@chromium.org
Change-Id: I10831b27c5c10b9a967e47a5fd08f806ef5d306d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2502328
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/branch-heads/8.6@{#34}
Cr-Branched-From: a64aed2333abf49e494d2a5ce24bbd14fff19f60-refs/heads/8.6.395@{#1}
Cr-Branched-From: a626bc036236c9bf92ac7b87dc40c9e538b087e3-refs/heads/master@{#69472}
diff --git a/src/codegen/code-stub-assembler.cc b/src/codegen/code-stub-assembler.cc
index 6e9b817759dbccd314fec13a911fee40d0b92b80..da0cb08023d1cade3fcb6ef0fb0f5ecaacd125ba 100644
--- a/src/codegen/code-stub-assembler.cc
+++ b/src/codegen/code-stub-assembler.cc
@@ -1772,12 +1772,13 @@ TNode<IntPtrT> CodeStubAssembler::LoadJSReceiverIdentityHash(
return var_hash.value();
}
-TNode<Uint32T> CodeStubAssembler::LoadNameHashField(SloppyTNode<Name> name) {
- CSA_ASSERT(this, IsName(name));
- return LoadObjectField<Uint32T>(name, Name::kHashFieldOffset);
+TNode<Uint32T> CodeStubAssembler::LoadNameHashAssumeComputed(TNode<Name> name) {
+ TNode<Uint32T> hash_field = LoadNameHashField(name);
+ CSA_ASSERT(this, IsClearWord32(hash_field, Name::kHashNotComputedMask));
+ return Unsigned(Word32Shr(hash_field, Int32Constant(Name::kHashShift)));
}
-TNode<Uint32T> CodeStubAssembler::LoadNameHash(SloppyTNode<Name> name,
+TNode<Uint32T> CodeStubAssembler::LoadNameHash(TNode<Name> name,
Label* if_hash_not_computed) {
TNode<Uint32T> hash_field = LoadNameHashField(name);
if (if_hash_not_computed != nullptr) {
@@ -8026,7 +8027,7 @@ void CodeStubAssembler::LookupBinary(TNode<Name> unique_name,
TNode<Uint32T> limit =
Unsigned(Int32Sub(NumberOfEntries<Array>(array), Int32Constant(1)));
TVARIABLE(Uint32T, var_high, limit);
- TNode<Uint32T> hash = LoadNameHashField(unique_name);
+ TNode<Uint32T> hash = LoadNameHashAssumeComputed(unique_name);
CSA_ASSERT(this, Word32NotEqual(hash, Int32Constant(0)));
// Assume non-empty array.
@@ -8044,7 +8045,7 @@ void CodeStubAssembler::LookupBinary(TNode<Name> unique_name,
TNode<Uint32T> sorted_key_index = GetSortedKeyIndex<Array>(array, mid);
TNode<Name> mid_name = GetKey<Array>(array, sorted_key_index);
- TNode<Uint32T> mid_hash = LoadNameHashField(mid_name);
+ TNode<Uint32T> mid_hash = LoadNameHashAssumeComputed(mid_name);
Label mid_greater(this), mid_less(this), merge(this);
Branch(Uint32GreaterThanOrEqual(mid_hash, hash), &mid_greater, &mid_less);
@@ -8071,7 +8072,7 @@ void CodeStubAssembler::LookupBinary(TNode<Name> unique_name,
TNode<Uint32T> sort_index =
GetSortedKeyIndex<Array>(array, var_low.value());
TNode<Name> current_name = GetKey<Array>(array, sort_index);
- TNode<Uint32T> current_hash = LoadNameHashField(current_name);
+ TNode<Uint32T> current_hash = LoadNameHashAssumeComputed(current_name);
GotoIf(Word32NotEqual(current_hash, hash), if_not_found);
Label next(this);
GotoIf(TaggedNotEqual(current_name, unique_name), &next);
diff --git a/src/codegen/code-stub-assembler.h b/src/codegen/code-stub-assembler.h
index a13699939942dd3260e98dff678566be2c8b4346..99a30c9ad95d4e36e25004f93472cf73130e9cdc 100644
--- a/src/codegen/code-stub-assembler.h
+++ b/src/codegen/code-stub-assembler.h
@@ -1322,13 +1322,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
// Check if the map is set for slow properties.
TNode<BoolT> IsDictionaryMap(SloppyTNode<Map> map);
- // Load the hash field of a name as an uint32 value.
- TNode<Uint32T> LoadNameHashField(SloppyTNode<Name> name);
- // Load the hash value of a name as an uint32 value.
+ // Load the Name::hash() value of a name as an uint32 value.
// If {if_hash_not_computed} label is specified then it also checks if
// hash is actually computed.
- TNode<Uint32T> LoadNameHash(SloppyTNode<Name> name,
+ TNode<Uint32T> LoadNameHash(TNode<Name> name,
Label* if_hash_not_computed = nullptr);
+ TNode<Uint32T> LoadNameHashAssumeComputed(TNode<Name> name);
// Load length field of a String object as Smi value.
TNode<Smi> LoadStringLengthAsSmi(TNode<String> string);
diff --git a/src/diagnostics/objects-debug.cc b/src/diagnostics/objects-debug.cc
index f94dd8a3c6a148ee53d49eae668ca7e3b85e41ff..185cf31d8cfda1207d0963904fb719f19c1e95c8 100644
--- a/src/diagnostics/objects-debug.cc
+++ b/src/diagnostics/objects-debug.cc
@@ -1662,12 +1662,13 @@ bool DescriptorArray::IsSortedNoDuplicates() {
uint32_t current = 0;
for (int i = 0; i < number_of_descriptors(); i++) {
Name key = GetSortedKey(i);
+ CHECK(key.HasHashCode());
if (key == current_key) {
Print();
return false;
}
current_key = key;
- uint32_t hash = GetSortedKey(i).Hash();
+ uint32_t hash = key.hash();
if (hash < current) {
Print();
return false;
@@ -1685,7 +1686,8 @@ bool TransitionArray::IsSortedNoDuplicates() {
for (int i = 0; i < number_of_transitions(); i++) {
Name key = GetSortedKey(i);
- uint32_t hash = key.Hash();
+ CHECK(key.HasHashCode());
+ uint32_t hash = key.hash();
PropertyKind kind = kData;
PropertyAttributes attributes = NONE;
if (!TransitionsAccessor::IsSpecialTransition(key.GetReadOnlyRoots(),
diff --git a/src/objects/descriptor-array-inl.h b/src/objects/descriptor-array-inl.h
index d9e3408dd96aed4f798176a38ae4f0eade1c6c89..a7c6443a05fa7debc1841fb259ff1bc98ba7e184 100644
--- a/src/objects/descriptor-array-inl.h
+++ b/src/objects/descriptor-array-inl.h
@@ -228,7 +228,7 @@ void DescriptorArray::Append(Descriptor* desc) {
for (insertion = descriptor_number; insertion > 0; --insertion) {
Name key = GetSortedKey(insertion - 1);
- if (key.Hash() <= hash) break;
+ if (key.hash() <= hash) break;
SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
}
diff --git a/src/objects/descriptor-array.h b/src/objects/descriptor-array.h
index f68948192900d901743548943e1df82567ade2ba..890863d5a01268756d5aa94037925120652cb1bd 100644
--- a/src/objects/descriptor-array.h
+++ b/src/objects/descriptor-array.h
@@ -113,7 +113,7 @@ class DescriptorArray
int slack = 0);
// Sort the instance descriptors by the hash codes of their keys.
- void Sort();
+ V8_EXPORT_PRIVATE void Sort();
// Search the instance descriptors for given name. {concurrent_search} signals
// if we are doing the search on a background thread. If so, we will sacrifice
diff --git a/src/objects/fixed-array-inl.h b/src/objects/fixed-array-inl.h
index a49483ebc6490dafdf13301dd991ffc301037476..adde6c7c1f7958643c46aedf8be33300d36f6306 100644
--- a/src/objects/fixed-array-inl.h
+++ b/src/objects/fixed-array-inl.h
@@ -217,7 +217,7 @@ int BinarySearch(T* array, Name name, int valid_entries,
// index). After doing the binary search and getting the correct internal
// index we check to have the index lower than valid_entries, if needed.
int high = array->number_of_entries() - 1;
- uint32_t hash = name.hash_field();
+ uint32_t hash = name.hash();
int limit = high;
DCHECK(low <= high);
@@ -225,7 +225,7 @@ int BinarySearch(T* array, Name name, int valid_entries,
while (low != high) {
int mid = low + (high - low) / 2;
Name mid_name = array->GetSortedKey(mid);
- uint32_t mid_hash = mid_name.hash_field();
+ uint32_t mid_hash = mid_name.hash();
if (mid_hash >= hash) {
high = mid;
@@ -237,7 +237,7 @@ int BinarySearch(T* array, Name name, int valid_entries,
for (; low <= limit; ++low) {
int sort_index = array->GetSortedKeyIndex(low);
Name entry = array->GetKey(InternalIndex(sort_index));
- uint32_t current_hash = entry.hash_field();
+ uint32_t current_hash = entry.hash();
if (current_hash != hash) {
// 'search_mode == ALL_ENTRIES' here and below is not needed since
// 'out_insertion_index != nullptr' implies 'search_mode == ALL_ENTRIES'.
@@ -269,12 +269,12 @@ template <SearchMode search_mode, typename T>
int LinearSearch(T* array, Name name, int valid_entries,
int* out_insertion_index) {
if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
- uint32_t hash = name.hash_field();
+ uint32_t hash = name.hash();
int len = array->number_of_entries();
for (int number = 0; number < len; number++) {
int sorted_index = array->GetSortedKeyIndex(number);
Name entry = array->GetKey(InternalIndex(sorted_index));
- uint32_t current_hash = entry.hash_field();
+ uint32_t current_hash = entry.hash();
if (current_hash > hash) {
*out_insertion_index = sorted_index;
return T::kNotFound;
diff --git a/src/objects/name-inl.h b/src/objects/name-inl.h
index 0735b4e506fbcb453d4e1a5a832225ca83ca1b96..ffcd287fd37454e3449b5064b4aa37196dadfdbd 100644
--- a/src/objects/name-inl.h
+++ b/src/objects/name-inl.h
@@ -94,6 +94,12 @@ uint32_t Name::Hash() {
return String::cast(*this).ComputeAndSetHash();
}
+uint32_t Name::hash() const {
+ uint32_t field = hash_field();
+ DCHECK(IsHashFieldComputed(field));
+ return field >> kHashShift;
+}
+
DEF_GETTER(Name, IsInterestingSymbol, bool) {
return IsSymbol(isolate) && Symbol::cast(*this).is_interesting_symbol();
}
diff --git a/src/objects/name.h b/src/objects/name.h
index 533d8b000ebfa0ef714b61a021de7fc3d0d456f8..6309de9d4ca4502d30c482455103dd16645e6401 100644
--- a/src/objects/name.h
+++ b/src/objects/name.h
@@ -23,9 +23,15 @@ class Name : public TorqueGeneratedName<Name, PrimitiveHeapObject> {
// Tells whether the hash code has been computed.
inline bool HasHashCode();
- // Returns a hash value used for the property table
+ // Returns a hash value used for the property table. Ensures that the hash
+ // value is computed.
+ // TODO(ishell): rename to EnsureHash().
inline uint32_t Hash();
+ // Returns a hash value used for the property table (same as Hash()), assumes
+ // the hash is already computed.
+ inline uint32_t hash() const;
+
// Equality operations.
inline bool Equals(Name other);
inline static bool Equals(Isolate* isolate, Handle<Name> one,
diff --git a/src/objects/objects.cc b/src/objects/objects.cc
index 5e0c831f73b6ccbe40c556497f5ba6fbc9f42b48..54b19d6cdc5ff1f7bd73605a09681c199892b9eb 100644
--- a/src/objects/objects.cc
+++ b/src/objects/objects.cc
@@ -4357,16 +4357,16 @@ void DescriptorArray::Sort() {
// Reset sorting since the descriptor array might contain invalid pointers.
for (int i = 0; i < len; ++i) SetSortedKey(i, i);
// Bottom-up max-heap construction.
- // Index of the last node with children
+ // Index of the last node with children.
const int max_parent_index = (len / 2) - 1;
for (int i = max_parent_index; i >= 0; --i) {
int parent_index = i;
- const uint32_t parent_hash = GetSortedKey(i).Hash();
+ const uint32_t parent_hash = GetSortedKey(i).hash();
while (parent_index <= max_parent_index) {
int child_index = 2 * parent_index + 1;
- uint32_t child_hash = GetSortedKey(child_index).Hash();
+ uint32_t child_hash = GetSortedKey(child_index).hash();
if (child_index + 1 < len) {
- uint32_t right_child_hash = GetSortedKey(child_index + 1).Hash();
+ uint32_t right_child_hash = GetSortedKey(child_index + 1).hash();
if (right_child_hash > child_hash) {
child_index++;
child_hash = right_child_hash;
@@ -4385,13 +4385,13 @@ void DescriptorArray::Sort() {
SwapSortedKeys(0, i);
// Shift down the new top element.
int parent_index = 0;
- const uint32_t parent_hash = GetSortedKey(parent_index).Hash();
+ const uint32_t parent_hash = GetSortedKey(parent_index).hash();
const int max_parent_index = (i / 2) - 1;
while (parent_index <= max_parent_index) {
int child_index = parent_index * 2 + 1;
- uint32_t child_hash = GetSortedKey(child_index).Hash();
+ uint32_t child_hash = GetSortedKey(child_index).hash();
if (child_index + 1 < i) {
- uint32_t right_child_hash = GetSortedKey(child_index + 1).Hash();
+ uint32_t right_child_hash = GetSortedKey(child_index + 1).hash();
if (right_child_hash > child_hash) {
child_index++;
child_hash = right_child_hash;
diff --git a/src/objects/transitions-inl.h b/src/objects/transitions-inl.h
index 5694d66d948325bb139b67a3a34c22759224d139..09157b7f5d0051b80e60de51f358d4fd5bde0b99 100644
--- a/src/objects/transitions-inl.h
+++ b/src/objects/transitions-inl.h
@@ -169,12 +169,20 @@ int TransitionArray::SearchNameForTesting(Name name, int* out_insertion_index) {
return SearchName(name, out_insertion_index);
}
+Map TransitionArray::SearchAndGetTargetForTesting(
+ PropertyKind kind, Name name, PropertyAttributes attributes) {
+ return SearchAndGetTarget(kind, name, attributes);
+}
+
int TransitionArray::SearchSpecial(Symbol symbol, int* out_insertion_index) {
return SearchName(symbol, out_insertion_index);
}
int TransitionArray::SearchName(Name name, int* out_insertion_index) {
DCHECK(name.IsUniqueName());
+ // The name is taken from DescriptorArray, so it must already has a computed
+ // hash.
+ DCHECK(name.HasHashCode());
return internal::Search<ALL_ENTRIES>(this, name, number_of_entries(),
out_insertion_index);
}
diff --git a/src/objects/transitions.cc b/src/objects/transitions.cc
index 1309ca82be544dced9d636f52519d49e70fbc1a3..93d43f42d97ebc53adb6f5927ff92bbb82ba57aa 100644
--- a/src/objects/transitions.cc
+++ b/src/objects/transitions.cc
@@ -604,8 +604,8 @@ void TransitionArray::Sort() {
temp_kind = details.kind();
temp_attributes = details.attributes();
}
- int cmp = CompareKeys(temp_key, temp_key.Hash(), temp_kind,
- temp_attributes, key, key.Hash(), kind, attributes);
+ int cmp = CompareKeys(temp_key, temp_key.hash(), temp_kind,
+ temp_attributes, key, key.hash(), kind, attributes);
if (cmp > 0) {
SetKey(j + 1, temp_key);
SetRawTarget(j + 1, temp_target);
diff --git a/src/objects/transitions.h b/src/objects/transitions.h
index 7bc4d70a35da1e20120cc2f55710ecb9155fd72c..26d29f4cf5ac5c333d95503ab484a9c3b4b1a2fa 100644
--- a/src/objects/transitions.h
+++ b/src/objects/transitions.h
@@ -143,6 +143,9 @@ class V8_EXPORT_PRIVATE TransitionsAccessor {
return encoding_;
}
+
+ inline TransitionArray transitions();
+
private:
friend class MarkCompactCollector; // For HasSimpleTransitionTo.
friend class TransitionArray;
@@ -175,8 +178,6 @@ class V8_EXPORT_PRIVATE TransitionsAccessor {
void TraverseTransitionTreeInternal(TraverseCallback callback, void* data,
DisallowHeapAllocation* no_gc);
- inline TransitionArray transitions();
-
Isolate* isolate_;
Handle<Map> map_handle_;
Map map_;
@@ -231,7 +232,7 @@ class TransitionArray : public WeakFixedArray {
V8_EXPORT_PRIVATE bool IsSortedNoDuplicates();
#endif
- void Sort();
+ V8_EXPORT_PRIVATE void Sort();
void PrintInternal(std::ostream& os);
@@ -260,6 +261,9 @@ class TransitionArray : public WeakFixedArray {
inline int SearchNameForTesting(Name name,
int* out_insertion_index = nullptr);
+ inline Map SearchAndGetTargetForTesting(PropertyKind kind, Name name,
+ PropertyAttributes attributes);
+
private:
friend class Factory;
friend class MarkCompactCollector;
@@ -296,8 +300,8 @@ class TransitionArray : public WeakFixedArray {
int Search(PropertyKind kind, Name name, PropertyAttributes attributes,
int* out_insertion_index = nullptr);
- Map SearchAndGetTarget(PropertyKind kind, Name name,
- PropertyAttributes attributes);
+ V8_EXPORT_PRIVATE Map SearchAndGetTarget(PropertyKind kind, Name name,
+ PropertyAttributes attributes);
// Search a non-property transition (like elements kind, observe or frozen
// transitions).
diff --git a/test/cctest/BUILD.gn b/test/cctest/BUILD.gn
index a55451c6c9c1d87b9dd670e14c16fcdac1d9753d..c4d0d98466d23be18bb2884a22c02531c9a93878 100644
--- a/test/cctest/BUILD.gn
+++ b/test/cctest/BUILD.gn
@@ -205,6 +205,7 @@ v8_source_set("cctest_sources") {
"test-debug.cc",
"test-decls.cc",
"test-deoptimization.cc",
+ "test-descriptor-array.cc",
"test-dictionary.cc",
"test-diy-fp.cc",
"test-double.cc",
diff --git a/test/cctest/test-descriptor-array.cc b/test/cctest/test-descriptor-array.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7abd36ec6c84959c3da59b8e78d9e4a0ee291632
--- /dev/null
+++ b/test/cctest/test-descriptor-array.cc
@@ -0,0 +1,424 @@
+// 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.
+
+#include "src/base/logging.h"
+#include "src/codegen/code-stub-assembler.h"
+#include "src/common/globals.h"
+#include "src/objects/descriptor-array.h"
+#include "src/objects/property-details.h"
+#include "src/objects/string-inl.h"
+#include "src/objects/transitions-inl.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/code-assembler-tester.h"
+#include "test/cctest/compiler/function-tester.h"
+#include "test/cctest/test-transitions.h"
+
+namespace v8 {
+namespace internal {
+
+namespace {
+
+using Label = compiler::CodeAssemblerLabel;
+template <class T>
+using TVariable = compiler::TypedCodeAssemblerVariable<T>;
+
+Handle<Name> NewNameWithHash(Isolate* isolate, const char* str, uint32_t hash,
+ bool is_integer) {
+ uint32_t hash_field = hash << Name::kHashShift;
+
+ static_assert(Name::kNofHashBitFields == 2, "This test needs updating");
+ static_assert(Name::kHashNotComputedMask == 1, "This test needs updating");
+ static_assert(Name::kIsNotIntegerIndexMask == 2, "This test needs updating");
+
+ if (!is_integer) {
+ hash_field |= Name::kIsNotIntegerIndexMask;
+ }
+ Handle<Name> name = isolate->factory()->NewOneByteInternalizedString(
+ OneByteVector(str), hash_field);
+ name->set_hash_field(hash_field);
+ CHECK(name->IsUniqueName());
+ return name;
+}
+
+template <typename... Args>
+MaybeHandle<Object> Call(Isolate* isolate, Handle<JSFunction> function,
+ Args... args) {
+ const int nof_args = sizeof...(Args);
+ Handle<Object> call_args[] = {args...};
+ Handle<Object> receiver = isolate->factory()->undefined_value();
+ return Execution::Call(isolate, function, receiver, nof_args, call_args);
+}
+
+void CheckDescriptorArrayLookups(Isolate* isolate, Handle<Map> map,
+ std::vector<Handle<Name>>& names,
+ Handle<JSFunction> csa_lookup) {
+ // Test C++ implementation.
+ {
+ DisallowHeapAllocation no_gc;
+ DescriptorArray descriptors = map->instance_descriptors();
+ DCHECK(descriptors.IsSortedNoDuplicates());
+ int nof_descriptors = descriptors.number_of_descriptors();
+
+ for (size_t i = 0; i < names.size(); ++i) {
+ Name name = *names[i];
+ InternalIndex index = descriptors.Search(name, nof_descriptors, false);
+ CHECK(index.is_found());
+ CHECK_EQ(i, index.as_uint32());
+ }
+ }
+
+ // Test CSA implementation.
+ if (!FLAG_jitless) {
+ for (size_t i = 0; i < names.size(); ++i) {
+ Handle<Object> name_index =
+ Call(isolate, csa_lookup, map, names[i]).ToHandleChecked();
+ CHECK(name_index->IsSmi());
+ CHECK_EQ(DescriptorArray::ToKeyIndex(static_cast<int>(i)),
+ Smi::ToInt(*name_index));
+ }
+ }
+}
+
+void CheckTransitionArrayLookups(Isolate* isolate,
+ Handle<TransitionArray> transitions,
+ std::vector<Handle<Map>>& maps,
+ Handle<JSFunction> csa_lookup) {
+ // Test C++ implementation.
+ {
+ DisallowHeapAllocation no_gc;
+ DCHECK(transitions->IsSortedNoDuplicates());
+
+ for (size_t i = 0; i < maps.size(); ++i) {
+ Map expected_map = *maps[i];
+ Name name =
+ expected_map.instance_descriptors().GetKey(expected_map.LastAdded());
+
+ Map map = transitions->SearchAndGetTargetForTesting(PropertyKind::kData,
+ name, NONE);
+ CHECK(!map.is_null());
+ CHECK_EQ(expected_map, map);
+ }
+ }
+
+ // Test CSA implementation.
+ if (!FLAG_jitless) {
+ for (size_t i = 0; i < maps.size(); ++i) {
+ Handle<Map> expected_map = maps[i];
+ Handle<Name> name(expected_map->instance_descriptors().GetKey(
+ expected_map->LastAdded()),
+ isolate);
+
+ Handle<Object> transition_map =
+ Call(isolate, csa_lookup, transitions, name).ToHandleChecked();
+ CHECK(transition_map->IsMap());
+ CHECK_EQ(*expected_map, *transition_map);
+ }
+ }
+}
+
+// Creates function with (Map, Name) arguments. Returns Smi with the index of
+// the name value of the found descriptor (DescriptorArray::ToKeyIndex())
+// or null otherwise.
+Handle<JSFunction> CreateCsaDescriptorArrayLookup(Isolate* isolate) {
+ // We are not allowed to generate code in jitless mode.
+ if (FLAG_jitless) return Handle<JSFunction>();
+
+ // Preallocate handle for the result in the current handle scope.
+ Handle<JSFunction> result_function(JSFunction{}, isolate);
+
+ const int kNumParams = 2;
+
+ compiler::CodeAssemblerTester asm_tester(
+ isolate, kNumParams + 1, // +1 to include receiver.
+ CodeKind::STUB);
+ {
+ CodeStubAssembler m(asm_tester.state());
+
+ TNode<Map> map = m.CAST(m.Parameter(1));
+ TNode<Name> unique_name = m.CAST(m.Parameter(2));
+
+ Label passed(&m), failed(&m);
+ Label if_found(&m), if_not_found(&m);
+ TVariable<IntPtrT> var_name_index(&m);
+
+ TNode<Uint32T> bit_field3 = m.LoadMapBitField3(map);
+ TNode<DescriptorArray> descriptors = m.LoadMapDescriptors(map);
+
+ m.DescriptorLookup(unique_name, descriptors, bit_field3, &if_found,
+ &var_name_index, &if_not_found);
+
+ m.BIND(&if_found);
+ m.Return(m.SmiTag(var_name_index.value()));
+
+ m.BIND(&if_not_found);
+ m.Return(m.NullConstant());
+ }
+
+ {
+ compiler::FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
+ // Copy function value to a handle created in the outer handle scope.
+ *(result_function.location()) = ft.function->ptr();
+ }
+
+ return result_function;
+}
+
+// Creates function with (TransitionArray, Name) arguments. Returns transition
+// map if transition is found or null otherwise.
+Handle<JSFunction> CreateCsaTransitionArrayLookup(Isolate* isolate) {
+ // We are not allowed to generate code in jitless mode.
+ if (FLAG_jitless) return Handle<JSFunction>();
+
+ // Preallocate handle for the result in the current handle scope.
+ Handle<JSFunction> result_function(JSFunction{}, isolate);
+
+ const int kNumParams = 2;
+ compiler::CodeAssemblerTester asm_tester(
+ isolate, kNumParams + 1, // +1 to include receiver.
+ CodeKind::STUB);
+ {
+ CodeStubAssembler m(asm_tester.state());
+
+ TNode<TransitionArray> transitions = m.CAST(m.Parameter(1));
+ TNode<Name> unique_name = m.CAST(m.Parameter(2));
+
+ Label passed(&m), failed(&m);
+ Label if_found(&m), if_not_found(&m);
+ TVariable<IntPtrT> var_name_index(&m);
+
+ m.TransitionLookup(unique_name, transitions, &if_found, &var_name_index,
+ &if_not_found);
+
+ m.BIND(&if_found);
+ {
+ STATIC_ASSERT(kData == 0);
+ STATIC_ASSERT(NONE == 0);
+ const int kKeyToTargetOffset = (TransitionArray::kEntryTargetIndex -
+ TransitionArray::kEntryKeyIndex) *
+ kTaggedSize;
+ TNode<Map> transition_map = m.CAST(m.GetHeapObjectAssumeWeak(
+ m.LoadArrayElement(transitions, WeakFixedArray::kHeaderSize,
+ var_name_index.value(), kKeyToTargetOffset)));
+ m.Return(transition_map);
+ }
+
+ m.BIND(&if_not_found);
+ m.Return(m.NullConstant());
+ }
+
+ {
+ compiler::FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
+ // Copy function value to a handle created in the outer handle scope.
+ *(result_function.location()) = ft.function->ptr();
+ }
+
+ return result_function;
+}
+
+} // namespace
+
+TEST(DescriptorArrayHashCollisionMassive) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope handle_scope(isolate);
+
+ static_assert(Name::kNofHashBitFields == 2, "This test needs updating");
+
+ std::vector<Handle<Name>> names;
+
+ // Use the same hash value for all names.
+ uint32_t hash =
+ static_cast<uint32_t>(isolate->GenerateIdentityHash(Name::kHashBitMask));
+
+ for (int i = 0; i < kMaxNumberOfDescriptors / 2; ++i) {
+ // Add pairs of names having the same base hash value but having different
+ // values of is_integer bit.
+ bool first_is_integer = (i & 1) != 0;
+ bool second_is_integer = (i & 2) != 0;
+
+ names.push_back(NewNameWithHash(isolate, "a", hash, first_is_integer));
+ names.push_back(NewNameWithHash(isolate, "b", hash, second_is_integer));
+ }
+
+ // Create descriptor array with the created names by appending fields to some
+ // map. DescriptorArray marking relies on the fact that it's attached to an
+ // owning map.
+ Handle<Map> map = Map::Create(isolate, 0);
+
+ Handle<FieldType> any_type = FieldType::Any(isolate);
+
+ for (size_t i = 0; i < names.size(); ++i) {
+ map = Map::CopyWithField(isolate, map, names[i], any_type, NONE,
+ PropertyConstness::kMutable,
+ Representation::Tagged(), OMIT_TRANSITION)
+ .ToHandleChecked();
+ }
+
+ Handle<JSFunction> csa_lookup = CreateCsaDescriptorArrayLookup(isolate);
+
+ CheckDescriptorArrayLookups(isolate, map, names, csa_lookup);
+
+ // Sort descriptor array and check it again.
+ map->instance_descriptors().Sort();
+ CheckDescriptorArrayLookups(isolate, map, names, csa_lookup);
+}
+
+TEST(DescriptorArrayHashCollision) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope handle_scope(isolate);
+
+ static_assert(Name::kNofHashBitFields == 2, "This test needs updating");
+
+ std::vector<Handle<Name>> names;
+ uint32_t hash = 0;
+
+ for (int i = 0; i < kMaxNumberOfDescriptors / 2; ++i) {
+ if (i % 2 == 0) {
+ // Change hash value for every pair of names.
+ hash = static_cast<uint32_t>(
+ isolate->GenerateIdentityHash(Name::kHashBitMask));
+ }
+
+ // Add pairs of names having the same base hash value but having different
+ // values of is_integer bit.
+ bool first_is_integer = (i & 1) != 0;
+ bool second_is_integer = (i & 2) != 0;
+
+ names.push_back(NewNameWithHash(isolate, "a", hash, first_is_integer));
+ names.push_back(NewNameWithHash(isolate, "b", hash, second_is_integer));
+ }
+
+ // Create descriptor array with the created names by appending fields to some
+ // map. DescriptorArray marking relies on the fact that it's attached to an
+ // owning map.
+ Handle<Map> map = Map::Create(isolate, 0);
+
+ Handle<FieldType> any_type = FieldType::Any(isolate);
+
+ for (size_t i = 0; i < names.size(); ++i) {
+ map = Map::CopyWithField(isolate, map, names[i], any_type, NONE,
+ PropertyConstness::kMutable,
+ Representation::Tagged(), OMIT_TRANSITION)
+ .ToHandleChecked();
+ }
+
+ Handle<JSFunction> csa_lookup = CreateCsaDescriptorArrayLookup(isolate);
+
+ CheckDescriptorArrayLookups(isolate, map, names, csa_lookup);
+
+ // Sort descriptor array and check it again.
+ map->instance_descriptors().Sort();
+ CheckDescriptorArrayLookups(isolate, map, names, csa_lookup);
+}
+
+TEST(TransitionArrayHashCollisionMassive) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope handle_scope(isolate);
+
+ static_assert(Name::kNofHashBitFields == 2, "This test needs updating");
+
+ std::vector<Handle<Name>> names;
+
+ // Use the same hash value for all names.
+ uint32_t hash =
+ static_cast<uint32_t>(isolate->GenerateIdentityHash(Name::kHashBitMask));
+
+ for (int i = 0; i < TransitionsAccessor::kMaxNumberOfTransitions / 2; ++i) {
+ // Add pairs of names having the same base hash value but having different
+ // values of is_integer bit.
+ bool first_is_integer = (i & 1) != 0;
+ bool second_is_integer = (i & 2) != 0;
+
+ names.push_back(NewNameWithHash(isolate, "a", hash, first_is_integer));
+ names.push_back(NewNameWithHash(isolate, "b", hash, second_is_integer));
+ }
+
+ // Create transitions for each name.
+ Handle<Map> root_map = Map::Create(isolate, 0);
+
+ std::vector<Handle<Map>> maps;
+
+ Handle<FieldType> any_type = FieldType::Any(isolate);
+
+ for (size_t i = 0; i < names.size(); ++i) {
+ Handle<Map> map =
+ Map::CopyWithField(isolate, root_map, names[i], any_type, NONE,
+ PropertyConstness::kMutable,
+ Representation::Tagged(), INSERT_TRANSITION)
+ .ToHandleChecked();
+ maps.push_back(map);
+ }
+
+ Handle<JSFunction> csa_lookup = CreateCsaTransitionArrayLookup(isolate);
+
+ Handle<TransitionArray> transition_array(
+ TestTransitionsAccessor(isolate, root_map).transitions(), isolate);
+
+ CheckTransitionArrayLookups(isolate, transition_array, maps, csa_lookup);
+
+ // Sort transition array and check it again.
+ transition_array->Sort();
+ CheckTransitionArrayLookups(isolate, transition_array, maps, csa_lookup);
+}
+
+TEST(TransitionArrayHashCollision) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope handle_scope(isolate);
+
+ static_assert(Name::kNofHashBitFields == 2, "This test needs updating");
+
+ std::vector<Handle<Name>> names;
+
+ // Use the same hash value for all names.
+ uint32_t hash =
+ static_cast<uint32_t>(isolate->GenerateIdentityHash(Name::kHashBitMask));
+
+ for (int i = 0; i < TransitionsAccessor::kMaxNumberOfTransitions / 2; ++i) {
+ if (i % 2 == 0) {
+ // Change hash value for every pair of names.
+ hash = static_cast<uint32_t>(
+ isolate->GenerateIdentityHash(Name::kHashBitMask));
+ }
+ // Add pairs of names having the same base hash value but having different
+ // values of is_integer bit.
+ bool first_is_integer = (i & 1) != 0;
+ bool second_is_integer = (i & 2) != 0;
+
+ names.push_back(NewNameWithHash(isolate, "a", hash, first_is_integer));
+ names.push_back(NewNameWithHash(isolate, "b", hash, second_is_integer));
+ }
+
+ // Create transitions for each name.
+ Handle<Map> root_map = Map::Create(isolate, 0);
+
+ std::vector<Handle<Map>> maps;
+
+ Handle<FieldType> any_type = FieldType::Any(isolate);
+
+ for (size_t i = 0; i < names.size(); ++i) {
+ Handle<Map> map =
+ Map::CopyWithField(isolate, root_map, names[i], any_type, NONE,
+ PropertyConstness::kMutable,
+ Representation::Tagged(), INSERT_TRANSITION)
+ .ToHandleChecked();
+ maps.push_back(map);
+ }
+
+ Handle<JSFunction> csa_lookup = CreateCsaTransitionArrayLookup(isolate);
+
+ Handle<TransitionArray> transition_array(
+ TestTransitionsAccessor(isolate, root_map).transitions(), isolate);
+
+ CheckTransitionArrayLookups(isolate, transition_array, maps, csa_lookup);
+
+ // Sort transition array and check it again.
+ transition_array->Sort();
+ CheckTransitionArrayLookups(isolate, transition_array, maps, csa_lookup);
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/test/cctest/test-transitions.h b/test/cctest/test-transitions.h
index 724eb3d3c544b5e9535e7a1b14d95eccec34f4cc..66bbbfa76dd7c2aa4c84363a69705d2564fee8a6 100644
--- a/test/cctest/test-transitions.h
+++ b/test/cctest/test-transitions.h
@@ -24,6 +24,8 @@ class TestTransitionsAccessor : public TransitionsAccessor {
bool IsFullTransitionArrayEncoding() {
return encoding() == kFullTransitionArray;
}
+
+ TransitionArray transitions() { return TransitionsAccessor::transitions(); }
};
} // namespace internal

View File

@@ -0,0 +1,127 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Thibaud Michaud <thibaudm@chromium.org>
Date: Thu, 15 Oct 2020 12:45:34 +0200
Subject: Merged: [codegen] Skip invalid optimization in tail calls
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Preparing for tail call is usually done by emitting the gap moves and
then moving the stack pointer to its new position. An optimization
consists in moving the stack pointer first and transforming some of the
moves into pushes. In the attached case it looks like this (arm):
138 add sp, sp, #40
13c str r6, [sp, #-4]!
140 str r6, [sp, #-4]!
144 str r6, [sp, #-4]!
148 str r6, [sp, #-4]!
14c str r6, [sp, #-4]!
...
160 vldr d1, [sp - 4*3]
The last line is a gap reload, but because the stack pointer was already
moved, the slot is now below the stack pointer. This is invalid and
triggers this DCHECK:
Fatal error in ../../v8/src/codegen/arm/assembler-arm.cc, line 402
Debug check failed: 0 <= offset (0 vs. -12).
A comment already explains that we skip the optimization if the gap
contains stack moves to prevent this, but the code only checks for
non-FP slots. This is fixed by replacing "source.IsStackSlot()" with
"source.IsAnyStackSlot()":
108 vldr d1, [sp + 4*2]
...
118 str r0, [sp, #+36]
11c str r0, [sp, #+32]
120 str r0, [sp, #+28]
124 str r0, [sp, #+24]
128 str r0, [sp, #+20]
...
134 add sp, sp, #20
TBR=jgruber@chromium.org
(cherry picked from commit 7506e063d0d7fb00e4b9c06735c91e1953296867)
Change-Id: I66ed6187755af956e245207e940c83ea0697a5e6
Bug: chromium:1137608
No-Try: true
No-Presubmit: true
No-Tree-Checks: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2505976
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/branch-heads/8.6@{#42}
Cr-Branched-From: a64aed2333abf49e494d2a5ce24bbd14fff19f60-refs/heads/8.6.395@{#1}
Cr-Branched-From: a626bc036236c9bf92ac7b87dc40c9e538b087e3-refs/heads/master@{#69472}
diff --git a/src/compiler/backend/code-generator.cc b/src/compiler/backend/code-generator.cc
index 83dccf69e82dd144a1ca4720947104b1960ae812..5596058c00543744c35da8f55c8ac9563fa15560 100644
--- a/src/compiler/backend/code-generator.cc
+++ b/src/compiler/backend/code-generator.cc
@@ -609,8 +609,8 @@ void CodeGenerator::GetPushCompatibleMoves(Instruction* instr,
// then the full gap resolver must be used since optimization with
// pushes don't participate in the parallel move and might clobber
// values needed for the gap resolve.
- if (source.IsStackSlot() && LocationOperand::cast(source).index() >=
- first_push_compatible_index) {
+ if (source.IsAnyStackSlot() && LocationOperand::cast(source).index() >=
+ first_push_compatible_index) {
pushes->clear();
return;
}
diff --git a/test/mjsunit/regress/wasm/regress-1137608.js b/test/mjsunit/regress/wasm/regress-1137608.js
new file mode 100644
index 0000000000000000000000000000000000000000..5011dced2f70ffbe2b6096a4e1863f434c8898a8
--- /dev/null
+++ b/test/mjsunit/regress/wasm/regress-1137608.js
@@ -0,0 +1,46 @@
+// 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: --no-liftoff --experimental-wasm-return-call --experimental-wasm-threads
+
+load("test/mjsunit/wasm/wasm-module-builder.js");
+
+(function Regress1137608() {
+ print(arguments.callee.name);
+ let builder = new WasmModuleBuilder();
+ let sig0 = builder.addType(kSig_i_iii);
+ let sig1 = builder.addType(makeSig([kWasmF64, kWasmF64, kWasmI32,
+ kWasmI32, kWasmI32, kWasmF32, kWasmI32, kWasmF64, kWasmI32, kWasmF32,
+ kWasmI32, kWasmF32, kWasmI32, kWasmF64, kWasmI32], [kWasmI32]));
+ let main = builder.addFunction("main", sig0)
+ .addBody([
+ kExprI64Const, 0,
+ kExprF64UConvertI64,
+ kExprF64Const, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00,
+ kExprF64Const, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+ kExprF64Mul,
+ kExprI32Const, 0,
+ kExprF64Const, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ kExprF64StoreMem, 0x00, 0xb0, 0xe0, 0xc0, 0x81, 0x03,
+ kExprI32Const, 0,
+ kExprI32Const, 0,
+ kExprI32Const, 0,
+ kExprF32Const, 0x00, 0x00, 0x00, 0x00,
+ kExprI32Const, 0,
+ kExprF64Const, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ kExprI32Const, 0,
+ kExprF32Const, 0x00, 0x00, 0x00, 0x00,
+ kExprI32Const, 0,
+ kExprF32Const, 0x00, 0x00, 0x00, 0x00,
+ kExprI32Const, 0,
+ kExprF64Const, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ kExprI32Const, 0,
+ kExprI32Const, 2,
+ kExprReturnCallIndirect, sig1, kTableZero]).exportFunc();
+ builder.addFunction("f", sig1).addBody([kExprI32Const, 0]);
+ builder.addTable(kWasmAnyFunc, 4, 4);
+ builder.addMemory(16, 32, false, true);
+ let module = new WebAssembly.Module(builder.toBuffer());
+ let instance = new WebAssembly.Instance(module);
+})();

View File

@@ -0,0 +1,134 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Charles Kerr <charles@charleskerr.com>
Date: Mon, 26 Oct 2020 16:53:25 -0500
Subject: perf: make GetPositionInfoSlow() faster
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Halve the number of lookups in ExtractLocationForJSFunction() by calling
GetPositionInfo() directly instead of making separate calls for column
and line number.
Improve the efficiency of position lookups in slow mode. The current
code does a linear walk through the source by calling String::Get() for
each character. This PR also does a linear walk, but avoids the overhead
of multiple Get() calls by pulling the String's flat content into a
local vector and walking through that.
Downstream Electron discussion of this can be found at
https://github.com/electron/electron/issues/24509
Change-Id: I22b034dc1bfe967164d2f8515a9a0c1d7f043c83
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2496065
Commit-Queue: Simon Zünd <szuend@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Simon Zünd <szuend@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70783}
diff --git a/AUTHORS b/AUTHORS
index 7c43c60fc13af2a793547a9e5ef689e380ef565f..31a46b9bec0757c78650124793ba30def5f438f7 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -69,6 +69,7 @@ Bert Belder <bertbelder@gmail.com>
Burcu Dogan <burcujdogan@gmail.com>
Caitlin Potter <caitpotter88@gmail.com>
Craig Schlenter <craig.schlenter@gmail.com>
+Charles Kerr <charles@charleskerr.com>
Chengzhong Wu <legendecas@gmail.com>
Choongwoo Han <cwhan.tunz@gmail.com>
Chris Nardi <hichris123@gmail.com>
diff --git a/src/objects/objects.cc b/src/objects/objects.cc
index 3ef1067d9f956cba708475aa2beb87dcc5df261b..5e0c831f73b6ccbe40c556497f5ba6fbc9f42b48 100644
--- a/src/objects/objects.cc
+++ b/src/objects/objects.cc
@@ -4785,30 +4785,43 @@ bool Script::ContainsAsmModule() {
}
namespace {
-bool GetPositionInfoSlow(const Script script, int position,
- Script::PositionInfo* info) {
- if (!script.source().IsString()) return false;
- if (position < 0) position = 0;
- String source_string = String::cast(script.source());
+template <typename Char>
+bool GetPositionInfoSlowImpl(const Vector<Char>& source, int position,
+ Script::PositionInfo* info) {
+ if (position < 0) {
+ position = 0;
+ }
int line = 0;
- int line_start = 0;
- int len = source_string.length();
- for (int pos = 0; pos <= len; ++pos) {
- if (pos == len || source_string.Get(pos) == '\n') {
- if (position <= pos) {
- info->line = line;
- info->column = position - line_start;
- info->line_start = line_start;
- info->line_end = pos;
- return true;
- }
- line++;
- line_start = pos + 1;
+ const auto begin = std::cbegin(source);
+ const auto end = std::cend(source);
+ for (auto line_begin = begin; line_begin < end;) {
+ const auto line_end = std::find(line_begin, end, '\n');
+ if (position <= (line_end - begin)) {
+ info->line = line;
+ info->column = static_cast<int>((begin + position) - line_begin);
+ info->line_start = static_cast<int>(line_begin - begin);
+ info->line_end = static_cast<int>(line_end - begin);
+ return true;
}
+ ++line;
+ line_begin = line_end + 1;
}
return false;
}
+bool GetPositionInfoSlow(const Script script, int position,
+ const DisallowHeapAllocation& no_gc,
+ Script::PositionInfo* info) {
+ if (!script.source().IsString()) {
+ return false;
+ }
+ auto source = String::cast(script.source());
+ const auto flat = source.GetFlatContent(no_gc);
+ return flat.IsOneByte()
+ ? GetPositionInfoSlowImpl(flat.ToOneByteVector(), position, info)
+ : GetPositionInfoSlowImpl(flat.ToUC16Vector(), position, info);
+}
+
} // namespace
bool Script::GetPositionInfo(int position, PositionInfo* info,
@@ -4830,7 +4843,9 @@ bool Script::GetPositionInfo(int position, PositionInfo* info,
if (line_ends().IsUndefined()) {
// Slow mode: we do not have line_ends. We have to iterate through source.
- if (!GetPositionInfoSlow(*this, position, info)) return false;
+ if (!GetPositionInfoSlow(*this, position, no_allocation, info)) {
+ return false;
+ }
} else {
DCHECK(line_ends().IsFixedArray());
FixedArray ends = FixedArray::cast(line_ends());
diff --git a/src/profiler/heap-snapshot-generator.cc b/src/profiler/heap-snapshot-generator.cc
index 2fa4f2e5e841bbbf98580dee241fac00899e780e..8f98451488052ba34a59635b707aa5bd3d086161 100644
--- a/src/profiler/heap-snapshot-generator.cc
+++ b/src/profiler/heap-snapshot-generator.cc
@@ -573,9 +573,9 @@ void V8HeapExplorer::ExtractLocationForJSFunction(HeapEntry* entry,
Script script = Script::cast(func.shared().script());
int scriptId = script.id();
int start = func.shared().StartPosition();
- int line = script.GetLineNumber(start);
- int col = script.GetColumnNumber(start);
- snapshot_->AddLocation(entry, scriptId, line, col);
+ Script::PositionInfo info;
+ script.GetPositionInfo(start, &info, Script::WITH_OFFSET);
+ snapshot_->AddLocation(entry, scriptId, info.line, info.column);
}
HeapEntry* V8HeapExplorer::AddEntry(HeapObject object) {

View File

@@ -1,7 +1,7 @@
[req]
default_bits = 4096
encrypt_key = no
default_md = 512
default_md = sha512
distinguished_name = req_distinguished_name
prompt = no

View File

@@ -145,7 +145,6 @@
"parallel/test-v8-flags",
"parallel/test-vm-module-basic",
"parallel/test-vm-parse-abort-on-uncaught-exception",
"parallel/test-vm-sigint",
"parallel/test-vm-sigint-existing-handler",
"parallel/test-vm-timeout",
"parallel/test-whatwg-encoding-custom-textdecoder",

41
script/push-patch.js Normal file
View File

@@ -0,0 +1,41 @@
const { createAppAuth } = require('@octokit/auth-app');
const cp = require('child_process');
if (!process.env.CIRCLE_BRANCH) {
console.error('Not building for a specific branch, can\'t autopush a patch');
process.exit(1);
}
if (process.env.CIRCLE_PR_NUMBER) {
console.error('Building for a forked PR, can\'t autopush a patch');
process.exit(1);
}
const auth = createAppAuth({
appId: process.env.PATCH_UP_APP_ID,
privateKey: Buffer.from(process.env.PATCH_UP_PRIVATE_KEY, 'base64').toString('utf8'),
installationId: process.env.PATCH_UP_INSTALLATION_ID,
clientId: process.env.PATCH_UP_CLIENT_ID,
clientSecret: process.env.PATCH_UP_CLIENT_SECRET
});
async function main () {
const installationAuth = await auth({ type: 'installation' });
const remoteURL = `https://x-access-token:${installationAuth.token}@github.com/electron/electron.git`;
// NEVER LOG THE OUTPUT OF THIS COMMAND
// GIT LEAKS THE ACCESS CREDENTIALS IN CONSOLE LOGS
const { status } = cp.spawnSync('git', ['push', '--set-upstream', remoteURL], {
stdio: 'ignore'
});
if (status !== 0) {
console.error('Failed to push to target branch');
process.exit(1);
}
}
if (process.mainModule === module) {
main().catch((err) => {
console.error(err);
process.exit(1);
});
}

View File

@@ -379,6 +379,7 @@ async function getBranchNameOfRef (ref, dir) {
return (await runGit(dir, ['branch', '--all', '--contains', ref, '--sort', 'version:refname']))
.split(/\r?\n/) // split into lines
.shift() // we sorted by refname and want the first result
.match(/(?:\s?\*\s){0,1}(.*)/)[1] // if present, remove leading '* ' in case we're currently in that branch
.match(/(?:.*\/)?(.*)/)[1] // 'remote/origins/10-x-y' -> '10-x-y'
.trim();
}
@@ -396,7 +397,7 @@ const getNotes = async (fromRef, toRef, newVersion) => {
const pool = new Pool();
const toBranch = await getBranchNameOfRef(toRef, ELECTRON_DIR);
console.log(`Generating release notes between ${fromRef} and ${toRef} for version ${newVersion} in branch ${toBranch}`);
console.log(`Generating release notes between '${fromRef}' and '${toRef}' for version '${newVersion}' in branch '${toBranch}'`);
// get the electron/electron commits
const electron = { owner: 'electron', repo: 'electron', dir: ELECTRON_DIR };

View File

@@ -29,6 +29,8 @@ PDB_LIST = [
os.path.join(RELEASE_DIR, '{0}.exe.pdb'.format(PROJECT_NAME))
]
PDB_LIST += glob.glob(os.path.join(RELEASE_DIR, '*.dll.pdb'))
NPX_CMD = "npx"
if sys.platform == "win32":
NPX_CMD += ".cmd"

View File

@@ -50,7 +50,7 @@ function uploadToGitHub () {
console.log(`Error uploading ${fileName} to GitHub, will retry. Error was:`, err);
retry++;
octokit.repos.listAssetsForRelease({
octokit.repos.listReleaseAssets({
owner: 'electron',
repo: targetRepo,
release_id: releaseId,

View File

@@ -20,7 +20,7 @@ sys.path.append(
from io import StringIO
from zipfile import ZipFile
from lib.config import PLATFORM, get_target_arch, get_env_var, s3_config, \
get_zip_name
get_zip_name, enable_verbose_mode, get_platform_key
from lib.util import get_electron_branding, execute, get_electron_version, \
scoped_cwd, s3put, get_electron_exec, \
get_out_dir, SRC_DIR, ELECTRON_DIR
@@ -44,7 +44,9 @@ TOOLCHAIN_PROFILE_NAME = get_zip_name(PROJECT_NAME, ELECTRON_VERSION, 'toolchain
def main():
args = parse_args()
if args.upload_to_s3:
if args.verbose:
enable_verbose_mode()
if args.upload_to_s3:
utcnow = datetime.datetime.utcnow()
args.upload_timestamp = utcnow.strftime('%Y%m%d')
@@ -76,11 +78,13 @@ def main():
shutil.copy2(os.path.join(OUT_DIR, 'symbols.zip'), symbols_zip)
upload_electron(release, symbols_zip, args)
if PLATFORM == 'darwin':
api_path = os.path.join(ELECTRON_DIR, 'electron-api.json')
upload_electron(release, api_path, args)
if get_platform_key() == 'darwin' and get_target_arch() == 'x64':
api_path = os.path.join(ELECTRON_DIR, 'electron-api.json')
upload_electron(release, api_path, args)
ts_defs_path = os.path.join(ELECTRON_DIR, 'electron.d.ts')
upload_electron(release, ts_defs_path, args)
ts_defs_path = os.path.join(ELECTRON_DIR, 'electron.d.ts')
upload_electron(release, ts_defs_path, args)
dsym_zip = os.path.join(OUT_DIR, DSYM_NAME)
shutil.copy2(os.path.join(OUT_DIR, 'dsym.zip'), dsym_zip)
upload_electron(release, dsym_zip, args)
@@ -149,6 +153,9 @@ def parse_args():
action='store_true',
default=False,
required=False)
parser.add_argument('--verbose',
action='store_true',
help='Mooooorreee logs')
return parser.parse_args()

View File

@@ -8,10 +8,6 @@
#include <memory>
#include <string>
#if defined(OS_LINUX)
#include <glib.h> // for g_setenv()
#endif
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "base/environment.h"
@@ -39,7 +35,6 @@
#include "shell/renderer/electron_renderer_client.h"
#include "shell/renderer/electron_sandboxed_renderer_client.h"
#include "shell/utility/electron_content_utility_client.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h"
@@ -112,12 +107,8 @@ void InvalidParameterHandler(const wchar_t*,
}
#endif
} // namespace
// TODO(nornagon): move path provider overriding to its own file in
// shell/common
namespace electron {
bool GetDefaultCrashDumpsPath(base::FilePath* path) {
base::FilePath cur;
if (!base::PathService::Get(DIR_USER_DATA, &cur))
@@ -147,12 +138,11 @@ void RegisterPathProvider() {
PATH_END);
}
} // namespace electron
} // namespace
void LoadResourceBundle(const std::string& locale) {
std::string LoadResourceBundle(const std::string& locale) {
const bool initialized = ui::ResourceBundle::HasSharedInstance();
if (initialized)
ui::ResourceBundle::CleanupSharedInstance();
DCHECK(!initialized);
// Load other resource files.
base::FilePath pak_dir;
@@ -163,12 +153,12 @@ void LoadResourceBundle(const std::string& locale) {
base::PathService::Get(base::DIR_MODULE, &pak_dir);
#endif
ui::ResourceBundle::InitSharedInstanceWithLocale(
std::string loaded_locale = ui::ResourceBundle::InitSharedInstanceWithLocale(
locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
bundle.ReloadLocaleResources(locale);
bundle.AddDataPackFromPath(pak_dir.Append(FILE_PATH_LITERAL("resources.pak")),
ui::SCALE_FACTOR_NONE);
return loaded_locale;
}
ElectronMainDelegate::ElectronMainDelegate() = default;
@@ -287,36 +277,6 @@ bool ElectronMainDelegate::BasicStartupComplete(int* exit_code) {
return false;
}
void ElectronMainDelegate::PostEarlyInitialization(bool is_running_tests) {
std::string custom_locale;
ui::ResourceBundle::InitSharedInstanceWithLocale(
custom_locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
auto* cmd_line = base::CommandLine::ForCurrentProcess();
if (cmd_line->HasSwitch(::switches::kLang)) {
const std::string locale = cmd_line->GetSwitchValueASCII(::switches::kLang);
const base::FilePath locale_file_path =
ui::ResourceBundle::GetSharedInstance().GetLocaleFilePath(locale);
if (!locale_file_path.empty()) {
custom_locale = locale;
#if defined(OS_LINUX)
/* When built with USE_GLIB, libcc's GetApplicationLocaleInternal() uses
* glib's g_get_language_names(), which keys off of getenv("LC_ALL") */
g_setenv("LC_ALL", custom_locale.c_str(), TRUE);
#endif
}
}
#if defined(OS_MACOSX)
if (custom_locale.empty())
l10n_util::OverrideLocaleWithCocoaLocale();
#endif
LoadResourceBundle(custom_locale);
ElectronBrowserClient::SetApplicationLocale(
l10n_util::GetApplicationLocale(custom_locale));
}
void ElectronMainDelegate::PreSandboxStartup() {
auto* command_line = base::CommandLine::ForCurrentProcess();

View File

@@ -17,7 +17,7 @@ class TracingSamplerProfiler;
namespace electron {
void LoadResourceBundle(const std::string& locale);
std::string LoadResourceBundle(const std::string& locale);
class ElectronMainDelegate : public content::ContentMainDelegate {
public:
@@ -31,7 +31,6 @@ class ElectronMainDelegate : public content::ContentMainDelegate {
bool BasicStartupComplete(int* exit_code) override;
void PreSandboxStartup() override;
void PreCreateMainMessageLoop() override;
void PostEarlyInitialization(bool is_running_tests) override;
content::ContentBrowserClient* CreateContentBrowserClient() override;
content::ContentGpuClient* CreateContentGpuClient() override;
content::ContentRendererClient* CreateContentRendererClient() override;

View File

@@ -12,7 +12,5 @@
<string>APPL</string>
<key>LSBackgroundOnly</key>
<true/>
<key>LSRequiresNativeExecution</key>
<true/>
</dict>
</plist>

View File

@@ -492,10 +492,10 @@ void OnClientCertificateSelected(
data.c_str(), data.length(), net::X509Certificate::FORMAT_AUTO);
if (!certs.empty()) {
scoped_refptr<net::X509Certificate> cert(certs[0].get());
for (size_t i = 0; i < identities->size(); ++i) {
if (cert->EqualsExcludingChain((*identities)[i]->certificate())) {
for (auto& identity : *identities) {
if (cert->EqualsExcludingChain(identity->certificate())) {
net::ClientCertIdentity::SelfOwningAcquirePrivateKey(
std::move((*identities)[i]),
std::move(identity),
base::BindRepeating(&GotPrivateKey, delegate, std::move(cert)));
break;
}

View File

@@ -4,9 +4,12 @@
#include "shell/browser/api/electron_api_browser_view.h"
#include <vector>
#include "shell/browser/api/electron_api_web_contents.h"
#include "shell/browser/browser.h"
#include "shell/browser/native_browser_view.h"
#include "shell/browser/ui/drag_util.h"
#include "shell/common/color_util.h"
#include "shell/common/gin_converters/gfx_converter.h"
#include "shell/common/gin_helper/dictionary.h"
@@ -63,11 +66,21 @@ BrowserView::BrowserView(gin::Arguments* args,
gin::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
web_preferences.Set("type", "browserView");
gin::Handle<class WebContents> web_contents =
WebContents::Create(isolate, web_preferences);
v8::Local<v8::Value> value;
// Copy the webContents option to webPreferences. This is only used internally
// to implement nativeWindowOpen option.
if (options.Get("webContents", &value)) {
web_preferences.SetHidden("webContents", value);
}
auto web_contents =
WebContents::CreateFromWebPreferences(args->isolate(), web_preferences);
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
api_web_contents_->AddObserver(this);
Observe(web_contents->web_contents());
view_.reset(
@@ -80,6 +93,7 @@ BrowserView::~BrowserView() {
if (api_web_contents_) { // destroy() is called
// Destroy WebContents asynchronously unless app is shutting down,
// because destroy() might be called inside WebContents's event handler.
api_web_contents_->RemoveObserver(this);
api_web_contents_->DestroyWebContents(!Browser::Get()->is_shutting_down());
}
}
@@ -89,6 +103,11 @@ void BrowserView::WebContentsDestroyed() {
web_contents_.Reset();
}
void BrowserView::OnDraggableRegionsUpdated(
const std::vector<mojom::DraggableRegionPtr>& regions) {
view_->UpdateDraggableRegions(regions);
}
// static
gin_helper::WrappableBase* BrowserView::New(gin_helper::ErrorThrower thrower,
gin::Arguments* args) {

View File

@@ -7,10 +7,13 @@
#include <memory>
#include <string>
#include <vector>
#include "content/public/browser/web_contents_observer.h"
#include "gin/handle.h"
#include "shell/browser/extended_web_contents_observer.h"
#include "shell/browser/native_browser_view.h"
#include "shell/common/api/api.mojom.h"
#include "shell/common/gin_helper/error_thrower.h"
#include "shell/common/gin_helper/trackable_object.h"
@@ -31,7 +34,8 @@ namespace api {
class WebContents;
class BrowserView : public gin_helper::TrackableObject<BrowserView>,
public content::WebContentsObserver {
public content::WebContentsObserver,
public ExtendedWebContentsObserver {
public:
static gin_helper::WrappableBase* New(gin_helper::ErrorThrower thrower,
gin::Arguments* args);
@@ -51,6 +55,10 @@ class BrowserView : public gin_helper::TrackableObject<BrowserView>,
// content::WebContentsObserver:
void WebContentsDestroyed() override;
// ExtendedWebContentsObserver:
void OnDraggableRegionsUpdated(
const std::vector<mojom::DraggableRegionPtr>& regions) override;
private:
void SetAutoResize(AutoResizeFlags flags);
void SetBounds(const gfx::Rect& bounds);

Some files were not shown because too many files have changed in this diff Show More