Compare commits

...

150 Commits

Author SHA1 Message Date
Electron Bot
1b8d60305b Bump v10.4.4 2021-04-27 08:00:07 -07:00
Pedro Pontes
1f6e825a9f chore: cherry-pick fe85e04a1797 from chromium (#28798)
* chore: cherry-pick fe85e04a1797 from chromium

* update patches

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-04-27 16:47:26 +09:00
Pedro Pontes
c9774944ba chore: cherry-pick 406ae3e8a9a8 from chromium (#28814)
* chore: cherry-pick 406ae3e8a9a8 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-04-27 10:11:54 +09:00
trop[bot]
99a521ecbe build: fix releases that failed halfway through npm publish actions (#28854)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2021-04-26 20:37:25 -04:00
Pedro Pontes
d3152808bb chore: cherry-pick 8f054c5df2 and de1dbdb608 from chromium (#28823)
* chore: cherry-pick 8f054c5df2 and de1dbdb608 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-04-26 12:35:15 -04:00
Pedro Pontes
3fe97b1b1b chore: cherry-pick 8ebd894186 and 1e35f64725 from v8 (#28811)
* chore: cherry-pick 8ebd894186 and 1e35f64725 from v8

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-04-26 20:09:36 +09:00
Pedro Pontes
95d9d7ddfe chore: cherry-pick fe20b05a0e5e from chromium (#28780)
* chore: cherry-pick fe20b05a0e5e from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-04-26 20:08:57 +09:00
trop[bot]
5593485831 fix: only set backgroundColor in default-app for default index.html (#28840)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-04-26 11:49:43 +02:00
Pedro Pontes
049b1d0817 chore: cherry-pick ffde6ee0e4 from v8 (#28800) 2021-04-26 16:30:37 +09:00
Pedro Pontes
a5e40fea7d chore: cherry-pick 6b84dc72351b from chromium (#28808)
* chore: cherry-pick 6b84dc72351b from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-04-26 09:16:38 +02:00
Pedro Pontes
840ff8d720 chore: cherry-pick 74c9ad9a53 from chromium (#28761) 2021-04-22 10:57:47 -07:00
Pedro Pontes
f8738fb355 chore: cherry-pick 8c3eb9d1c409 from chromium (#28705)
* chore: cherry-pick 8c3eb9d1c409 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-04-21 11:42:27 -04:00
Pedro Pontes
16568d71e4 chore: cherry-pick 6a6361c9f31c from chromium (#28703)
* chore: cherry-pick 6a6361c9f31c from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-04-21 13:18:10 +02:00
Electron Bot
8f1074c204 chore: cherry-pick 512cd5e179f4 from v8 (#28750)
* chore: cherry-pick 512cd5e179f4 from v8

* update patches
2021-04-21 12:29:48 +02:00
Pedro Pontes
0b6842d429 chore: cherry-pick 872b8c13d7 from skia (#28739) 2021-04-21 12:21:04 +02:00
Pedro Pontes
4f4c6a2161 chore: cherry-pick 012e9baf46c9 from chromium (#28725)
* chore: cherry-pick 012e9baf46c9 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-04-20 11:50:10 -04:00
trop[bot]
95b81c16c4 build: read node files as binary files (#28733)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-04-19 19:59:11 -04:00
Pedro Pontes
bb913bc17b chore: cherry-pick 254c7945ee from v8 (#28698) 2021-04-19 09:54:40 -04:00
Pedro Pontes
7c72a36b15 chore: cherry-pick 3c80bb2a594f from chromium (#28690)
* chore: cherry-pick 3c80bb2a594f from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-04-19 09:52:15 -04:00
Electron Bot
792d189241 Bump v10.4.3 2021-04-13 13:36:46 -07:00
Electron Bot
602f65ab5d chore: cherry-pick 02f84c745fc0 from v8 (#28640)
* chore: cherry-pick 02f84c745fc0 from v8

* update patches
2021-04-13 13:29:37 -07:00
trop[bot]
18d60df173 docs: systemPreferences.subscribeWorkspaceNotification return type (#28611)
Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com>
2021-04-12 00:14:36 -07:00
trop[bot]
ce12429814 ci: Add goma fallback flag (#28547)
* ci: fallback to local compile if goma auth fails

* use correct flag

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-04-07 09:47:42 +09:00
trop[bot]
b44be57752 fix: disappearing thumbar after win.hide() (#28388)
* fix: disappearing thumbar after win.hide()

* Add descriptive comment

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-25 12:15:45 -07:00
Pedro Pontes
7d8616b2b7 chore: cherry-pick e1505713dc31 from chromium (#28234) 2021-03-24 09:55:51 +09:00
Electron Bot
35b0e35544 Bump v10.4.2 2021-03-23 08:09:55 -07:00
trop[bot]
93b44837a2 fix: escape URL passed to shell.openExternal on windows (#28339)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2021-03-23 03:00:30 -07:00
Pedro Pontes
e16d593fcb chore: cherry-pick a66dbdcf6493 from chromium (#28299) 2021-03-22 08:09:21 -07:00
trop[bot]
51f9712c8f fix: DesktopCapturer gc'd prior to capture completion (#28279)
desktopCapture.getSources() returns a promise which should resolve
when capturing finishes. Internally it creates an instance of
DesktopCapturer which is responsible for resolving or rejecting
the promise.

Between the time DesktopCapturer starts capturing frames and when
it finishes, it's possible for its handle to be GC'd leading to
it never resolving.

These changes pin the instance of DesktopCapturer until it either
finishes or errors.

fixes #25595

Co-authored-by: samuelmaddock <samuel.maddock@gmail.com>
2021-03-22 11:03:41 +09:00
trop[bot]
36cdfef776 fix: drag region offsets in BrowserViews (#28295)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-22 10:58:42 +09:00
Pedro Pontes
8920fd100e chore: cherry-pick c6d6f7aee733 from chromium (#28250)
* chore: cherry-pick c6d6f7aee733 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-19 10:23:05 +09:00
Pedro Pontes
4142f4e74e chore: cherry-pick 37210e5ab006 from chromium (#28248)
* chore: cherry-pick 37210e5ab006 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-03-18 15:15:59 +09:00
Pedro Pontes
ffd43c97f2 chore: cherry-pick 53c4d05797 and 6e8f04c980 from v8 (#28237)
* cherry-pick 53c4d05797 and 6e8f04c980 from v8

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-03-18 15:15:21 +09:00
Pedro Pontes
a576c92d4b chore: cherry-pick 5651fb858b75 from chromium (#28199)
* chore: cherry-pick 5651fb858b75 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-16 19:20:21 +09:00
Pedro Pontes
9c3da1cb35 chore: cherry-pick b3dc4c4b349d from chromium (#28133)
* chore: cherry-pick b3dc4c4b349d from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-03-15 13:32:29 -04:00
Electron Bot
2e5c33a25b Bump v10.4.1 2021-03-15 10:28:28 -07:00
Pedro Pontes
beca2c5c02 chore: cherry-pick 6e8856624cbb from chromium (#28166)
* chore: cherry-pick 6e8856624cbb from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-15 16:54:55 +09:00
Pedro Pontes
4b24e2b045 chore: cherry-pick b772b48067c4 from chromium (#28098)
* chore: cherry-pick b772b48067c4 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-15 10:23:52 +09:00
Keeley Hammond
1f1ff0e51f fix: documentEdited property on BrowserWindow (#28159) 2021-03-14 17:27:36 -07:00
Pedro Pontes
e744ac042a chore: cherry-pick 3910c9f5cde6 from chromium (#28094)
* chore: cherry-pick 3910c9f5cde6 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-03-13 10:44:05 +09:00
Keeley Hammond
12a9970969 fix: values return from the ctx bridge with dynamic property support should themselves support dynamic properties (#28160)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2021-03-12 17:39:06 -08:00
Pedro Pontes
bb915813d7 chore: cherry-pick a4faa754a9ef from chromium (#28092)
* chore: cherry-pick a4faa754a9ef from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-12 19:44:33 +09:00
Pedro Pontes
2e9a3d6f28 chore: cherry-pick 38781b86f0 from chromium (#28051) 2021-03-12 16:37:59 +09:00
Pedro Pontes
91c465dcea chore: cherry-pick dea071d8b30f from chromium (#28090)
* chore: cherry-pick dea071d8b30f from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-03-10 11:06:03 -05:00
trop[bot]
200e7294de build: call goma_ctl.py ensure_start directly (#28059)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-03-08 19:17:45 -08:00
Pedro Pontes
c2cef0aa02 chore: cherry-pick 7e0e52df283c from chromium (#28047)
* chore: cherry-pick 7e0e52df283c from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-03-08 14:03:59 -05:00
Milan Burda
581b47582f fix: warning when worldSafeExecuteJavaScript is disabled (#27974) 2021-03-05 10:15:37 +09:00
trop[bot]
59951f344b fix: offset browserview drag regions on macOS (#27986)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-04 16:31:49 +09:00
trop[bot]
6e9db782c7 fix: ensure owner window valid (#27946)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-02 09:44:05 -08:00
Shelley Vohr
a64d0713cd fix: set WebContents background color ubiquitously (#27945)
Move it from LoadURL to RenderViewCreated which is present
in all window creation cases and is called early enough to be
relevant from user prespective and after RenderWidgetHostView
is already present.

Co-authored-by: marekharanczyk <48673767+marekharanczyk@users.noreply.github.com>
2021-03-01 13:21:32 -08:00
Shelley Vohr
e7d7c66636 fix: libuv hang when nodeIntegrationInSubframes enabled (#27881) 2021-02-24 18:01:05 +09:00
Michaela Laurencin
c6f8625947 fix: replace default frameName title with null check (#27813) (#27868)
* fix: replace default frameName title with null check (#27521)

* refactor: replace default frameName title with null check

* add isNativeWindowOpen check in makeBrowserWindowOptions

* modify snapshot test files

* replace title with frame-name again for proxy - not native open

* modify proxy snapshot title key-value to come after height key-value

* add nativewindowopen check to null title

* fix lint and json formatting

* reformat test cases for this branch

the merged changes included some rearrangements to the json items that
do not apply to this branch, so the items were reordered according to
this branch's previous files.

* remove default frameName title for native open call and modify test txts
2021-02-23 10:26:01 -05:00
trop[bot]
1c198eef50 fix: cap sendInputEvent text length at n-1 (#27854)
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-02-22 14:01:21 -08:00
Electron Bot
dc664acab2 Bump v10.4.0 2021-02-19 11:56:33 -08:00
Keeley Hammond
6b89037dea Revert "perf: patch libuv to use posix_spawn on macOS (#27655)" (#27811)
This reverts commit afb74be01a.
2021-02-19 10:00:45 -08:00
trop[bot]
d3e828cc4e docs: update menu item '&' escaping (#27816)
Co-authored-by: mlaurencin <mlaurencin@electronjs.org>
2021-02-19 09:45:03 -08:00
trop[bot]
acabbf22fe fix: don't create last saved path if none exists (#27807)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-02-19 15:44:28 +09:00
trop[bot]
ee95a258b3 fix: restore window event redispatching on mac (#27812)
Co-authored-by: clavin <cwatford@slack-corp.com>
2021-02-19 15:42:02 +09:00
Robo
072bec5d01 chore: cherry-pick b712f9fd66 from chromium (#27796)
Backports https://chromium-review.googlesource.com/c/chromium/src/+/2690730
2021-02-18 17:59:11 -08:00
Robo
c3da53d3c0 chore: cherry-pick 62bda83979 from chromium (#27795)
Backports https://chromium-review.googlesource.com/c/chromium/src/+/2651183
2021-02-18 15:33:47 -08:00
trop[bot]
2345ff0644 fix: enableBlinkFeatures warning in webviews (#27788)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-02-18 14:06:56 -08:00
Robo
a217df4a9d chore: cherry-pick 59f3ca2780 from chromium (#27794)
Backports https://chromium-review.googlesource.com/c/chromium/src/+/2679121
2021-02-18 13:59:39 -08:00
Robo
4de0f99073 chore: cherry-pick 84853ff62a from v8 (#27793)
Backports https://chromium-review.googlesource.com/c/v8/v8/+/2689191
2021-02-18 13:19:48 -08:00
Robo
4f3b520516 chore: cherry-pick 3a6f6fbfd8 from chromium (#27791)
Backports https://chromium-review.googlesource.com/c/chromium/src/+/2692927
2021-02-18 13:18:59 -08:00
Eryk Rakowski
4293389679 feat: add win.setTopBrowserView() so that BrowserViews can be raised (#27711)
* feat: add `win.setTopBrowserView()` so that BrowserViews can be raised (#27007)

* feat: Raise a browser view via `BrowserWindow.setTopBrowserView()`.

This is similar to removing and re-adding a browser view, but avoids a visible flicker as the browser view is not removed from the window when using `setTopBrowserView`. Note: if the given browser view is not attached to the window, it will be added.

This commit contains the macOS implementation.

* feat: setTopBrowserView support for Windows and Linux

* docs: add info about setTopBrowserView

* docs: Clarify behavior when browserView is not yet attached.

* fix: throw en error when browserView is not attached to the window

* fix: build error

* fix: test

* fix: add test case

* fix: tests

* fix: reparenting

* fix: close second window in tests

Co-authored-by: sentialx <sentialx@gmail.com>

* fix: build error

Co-authored-by: Stewart Lord <stew@offbynone.com>
2021-02-18 19:17:04 +09:00
Jeremy Rose
7c1335ec1c chore: cherry-pick 76cb1cc32baa from chromium (#27749)
* chore: cherry-pick 76cb1cc32baa from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-02-18 10:18:17 +09:00
Cheng Zhao
779efcfa11 fix: check WebContents before emitting render-process-gone event (#27758) 2021-02-17 15:52:05 -08:00
Milan Burda
bd08155093 refactor: load preload script directly as a string (#27741) 2021-02-16 11:40:10 -08:00
trop[bot]
f71c2c78dd ci: ignore errors deleting user app directories on WOA testing (#27727)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-02-15 11:49:07 +09:00
Jeremy Rose
5e30c0ae26 chore: cherry-pick df438f22f7d2 from chromium (#27608)
* chore: cherry-pick df438f22f7d2 from chromium

* fix patch
2021-02-15 09:37:38 +09:00
Jeremy Rose
7966baff5a chore: cherry-pick 9afec1792cfc from chromium (#27611) 2021-02-11 16:35:05 -08:00
Jeremy Rose
986d23d793 chore: cherry-pick b0d3d3e85fa6 from skia (#27613) 2021-02-11 15:59:05 -08:00
trop[bot]
afb74be01a perf: patch libuv to use posix_spawn on macOS (#27655)
* perf: patch libuv to use posix_spawn on macOS

patch libuv to fix a performance regression in macOS >= 11

Spawning child processes in an Electron application with a hardened
runtime has become slow in macOS Big Sur. This patch is a squashed
version of https://github.com/libuv/libuv/pull/3064

This patch should be removed when libuv PR 3064 is merged.

Fixes: https://github.com/libuv/libuv/issues/3050
Fixes: https://github.com/electron/electron/issues/26143
PR-URL: https://github.com/libuv/libuv/pull/3064

Authored-by: Juan Pablo Canepa <jpcanepa@gmail.com>
Co-authored-by: Marcello Bastéa-Forte <marcello@descript.com>
Electron patch prepared by: Pat DeSantis <pdesantis3@gmail.com>

* Remove trailing whitespaces from patch file

* update patches

* Update patch description

* Update .patches

* update patches

Co-authored-by: Pat DeSantis <pdesantis3@gmail.com>
Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Robo <hop2deep@gmail.com>
2021-02-10 16:53:36 -08:00
Shelley Vohr
8068b39ddc fix: Cannot read property 'setDockSide' of undefined (#27691) 2021-02-10 10:58:51 -08:00
Shelley Vohr
e8ae6fe0d0 fix: BrowserView rendering flicker (#27660) 2021-02-09 13:09:51 -08:00
trop[bot]
b5de6d9440 perf: optimize data structures in context_bridge::ObjectCache (#27665)
* Use std::forward_list instead of base::LinkedList for better perf,
more consistent memory management.  Better than std::list because we
don't need the double-linked-list behavior of std::list
* Use std::unordered_map instead of std::map for the v8 hash table

Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2021-02-09 08:32:03 -08:00
trop[bot]
a2f777213d fix: clean up base::LinkedList in context_bridge::ObjectCache (#27637)
base::LinkedList does not delete its members on destruction. We need to
manually ensure the linkedlist is empty when the ObjectCache is
destroyed.

Fixes #27039

Notes: Fixed memory leak when sending non-primitives over the context
bridge

Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2021-02-05 14:25:05 -08:00
Electron Bot
f916f172e0 Bump v10.3.2 2021-02-05 10:08:23 -08:00
Jeremy Rose
6606b743c0 chore: cherry-pick 36abafa0a316 from v8 (#27623) 2021-02-05 09:43:16 -08:00
Andrey Belenko
ee86f029d8 chore: Chromium backports M87-1 (#26932)
* chore: chromium backports M87-1

Contains applicable backports from M87-1 release
CVE-2020-16037
CVE-2020-16041
CVE-2020-16042

* chore: cherry-pick 381c4b5679 from chromium. (#26832)

* fix: message box missing an "OK" button in GTK (#26915)

Co-authored-by: Mimi <1119186082@qq.com>

* chore: cherry-pick d8d64b7cd244 from chromium (#26892)

* chore: cherry-pick 290fe9c6e245 from v8 (#26896)

* docs: add missing deprecated systemPreferences APIs to breaking-changes (#26934)

Co-authored-by: Milan Burda <milan.burda@gmail.com>

* chore: cherry-pick 3abc372c9c00 from chromium (#26894)

* chore: cherry-pick 3abc372c9c00 from chromium

* resolve conflict

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

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

* 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

* Bump v10.2.0

* chore: cherry-pick 6763a713f957 from skia (#26956)

* chore: chromium backports M87-1

PR feedback: add links to changes in the upstream

Co-authored-by: Andrey Belenko <anbelen@microsoft.com>
Co-authored-by: Pedro Pontes <pepontes@microsoft.com>
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Mimi <1119186082@qq.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
Co-authored-by: Biru Mohanathas <birunthan@mohanathas.com>
Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Michaela Laurencin <35157522+mlaurencin@users.noreply.github.com>
2021-02-04 13:46:08 -05:00
trop[bot]
8baf1dc0e5 fix: crash when loadExtension fails (#27590)
Co-authored-by: samuelmaddock <samuel.maddock@gmail.com>
2021-02-03 16:29:09 +09:00
trop[bot]
0827a06b1e docs: Update Readme, don't mention Electron < 2 (#27540)
* chore: Update Readme, don't mention Electron < 2

* chore: Add back versioning info

Co-authored-by: Felix Rieseberg <felix@felixrieseberg.com>
2021-01-29 12:44:12 -08:00
Pedro Pontes
2aec5c5df5 chore: cherry-pick 0d2bf89e15cc from chromium (#27533)
* chore: cherry-pick 0d2bf89e15cc from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-01-29 12:39:43 -08:00
Pedro Pontes
5483733b1b chore: cherry-pick eddb823309 from v8. (#27532) 2021-01-28 14:57:33 -08:00
Milan Burda
52f8f91931 docs: update Xcode / macOS SDK version in build-instructions-macos.md (#27514) 2021-01-28 11:47:14 -08:00
Pedro Pontes
227d6ead6d chore: cherry-pick 442703fe44 from chromium. (#27531) 2021-01-28 13:31:11 -06:00
Erick Zhao
fb4cd68f93 docs: update verb tenses for structured clone notes (#27520) 2021-01-27 11:49:16 -08:00
Electron Bot
7d3db3d7f8 Bump v10.3.1 2021-01-27 11:18:22 -08:00
Pedro Pontes
9510e1f6e4 chore: cherry-pick f9add3b8e5 from chromium. (#27452)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-01-27 20:09:48 +09:00
Pedro Pontes
a396489101 chore: cherry-pick 4af9de9806 and 115eccc0c6 from chromium. (#27495)
* chore: cherry-pick 4af9de9806 and 115eccc0c6 from chromium.

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-01-27 20:09:16 +09:00
Milan Burda
b90f5435a9 fix(asar): readdir(withFileTypes) fails on deep directory (#26865) (#27507)
when using readdirSync on a deep directory within the archive, the code fails to get the stats of child paths.

Co-authored-by: Avi Vahl <avi.vahl@wix.com>
2021-01-27 17:04:34 +09:00
Milan Burda
13a0757acb build: fix build with enable_printing=false (#27456) (#27505) 2021-01-27 16:35:38 +09:00
Pedro Pontes
a5a6f12e1d chore: cherry-pick 9ec949913373 from chromium (#27402)
* chore: cherry-pick 9ec949913373 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-01-26 14:30:30 -08:00
Pedro Pontes
cef56e162f chore: cherry-pick 2c26785, b03de8b and a3c3ef6 from usrsctp. (#27492)
* chore: cherry-pick 2c26785, b03de8b and a3c3ef6 from usrsctp.

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-01-26 14:13:44 -08:00
Pedro Pontes
a73163d09a chore: cherry-pick d74ba931c4b7 from chromium (#27407)
* chore: cherry-pick d74ba931c4b7 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-01-26 09:19:52 -08:00
trop[bot]
2e98e11364 fix: <webview> not working with Trusted Types (#27465)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-01-25 11:47:33 -08:00
tosmolka
0ead47ffea chore: cherry-pick 3ca3d70c7af5 from chromium (#27395)
* chore: cherry-pick 3ca3d70c7af5 from chromium

* update patches

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-01-25 11:29:54 -08:00
tosmolka
1897909a50 chore: cherry-pick 4794770cf175 from chromium (#27394)
* chore: cherry-pick 4794770cf175 from chromium

* update patches
2021-01-25 08:39:19 -08:00
trop[bot]
62b2243574 fix: CSP with unsafe-eval detection with Trusted Types (#27468)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-01-25 08:33:25 -08:00
tosmolka
6e35f2b7dd chore: cherry-pick 861253f1de98 from chromium (#27361)
* chore: cherry-pick 861253f1de98 from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-01-25 13:34:22 +09:00
tosmolka
c4bf95576c chore: cherry-pick da9b5ec032ad from chromium (#27399)
* chore: cherry-pick da9b5ec032ad from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-01-22 11:35:28 -08:00
tosmolka
4005935937 chore: cherry-pick 79440c3a0675 from chromium (#27360)
* chore: cherry-pick 79440c3a0675 from chromium

* Resolve merge conflicts
2021-01-22 11:33:58 -08:00
Pedro Pontes
31fa081da1 chore: cherry-pick ffd6ff5a61b9 from v8 (#27412)
* chore: cherry-pick ffd6ff5a61b9 from v8

* update patches

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-01-21 12:59:06 -08:00
trop[bot]
340b4a2c1e fix: actually clear pending requests in devtoolsagenthost (#27438)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-01-21 12:51:03 -08:00
Pedro Pontes
fd269ec973 chore: cherry-pick 44d052c and 0919d75 from v8. (#27420) 2021-01-21 09:42:55 -08:00
tosmolka
d133ec709f chore: cherry-pick d866af575997 from chromium (#27393)
* chore: cherry-pick d866af575997 from chromium

* update patches
2021-01-21 09:33:52 -08:00
Milan Burda
2b76ac0848 fix: apply tzdata2020f to ICU (#27368)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2021-01-21 15:43:21 +09:00
trop[bot]
726e3f9bb8 fix: Shutdown crash in DownloadItem callback (#27417)
The call stack for one of our top crashes looks like this:

```
node::Abort (node_errors.cc:241)
node::Assert (node_errors.cc:256)
node::MakeCallback (callback.cc:226)
gin_helper::internal::CallMethodWithArgs (event_emitter_caller.cc:23)
gin_helper::EmitEvent<T> (event_emitter_caller.h:51)
gin_helper::EventEmitterMixin<T>::Emit<T> (event_emitter_mixin.h:81)
electron::api::DownloadItem::OnDownloadUpdated (electron_api_download_item.cc:115)
download::DownloadItemImpl::UpdateObservers (download_item_impl.cc:482)
content::DownloadManagerImpl::Shutdown (download_manager_impl.cc:508)
content::BrowserContext::~BrowserContext (browser_context.cc:476)
```

Full stack here: https://sentry.io/share/issue/9b030a0601b547188181b543c16ecda2/

During browser shutdown, the `DownloadManager` was being cleaned up
*after* the Node environment had already been destroyed. This caused the
`DownloadItem::OnDownloadUpdated` callback to crash when trying to emit
the JS `done` event.

To prevent this, we now manually shut down the `DownloadManager`
earlier. This is also mentioned in the comment on
`DownloadManager::Shutdown`:

```
// Shutdown the download manager. Content calls this when BrowserContext is
// being destructed. If the embedder needs this to be called earlier, it can
// call it. In that case, the delegate's Shutdown() method will only be called
// once.
```

Co-authored-by: Biru Mohanathas <birunthan@mohanathas.com>
2021-01-21 15:29:50 +09:00
tosmolka
bc336e16ef chore: cherry-pick 63166010061d from v8 (#27397)
* chore: cherry-pick 63166010061d from v8

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-01-20 11:34:02 -08:00
tosmolka
1faf18f2d4 chore: cherry-pick 19aeffd4d93f from chromium (#27396)
* chore: cherry-pick 19aeffd4d93f from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-01-20 10:58:10 -08:00
Robo
4a1e299053 fix: increase stack size on windows (#27386) 2021-01-20 13:29:31 -05:00
trop[bot]
ae1f1f2dfa fix: prevent crash when keyboard event immediately precedes calling BrowserWindow.close() (#27358)
* fix: prevent crash when destroyed widget receives keyboard event

Activating a key to close a window will cause a silent crash. Handling the keyboard
event will lead to a nullptr dereferenced in Chromium code if the window widget has
already been destroyed.

* test: ensure BrowserWindow doesn't crash from keyboard events during close

Co-authored-by: samuelmaddock <samuel.maddock@gmail.com>
2021-01-19 15:50:43 +09:00
Shelley Vohr
fe4bc1d568 refactor: use platform-specific TaskRunner to print (#27328) 2021-01-19 15:24:09 +09:00
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
193 changed files with 14426 additions and 315 deletions

View File

@@ -300,23 +300,26 @@ step-setup-goma-for-build: &step-setup-goma-for-build
npm install
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
node -e "require('./src/utils/goma.js').ensure()"
third_party/goma/goma_ctl.py ensure_start
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
echo 'export GOMA_FALLBACK_ON_AUTH_FAILURE=true' >> $BASH_ENV
cd ..
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
@@ -392,8 +395,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
@@ -801,6 +806,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
@@ -1005,7 +1012,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

@@ -1116,6 +1116,19 @@ if (is_mac) {
"//build/config/win:delayloads",
]
if (current_cpu == "x86") {
# Set the initial stack size to 0.5MiB, instead of the 1.5MiB needed by
# Chrome's main thread. This saves significant memory on threads (like
# those in the Windows thread pool, and others) whose stack size we can
# only control through this setting. Because Chrome's main thread needs
# a minimum 1.5 MiB stack, the main thread (in 32-bit builds only) uses
# fibers to switch to a 1.5 MiB stack before running any other code.
ldflags += [ "/STACK:0x80000" ]
} else {
# Increase the initial stack size. The default is 1MB, this is 8MB.
ldflags += [ "/STACK:0x800000" ]
}
# This is to support renaming of electron.exe. node-gyp has hard-coded
# executable names which it will recognise as node. This module definition
# file claims that the electron executable is in fact named "node.exe",

View File

@@ -1 +1 @@
10.1.7
10.4.4

View File

@@ -28,15 +28,12 @@ The preferred method is to install Electron as a development dependency in your
app:
```sh
npm install electron --save-dev [--save-exact]
npm install electron --save-dev
```
The `--save-exact` flag is recommended for Electron prior to version 2, as it does not follow semantic
versioning. As of version 2.0.0, Electron follows semver, so you don't need `--save-exact` flag. For info on how to manage Electron versions in your apps, see
[Electron versioning](docs/tutorial/electron-versioning.md).
For more installation options and troubleshooting tips, see
[installation](docs/tutorial/installation.md).
[installation](docs/tutorial/installation.md). For info on how to manage Electron versions in your apps, see
[Electron versioning](docs/tutorial/electron-versioning.md).
## Quick start & Electron Fiddle

View File

@@ -36,6 +36,7 @@ environment:
ELECTRON_ENABLE_STACK_DUMPING: 1
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
GOMA_FALLBACK_ON_AUTH_FAILURE: true
notifications:
- provider: Webhook
url: https://electron-mission-control.herokuapp.com/rest/appveyor-hook

View File

@@ -92,6 +92,6 @@ steps:
condition: always()
- powershell: |
Remove-Item -path $env:APPDATA/Electron* -Recurse
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore
displayName: 'Delete user app data directories'
condition: always()

View File

@@ -41,14 +41,14 @@ ipcMain.handle('bootstrap', (event) => {
return isTrustedSender(event.sender) ? electronPath : null;
});
async function createWindow () {
async function createWindow (backgroundColor?: string) {
await app.whenReady();
const options: Electron.BrowserWindowConstructorOptions = {
width: 960,
height: 620,
autoHideMenuBar: true,
backgroundColor: '#2f3241',
backgroundColor,
webPreferences: {
preload: path.resolve(__dirname, 'preload.js'),
contextIsolation: true,
@@ -96,7 +96,7 @@ export const loadURL = async (appUrl: string) => {
};
export const loadFile = async (appPath: string) => {
mainWindow = await createWindow();
mainWindow = await createWindow(appPath === 'index.html' ? '#2f3241' : undefined);
mainWindow.loadFile(appPath);
mainWindow.focus();
};

View File

@@ -1829,6 +1829,13 @@ Replacement API for setBrowserView supporting work with multi browser views.
* `browserView` [BrowserView](browser-view.md)
#### `win.setTopBrowserView(browserView)` _Experimental_
* `browserView` [BrowserView](browser-view.md)
Raises `browserView` above other `BrowserView`s attached to `win`.
Throws an error if `browserView` is not attached to `win`.
#### `win.getBrowserViews()` _Experimental_
Returns `BrowserView[]` - an array of all BrowserViews that have been attached

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

@@ -61,9 +61,13 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
throw an exception.
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
> special Electron objects is deprecated, and will begin throwing an exception
> starting with Electron 9.
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
> special Electron objects will throw an exception.
>
> Since the main process does not have support for DOM objects such as
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
> Electron's IPC to the main process, as the main process would have no way to decode
> them. Attempting to send such objects over IPC will result in an error.
The main process handles it by listening for `channel` with the
[`ipcMain`](ipc-main.md) module.
@@ -85,9 +89,13 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
throw an exception.
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
> special Electron objects is deprecated, and will begin throwing an exception
> starting with Electron 9.
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
> special Electron objects will throw an exception.
>
> Since the main process does not have support for DOM objects such as
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
> Electron's IPC to the main process, as the main process would have no way to decode
> them. Attempting to send such objects over IPC will result in an error.
The main process should listen for `channel` with
[`ipcMain.handle()`](ipc-main.md#ipcmainhandlechannel-listener).
@@ -123,9 +131,13 @@ Algorithm][SCA], just like [`window.postMessage`][], so prototype chains will no
included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
throw an exception.
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
> special Electron objects is deprecated, and will begin throwing an exception
> starting with Electron 9.
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
> special Electron objects will throw an exception.
>
> Since the main process does not have support for DOM objects such as
> `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over
> Electron's IPC to the main process, as the main process would have no way to decode
> them. Attempting to send such objects over IPC will result in an error.
The main process handles it by listening for `channel` with [`ipcMain`](ipc-main.md) module,
and replies by setting `event.returnValue`.

View File

@@ -22,8 +22,10 @@ Sets `menu` as the application menu on macOS. On Windows and Linux, the
Also on Windows and Linux, you can use a `&` in the top-level item name to
indicate which letter should get a generated accelerator. For example, using
`&File` for the file menu would result in a generated `Alt-F` accelerator that
opens the associated menu. The indicated character in the button label gets an
underline. The `&` character is not displayed on the button label.
opens the associated menu. The indicated character in the button label then gets an
underline, and the `&` character is not displayed on the button label.
In order to escape the `&` character in an item name, add a proceeding `&`. For example, `&&File` would result in `&File` displayed on the button label.
Passing `null` will suppress the default menu. On Windows and Linux,
this has the additional effect of removing the menu bar from the window.

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

@@ -132,6 +132,8 @@ This is necessary for events such as `NSUserDefaultsDidChangeNotification`.
* `userInfo` Record<String, unknown>
* `object` String
Returns `Number` - The ID of this subscription
Same as `subscribeNotification`, but uses `NSWorkspace.sharedWorkspace.notificationCenter`.
This is necessary for events such as `NSWorkspaceDidActivateApplicationNotification`.

View File

@@ -1549,8 +1549,7 @@ included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will
throw an exception.
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
> special Electron objects is deprecated, and will begin throwing an exception
> starting with Electron 9.
> special Electron objects will throw an exception.
The renderer process can handle the message by listening to `channel` with the
[`ipcRenderer`](ipc-renderer.md) module.
@@ -1586,7 +1585,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[]
@@ -1596,9 +1597,8 @@ Send an asynchronous message to a specific frame in a renderer process via
chains will not be included. Sending Functions, Promises, Symbols, WeakMaps, or
WeakSets will throw an exception.
> **NOTE**: Sending non-standard JavaScript types such as DOM objects or
> special Electron objects is deprecated, and will begin throwing an exception
> starting with Electron 9.
> **NOTE:** Sending non-standard JavaScript types such as DOM objects or
> special Electron objects will throw an exception.
The renderer process can handle the message by listening to `channel` with the
[`ipcRenderer`](ipc-renderer.md) module.
@@ -1760,7 +1760,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 +1858,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

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

@@ -42,7 +42,7 @@ $ pip install pyobjc
If you're developing Electron and don't plan to redistribute your
custom Electron build, you may skip this section.
Official Electron builds are built with [Xcode 9.4.1](http://adcdownload.apple.com/Developer_Tools/Xcode_9.4.1/Xcode_9.4.1.xip), and the macOS 10.13 SDK. Building with a newer SDK works too, but the releases currently use the 10.13 SDK.
Official Electron builds are built with [Xcode 11.1](https://download.developer.apple.com/Developer_Tools/Xcode_11.1/Xcode_11.1.xip), and the macOS 10.15 SDK. Building with a newer SDK works too, but the releases currently use the 10.15 SDK.
## Building Electron

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

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

@@ -45,7 +45,7 @@ Object.defineProperty(TopLevelWindow.prototype, 'kiosk', {
});
Object.defineProperty(TopLevelWindow.prototype, 'documentEdited', {
get: function () { return this.isFullscreen(); },
get: function () { return this.isDocumentEdited(); },
set: function (edited) { this.setDocumentEdited(edited); }
});

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);
};
};
@@ -587,7 +588,6 @@ WebContents.prototype._init = function () {
width: 800,
height: 600,
webContents,
title: frameName,
webPreferences,
...options
};

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

@@ -83,7 +83,7 @@ const getPreloadScript = async function (preloadPath) {
let preloadSrc = null;
let preloadError = null;
try {
preloadSrc = (await fs.promises.readFile(preloadPath)).toString();
preloadSrc = await fs.promises.readFile(preloadPath, 'utf8');
} catch (error) {
preloadError = error;
}

View File

@@ -597,7 +597,13 @@
if (options.withFileTypes) {
const dirents = [];
for (const file of files) {
const stats = archive.stat(file);
const childPath = path.join(filePath, file);
const stats = archive.stat(childPath);
if (!stats) {
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
nextTick(callback, [error]);
return;
}
if (stats.isFile) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
} else if (stats.isDirectory) {
@@ -633,7 +639,11 @@
if (options.withFileTypes) {
const dirents = [];
for (const file of files) {
const stats = archive.stat(file);
const childPath = path.join(filePath, file);
const stats = archive.stat(childPath);
if (!stats) {
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
}
if (stats.isFile) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
} else if (stats.isDirectory) {

View File

@@ -49,7 +49,7 @@ class WebFrame extends EventEmitter {
}
const { hasSwitch } = process.electronBinding('command_line');
const worldSafeJS = hasSwitch('world-safe-execute-javascript') && hasSwitch('context-isolation');
const worldSafeJS = hasSwitch('world-safe-execute-javascript') || !hasSwitch('context-isolation');
// Populate the methods.
for (const name in binding) {

View File

@@ -80,7 +80,7 @@ const isUnsafeEvalEnabled: () => Promise<boolean> = function () {
// Call _executeJavaScript to bypass the world-safe deprecation warning
return (webFrame as any)._executeJavaScript(`(${(() => {
try {
new Function(''); // eslint-disable-line no-new,no-new-func
eval(window.trustedTypes.emptyScript); // eslint-disable-line no-eval
} catch {
return false;
}
@@ -224,7 +224,7 @@ const warnAboutExperimentalFeatures = function (webPreferences?: Electron.WebPre
const warnAboutEnableBlinkFeatures = function (webPreferences?: Electron.WebPreferences) {
if (!webPreferences ||
!Object.prototype.hasOwnProperty.call(webPreferences, 'enableBlinkFeatures') ||
(webPreferences.enableBlinkFeatures && webPreferences.enableBlinkFeatures.length === 0)) {
(webPreferences.enableBlinkFeatures != null && webPreferences.enableBlinkFeatures.length === 0)) {
return;
}

View File

@@ -41,7 +41,9 @@ export class WebViewImpl {
// Create internal iframe element.
this.internalElement = this.createInternalElement();
const shadowRoot = this.webviewNode.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = '<!DOCTYPE html><style type="text/css">:host { display: flex; }</style>';
const style = shadowRoot.ownerDocument!.createElement('style');
style.textContent = ':host { display: flex; }';
shadowRoot.appendChild(style);
this.setupWebViewAttributes();
this.viewInstanceId = getNextId();
shadowRoot.appendChild(this.internalElement);

View File

@@ -1,6 +1,6 @@
{
"name": "electron",
"version": "10.1.7",
"version": "10.4.4",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {

View File

@@ -116,3 +116,59 @@ 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
backport_1142331.patch
backport_1151865.patch
cherry-pick-19aeffd4d93f.patch
cherry-pick-4794770cf175.patch
cherry-pick-79440c3a0675.patch
cherry-pick-d866af575997.patch
cherry-pick-da9b5ec032ad.patch
cherry-pick-861253f1de98.patch
cherry-pick-3ca3d70c7af5.patch
mediacapabilities_use_threadsafe_static_wtf_string.patch
cherry-pick-d74ba931c4b7.patch
cherry-pick-9ec949913373.patch
ots_backport_maxp_sanitization.patch
ots_backport_of_glyf_guard_access_to_maxp_version_1_field.patch
layoutng_fix_an_incorrect_cache-hit_for_line_boxes.patch
cherry-pick-0d2bf89e15cc.patch
cherry-pick-df438f22f7d2.patch
cherry-pick-9afec1792cfc.patch
cherry-pick-76cb1cc32baa.patch
stop_using_raw_webcontents_ptr_in_dragdownloadfile.patch
fix_heap_overflow_in_videoframeyuvconverter.patch
disable_gpu_acceleration_on_all_mesa_software_rasterizers.patch
websocket_don_t_clear_event_queue_on_destruction.patch
cherry-pick-7e0e52df283c.patch
cherry-pick-dea071d8b30f.patch
cherry-pick-a4faa754a9ef.patch
mediarecorder_tolerate_non-gmb_nv12_frames_for_h264.patch
cherry-pick-6e8856624cbb.patch
cherry-pick-b772b48067c4.patch
cherry-pick-3910c9f5cde6.patch
cherry-pick-5651fb858b75.patch
cherry-pick-b3dc4c4b349d.patch
cherry-pick-c6d6f7aee733.patch
cherry-pick-37210e5ab006.patch
reland_reland_fsa_add_issafepathcomponent_checks_to.patch
css_make_fetches_from_inline_css_use_the_document_s_url_as_referrer.patch
cherry-pick-3c80bb2a594f.patch
cherry-pick-6a6361c9f31c.patch
cherry-pick-012e9baf46c9.patch
cherry-pick-8c3eb9d1c409.patch
use_idtype_for_permission_change_subscriptions.patch
cherry-pick-fe85e04a1797.patch
m86-lts_add_null_pointer_check_in_renderwidgethostinputeventrouter.patch
m86-lts_add_weak_pointer_to_rwhier_framesinkidownermap_and.patch
cherry-pick-406ae3e8a9a8.patch
cherry-pick-fe20b05a0e5e.patch
cherry-pick-6b84dc72351b.patch

View File

@@ -0,0 +1,141 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrey Belenko <anbelen@microsoft.com>
Date: Thu, 10 Dec 2020 18:04:03 +0100
Subject: Chromium backport: crbug.com/1142331
M87-1
Clipboard: Fix UaP in ClipboardWriter/FileReaderLoader
https://chromium-review.googlesource.com/c/chromium/src/+/2536946
CVE-2020-16037
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
index fc5f32d86fd2cc4aeeaadddc94da6ce5e8e7990a..9c72fb55426f685045418947427406016d947589 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -104,7 +104,7 @@ ScriptPromise ClipboardPromise::CreateForWriteText(ExecutionContext* context,
ClipboardPromise::ClipboardPromise(ExecutionContext* context,
ScriptState* script_state)
- : ExecutionContextClient(context),
+ : ExecutionContextLifecycleObserver(context),
script_state_(script_state),
script_promise_resolver_(
MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
@@ -483,13 +483,20 @@ scoped_refptr<base::SingleThreadTaskRunner> ClipboardPromise::GetTaskRunner() {
return GetExecutionContext()->GetTaskRunner(TaskType::kUserInteraction);
}
+// ExecutionContextLifecycleObserver implementation.
+void ClipboardPromise::ContextDestroyed() {
+ script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kNotAllowedError, "Document detached."));
+ clipboard_writer_.Clear();
+}
+
void ClipboardPromise::Trace(Visitor* visitor) const {
visitor->Trace(script_state_);
visitor->Trace(script_promise_resolver_);
visitor->Trace(clipboard_writer_);
visitor->Trace(permission_service_);
visitor->Trace(clipboard_item_data_);
- ExecutionContextClient::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
index 18efbc8c632dd7061fb31437529f1b14a25beb3a..307ce3b51a7c75b60301885685f5c0d780997250 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
@@ -26,7 +26,7 @@ class ExecutionContext;
class ClipboardItemOptions;
class ClipboardPromise final : public GarbageCollected<ClipboardPromise>,
- public ExecutionContextClient {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(ClipboardPromise);
public:
@@ -83,6 +83,9 @@ class ClipboardPromise final : public GarbageCollected<ClipboardPromise>,
LocalFrame* GetLocalFrame() const;
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner();
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
+
Member<ScriptState> script_state_;
Member<ScriptPromiseResolver> script_promise_resolver_;
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
index 2891db58d47b30575efd782ae1c7cf8ee7558cc4..4b224c9679ca51c01328479685970235f35a32fd 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
@@ -188,9 +188,12 @@ ClipboardWriter::ClipboardWriter(SystemClipboard* system_clipboard,
file_reading_task_runner_(promise->GetExecutionContext()->GetTaskRunner(
TaskType::kFileReading)),
system_clipboard_(system_clipboard),
- raw_system_clipboard_(raw_system_clipboard) {}
+ raw_system_clipboard_(raw_system_clipboard),
+ self_keep_alive_(PERSISTENT_FROM_HERE, this) {}
-ClipboardWriter::~ClipboardWriter() = default;
+ClipboardWriter::~ClipboardWriter() {
+ DCHECK(!file_reader_);
+}
// static
bool ClipboardWriter::IsValidType(const String& type, bool is_raw) {
@@ -220,7 +223,9 @@ void ClipboardWriter::DidFinishLoading() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DOMArrayBuffer* array_buffer = file_reader_->ArrayBufferResult();
DCHECK(array_buffer);
+
file_reader_.reset();
+ self_keep_alive_.Clear();
worker_pool::PostTask(
FROM_HERE, CrossThreadBindOnce(&ClipboardWriter::DecodeOnBackgroundThread,
@@ -230,6 +235,8 @@ void ClipboardWriter::DidFinishLoading() {
}
void ClipboardWriter::DidFail(FileErrorCode error_code) {
+ file_reader_.reset();
+ self_keep_alive_.Clear();
promise_->RejectFromReadOrDecodeFailure();
}
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.h b/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
index 527b063cd20900653dc37027bef8d24af31fb6de..3de3f5ad34b8ebf378421c64c917e3091e5343c6 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader_client.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
#include "third_party/skia/include/core/SkImage.h"
namespace blink {
@@ -27,6 +28,11 @@ class RawSystemClipboard;
// take advantage of vulnerabilities in their decoders. In
// ClipboardRawDataWriter, this decoding is skipped.
// (3) Writing the blob's decoded contents to the system clipboard.
+//
+// ClipboardWriter is owned only by itself and ClipboardPromise. It keeps
+// itself alive for the duration of FileReaderLoader's async operations using
+// SelfKeepAlive, and keeps itself alive afterwards during cross-thread
+// operations by using WrapCrossThreadPersistent.
class ClipboardWriter : public GarbageCollected<ClipboardWriter>,
public FileReaderLoaderClient {
public:
@@ -80,6 +86,10 @@ class ClipboardWriter : public GarbageCollected<ClipboardWriter>,
Member<SystemClipboard> system_clipboard_;
// Access to the global unsanitized system clipboard.
Member<RawSystemClipboard> raw_system_clipboard_;
+
+ // Oilpan: ClipboardWriter must remain alive until Member<T>::Clear() is
+ // called, to keep the FileReaderLoader alive and avoid unexpected UaPs.
+ SelfKeepAlive<ClipboardWriter> self_keep_alive_;
};
} // namespace blink

View File

@@ -0,0 +1,23 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrey Belenko <anbelen@microsoft.com>
Date: Thu, 10 Dec 2020 22:16:48 +0100
Subject: Chromium backport: crbug.com/1151865
M87-1
Reject mojom::DataElement serialization if array size read failed
https://chromium-review.googlesource.com/c/chromium/src/+/2567130
CVE-2020-16041
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc
index ce1478f6df691d5b1f7862a45ac3989a43e2d814..881bcb23ab3291e61088458f46c446fe9e7fb7cf 100644
--- a/services/network/public/cpp/url_request_mojom_traits.cc
+++ b/services/network/public/cpp/url_request_mojom_traits.cc
@@ -286,6 +286,8 @@ bool StructTraits<network::mojom::DataElementDataView, network::DataElement>::
if (data.type() == network::mojom::DataElementType::kBytes) {
if (!data.ReadBuf(&out->buf_))
return false;
+ if (data.length() != out->buf_.size())
+ return false;
}
out->type_ = data.type();
out->data_pipe_getter_ = data.TakeDataPipeGetter<

View File

@@ -0,0 +1,86 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jana Grill <janagrill@google.com>
Date: Thu, 15 Apr 2021 20:49:42 +0000
Subject: Mojo: Remove some inappropriate DCHECKs
There are a few places where we DCHECK conditions that cannot be
reliably asserted since they depend on untrusted inputs. These are
replaced with logic to conditionally terminate the connection to the
offending peer process.
(cherry picked from commit a32b061fc92cc3864d036ffb8c22c12b05202589)
Fixed: 1195333
Change-Id: I0c6873bf55d6b0b1d0cbb3c2e5b256e1a57ff696
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2808893
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Original-Commit-Position: refs/heads/master@{#870007}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2821958
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1608}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc
index c7646fa4dc5c5062e8a8a620e55839301af51bed..c333ed64f71f0dfe5d0012b07bcedccfd94cd5e9 100644
--- a/mojo/core/node_controller.cc
+++ b/mojo/core/node_controller.cc
@@ -942,7 +942,11 @@ void NodeController::OnBrokerClientAdded(const ports::NodeName& from_node,
void NodeController::OnAcceptBrokerClient(const ports::NodeName& from_node,
const ports::NodeName& broker_name,
PlatformHandle broker_channel) {
- DCHECK(!GetConfiguration().is_broker_process);
+ if (GetConfiguration().is_broker_process) {
+ // The broker should never receive this message from anyone.
+ DropPeer(from_node, nullptr);
+ return;
+ }
// This node should already have an inviter in bootstrap mode.
ports::NodeName inviter_name;
@@ -953,8 +957,13 @@ void NodeController::OnAcceptBrokerClient(const ports::NodeName& from_node,
inviter = bootstrap_inviter_channel_;
bootstrap_inviter_channel_ = nullptr;
}
- DCHECK(inviter_name == from_node);
- DCHECK(inviter);
+
+ if (inviter_name != from_node || !inviter ||
+ broker_name == ports::kInvalidNodeName) {
+ // We are not expecting this message. Assume the source is hostile.
+ DropPeer(from_node, nullptr);
+ return;
+ }
base::queue<ports::NodeName> pending_broker_clients;
std::unordered_map<ports::NodeName, OutgoingMessageQueue>
@@ -965,22 +974,22 @@ void NodeController::OnAcceptBrokerClient(const ports::NodeName& from_node,
std::swap(pending_broker_clients, pending_broker_clients_);
std::swap(pending_relay_messages, pending_relay_messages_);
}
- DCHECK(broker_name != ports::kInvalidNodeName);
// It's now possible to add both the broker and the inviter as peers.
// Note that the broker and inviter may be the same node.
scoped_refptr<NodeChannel> broker;
if (broker_name == inviter_name) {
- DCHECK(!broker_channel.is_valid());
broker = inviter;
- } else {
- DCHECK(broker_channel.is_valid());
+ } else if (broker_channel.is_valid()) {
broker = NodeChannel::Create(
this,
ConnectionParams(PlatformChannelEndpoint(std::move(broker_channel))),
Channel::HandlePolicy::kAcceptHandles, io_task_runner_,
ProcessErrorCallback());
AddPeer(broker_name, broker, true /* start_channel */);
+ } else {
+ DropPeer(from_node, nullptr);
+ return;
}
AddPeer(inviter_name, inviter, false /* start_channel */);

View File

@@ -0,0 +1,148 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sam McNally <sammc@chromium.org>
Date: Thu, 17 Dec 2020 02:58:09 +0000
Subject: Observe ProcessManager shutdowns from KeepAliveImpl.
ExtensionRegistry uses the underlying BrowserContext for incognito
contexts. Thus, for incognito uses, the ProcessManager can be destroyed
without the KeepAliveImpl being notified. Observe ProcessManager
shutdowns directly to ensure KeepAliveImpls are cleaned up when a
ProcessManager is shut down.
[Substituted ScopedObserver for base::ScopedObservation since the latter
was introduced in 88]
(cherry picked from commit 5a55fe16e633dd02e3c40e513acabf4324bb6318)
(cherry picked from commit c2bf2463fbeff3959ea1998a4f3ae82dd648b56c)
Bug: 1149177
Change-Id: I39a0cf54bcf8cf0d58e36560935b8d2f79399cd2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2548585
Auto-Submit: Sam McNally <sammc@chromium.org>
Commit-Queue: Ben Wells <benwells@chromium.org>
Reviewed-by: Ben Wells <benwells@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#830107}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2563379
Reviewed-by: Sam McNally <sammc@chromium.org>
Commit-Queue: Sam McNally <sammc@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4280@{#1653}
Cr-Original-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2587154
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1496}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/extensions/browser/mojo/keep_alive_impl.cc b/extensions/browser/mojo/keep_alive_impl.cc
index 0cc74657805296772e00d98225f8113b69904ac5..a7344015d62c4d84eeeddcf9da6f5d38db7e802c 100644
--- a/extensions/browser/mojo/keep_alive_impl.cc
+++ b/extensions/browser/mojo/keep_alive_impl.cc
@@ -8,7 +8,6 @@
#include "base/bind.h"
#include "content/public/browser/browser_context.h"
-#include "extensions/browser/process_manager.h"
namespace extensions {
@@ -32,6 +31,7 @@ KeepAliveImpl::KeepAliveImpl(content::BrowserContext* context,
receiver_.set_disconnect_handler(
base::BindOnce(&KeepAliveImpl::OnDisconnected, base::Unretained(this)));
extension_registry_observer_.Add(ExtensionRegistry::Get(context_));
+ process_manager_observation_.Add(ProcessManager::Get(context_));
}
KeepAliveImpl::~KeepAliveImpl() = default;
@@ -54,4 +54,8 @@ void KeepAliveImpl::OnDisconnected() {
delete this;
}
+void KeepAliveImpl::OnProcessManagerShutdown(ProcessManager* manager) {
+ delete this;
+}
+
} // namespace extensions
diff --git a/extensions/browser/mojo/keep_alive_impl.h b/extensions/browser/mojo/keep_alive_impl.h
index a3e4233a3e6691999decb281dbaf80f74bf922cc..331fc2fdf670e44d51adc610ee39144dac15ae87 100644
--- a/extensions/browser/mojo/keep_alive_impl.h
+++ b/extensions/browser/mojo/keep_alive_impl.h
@@ -10,6 +10,8 @@
#include "base/scoped_observer.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_registry_observer.h"
+#include "extensions/browser/process_manager.h"
+#include "extensions/browser/process_manager_observer.h"
#include "extensions/common/mojom/keep_alive.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
@@ -21,10 +23,13 @@ class RenderFrameHost;
namespace extensions {
class Extension;
+class ProcessManager;
// An RAII mojo service implementation for extension keep alives. This adds a
// keep alive on construction and removes it on destruction.
-class KeepAliveImpl : public KeepAlive, public ExtensionRegistryObserver {
+class KeepAliveImpl : public KeepAlive,
+ public ExtensionRegistryObserver,
+ public ProcessManagerObserver {
public:
// Create a keep alive for |extension| running in |context| and connect it to
// |receiver|. When the receiver closes its pipe, the keep alive ends.
@@ -45,6 +50,9 @@ class KeepAliveImpl : public KeepAlive, public ExtensionRegistryObserver {
UnloadedExtensionReason reason) override;
void OnShutdown(ExtensionRegistry* registry) override;
+ // ProcessManagerObserver overrides.
+ void OnProcessManagerShutdown(ProcessManager* manager) override;
+
// Invoked when the mojo connection is disconnected.
void OnDisconnected();
@@ -52,6 +60,8 @@ class KeepAliveImpl : public KeepAlive, public ExtensionRegistryObserver {
const Extension* extension_;
ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
extension_registry_observer_{this};
+ ScopedObserver<ProcessManager, ProcessManagerObserver>
+ process_manager_observation_{this};
mojo::Receiver<KeepAlive> receiver_;
DISALLOW_COPY_AND_ASSIGN(KeepAliveImpl);
diff --git a/extensions/browser/mojo/keep_alive_impl_unittest.cc b/extensions/browser/mojo/keep_alive_impl_unittest.cc
index 90599cc46d24dc7ec0eabb1da17545b489d93445..e6f60c39cf29d9554cb0f1096ed87345d3e38923 100644
--- a/extensions/browser/mojo/keep_alive_impl_unittest.cc
+++ b/extensions/browser/mojo/keep_alive_impl_unittest.cc
@@ -160,7 +160,7 @@ TEST_F(KeepAliveTest, UnloadExtension) {
run_loop.Run();
}
-TEST_F(KeepAliveTest, Shutdown) {
+TEST_F(KeepAliveTest, ShutdownExtensionRegistry) {
mojo::Remote<KeepAlive> keep_alive;
CreateKeepAlive(keep_alive.BindNewPipeAndPassReceiver());
EXPECT_EQ(1, GetKeepAliveCount());
@@ -178,4 +178,22 @@ TEST_F(KeepAliveTest, Shutdown) {
run_loop.Run();
}
+TEST_F(KeepAliveTest, ShutdownProcessManager) {
+ mojo::Remote<KeepAlive> keep_alive;
+ CreateKeepAlive(keep_alive.BindNewPipeAndPassReceiver());
+ EXPECT_EQ(1, GetKeepAliveCount());
+ EXPECT_EQ(1u, GetActivities().count(mojo_activity_));
+
+ ProcessManager::Get(browser_context())->Shutdown();
+ // After a shutdown event, the KeepAliveImpl should not access its
+ // ProcessManager and so the keep-alive count should remain unchanged.
+ EXPECT_EQ(1, GetKeepAliveCount());
+ EXPECT_EQ(1u, GetActivities().count(mojo_activity_));
+
+ // Wait for |keep_alive| to disconnect.
+ base::RunLoop run_loop;
+ keep_alive.set_disconnect_handler(run_loop.QuitClosure());
+ run_loop.Run();
+}
+
} // namespace extensions

View File

@@ -0,0 +1,124 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matthew Denton <mpdenton@chromium.org>
Date: Tue, 15 Dec 2020 01:09:52 +0000
Subject: Fix UAF in ~MultiThreadedCertVerifier
MultiThreadedCertVerifier keeps a list of
MultiThreadedCertVerifier::InternalRequests in order to eagerly reset
callbacks passed to Verify() if the MultiThreadedCertVerifier is
itself deleted (CertVerifier contract guarantees this eager reset
behavior).
In ~MultiThreadedCertVerifier we loop through this list and reset the
callbacks, but then delete the InternalRequest from the list. However,
the callbacks are allowed to own the InternalRequest, so this leads
to a UaF.
We don't need to remove the InternalRequest from the list in
~MultiThreadedCertVerifier, because we are not in charge of the
lifetime of the InternalRequest. InternalRequest can remove itself
from the list during ~InternalRequest, or MultiThreadedCertVerifier
can remove it from the list when a CertVerification job is complete.
The former is safe because ~InternalRequest won't remove itself from
the list if the MultiThreadedCertVerifier is already destructed.
The latter is obviously safe because if the request was cancelled,
then InternalRequest::OnJobCompleted will never run, so
|this| is always valid to remove from the list during
InternalRequest::OnJobCompleted.
The added test reproduces the UAF without the fix.
Bug: 1157562
Change-Id: I92d0dc6ca6df084f55ea511ea692853ee63f5033
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2587560
Reviewed-by: Ryan Sleevi <rsleevi@chromium.org>
Commit-Queue: Matthew Denton <mpdenton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836903}
diff --git a/net/cert/multi_threaded_cert_verifier.cc b/net/cert/multi_threaded_cert_verifier.cc
index f2546d9187dc6aedbf5eab055d2017939df6a705..b46dbf68d0f239c2d002f9dedeecd6f10709f9c4 100644
--- a/net/cert/multi_threaded_cert_verifier.cc
+++ b/net/cert/multi_threaded_cert_verifier.cc
@@ -202,10 +202,13 @@ MultiThreadedCertVerifier::~MultiThreadedCertVerifier() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Reset the callbacks for each InternalRequest to fulfill the respective
// net::CertVerifier contract.
- while (!request_list_.empty()) {
- base::LinkNode<InternalRequest>* curr = request_list_.head();
- curr->value()->ResetCallback();
- curr->RemoveFromList();
+ for (base::LinkNode<InternalRequest>* node = request_list_.head();
+ node != request_list_.end();) {
+ // Resetting the callback may delete the request, so save a pointer to the
+ // next node first.
+ base::LinkNode<InternalRequest>* next_node = node->next();
+ node->value()->ResetCallback();
+ node = next_node;
}
}
diff --git a/net/cert/multi_threaded_cert_verifier.h b/net/cert/multi_threaded_cert_verifier.h
index 82b750a42f8eb99675e35aa41ef167c1e7896a33..05c5463abffc61644e31293b6876801efc6138fb 100644
--- a/net/cert/multi_threaded_cert_verifier.h
+++ b/net/cert/multi_threaded_cert_verifier.h
@@ -50,6 +50,10 @@ class NET_EXPORT_PRIVATE MultiThreadedCertVerifier : public CertVerifier {
Config config_;
scoped_refptr<CertVerifyProc> verify_proc_;
+ // Holds a list of CertVerifier::Requests that have not yet completed or been
+ // deleted. It is used to ensure that when the MultiThreadedCertVerifier is
+ // deleted, we eagerly reset all of the callbacks provided to Verify(), and
+ // don't call them later, as required by the CertVerifier contract.
base::LinkedList<InternalRequest> request_list_;
#if defined(USE_NSS_CERTS)
diff --git a/net/cert/multi_threaded_cert_verifier_unittest.cc b/net/cert/multi_threaded_cert_verifier_unittest.cc
index 89c394541a94697036e34c7430e982c4eeb1a1f7..b5cf4bbaf3648f8b562fffd3804b65ab5b9379ab 100644
--- a/net/cert/multi_threaded_cert_verifier_unittest.cc
+++ b/net/cert/multi_threaded_cert_verifier_unittest.cc
@@ -152,6 +152,45 @@ TEST_F(MultiThreadedCertVerifierTest, DeleteVerifier) {
RunUntilIdle();
}
+namespace {
+
+struct CertVerifyResultHelper {
+ void FailTest(int /* result */) { FAIL(); }
+ std::unique_ptr<CertVerifier::Request> request;
+};
+
+} // namespace
+
+// The same as the above "DeleteVerifier" test, except the callback provided
+// will own the CertVerifier::Request as allowed by the CertVerifier contract.
+// This is a regression test for https://crbug.com/1157562.
+TEST_F(MultiThreadedCertVerifierTest, DeleteVerifierCallbackOwnsResult) {
+ base::FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<X509Certificate> test_cert(
+ ImportCertFromFile(certs_dir, "ok_cert.pem"));
+ ASSERT_NE(static_cast<X509Certificate*>(nullptr), test_cert.get());
+
+ int error;
+ CertVerifyResult verify_result;
+ std::unique_ptr<CertVerifyResultHelper> result_helper =
+ std::make_unique<CertVerifyResultHelper>();
+ CertVerifyResultHelper* result_helper_ptr = result_helper.get();
+ CompletionOnceCallback callback = base::BindOnce(
+ &CertVerifyResultHelper::FailTest, std::move(result_helper));
+
+ error = verifier_->Verify(
+ CertVerifier::RequestParams(test_cert, "www.example.com", 0,
+ /*ocsp_response=*/std::string(),
+ /*sct_list=*/std::string()),
+ &verify_result, std::move(callback), &result_helper_ptr->request,
+ NetLogWithSource());
+ ASSERT_THAT(error, IsError(ERR_IO_PENDING));
+ ASSERT_TRUE(result_helper_ptr->request);
+ verifier_.reset();
+
+ RunUntilIdle();
+}
+
// Tests that a canceled request is not leaked.
TEST_F(MultiThreadedCertVerifierTest, CancelRequestThenQuit) {
base::FilePath certs_dir = GetTestCertsDirectory();

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,148 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Antonio Sartori <antoniosartori@chromium.org>
Date: Mon, 8 Mar 2021 10:28:40 +0000
Subject: Strip url to origin in X-Frame-Options violation messages
X-Frame-Options violations are logged via a console message in the
parent frame. To avoid leaking sensitive data to the parent frame,
let's report as "blocked url" just the origin of the blocked frame's
url, as we are already doing for the frame-ancestors CSP directive.
[M86 Merge]: ancestor_throttle.cc was moved.
(cherry picked from commit 93ce5606cd9a9597993ba70670b4092ab6722281)
Bug: 1146651
Change-Id: If5e5ac62f7e44e714b109e6adc389f11999e0f8b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2534851
Commit-Queue: Antonio Sartori <antoniosartori@chromium.org>
Reviewed-by: Charlie Reis <creis@chromium.org>
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#828651}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2731577
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1563}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ConsoleMessagesForBlockedLoadsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/ConsoleMessagesForBlockedLoadsTest.java
index 7394abb2e639a8f3b25cca0a568135cd4e8bd0d8..c746763be2a77a87a52e9ef31bbbd25de7ba03ae 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/ConsoleMessagesForBlockedLoadsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/ConsoleMessagesForBlockedLoadsTest.java
@@ -94,7 +94,7 @@ public class ConsoleMessagesForBlockedLoadsTest {
mActivityTestRule.loadUrlSync(
mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl);
AwConsoleMessage errorMessage = getSingleErrorMessage();
- assertNotEquals(errorMessage.message().indexOf(iframeUrl), -1);
+ assertNotEquals(errorMessage.message().indexOf(mWebServer.getBaseUrl()), -1);
}
@Test
diff --git a/content/browser/frame_host/ancestor_throttle.cc b/content/browser/frame_host/ancestor_throttle.cc
index 8630ace7189d465cea8360a55acf899fa801f15e..75269311d73c1d9b881bc40f320265772b074d63 100644
--- a/content/browser/frame_host/ancestor_throttle.cc
+++ b/content/browser/frame_host/ancestor_throttle.cc
@@ -239,12 +239,20 @@ void AncestorThrottle::ParseXFrameOptionsError(const std::string& value,
"Refused to display '%s' in a frame because it set multiple "
"'X-Frame-Options' headers with conflicting values "
"('%s'). Falling back to 'deny'.",
- navigation_handle()->GetURL().spec().c_str(), value.c_str());
+ url::Origin::Create(navigation_handle()->GetURL())
+ .GetURL()
+ .spec()
+ .c_str(),
+ value.c_str());
} else {
message = base::StringPrintf(
"Invalid 'X-Frame-Options' header encountered when loading '%s': "
"'%s' is not a recognized directive. The header will be ignored.",
- navigation_handle()->GetURL().spec().c_str(), value.c_str());
+ url::Origin::Create(navigation_handle()->GetURL())
+ .GetURL()
+ .spec()
+ .c_str(),
+ value.c_str());
}
// Log a console error in the parent of the current RenderFrameHost (as
@@ -265,11 +273,19 @@ void AncestorThrottle::ConsoleErrorXFrameOptions(
std::string message = base::StringPrintf(
"Refused to display '%s' in a frame because it set 'X-Frame-Options' "
"to '%s'.",
- navigation_handle()->GetURL().spec().c_str(),
+ url::Origin::Create(navigation_handle()->GetURL())
+ .GetURL()
+ .spec()
+ .c_str(),
disposition == HeaderDisposition::DENY ? "deny" : "sameorigin");
// Log a console error in the parent of the current RenderFrameHost (as
// the current RenderFrameHost itself doesn't yet have a document).
+ //
+ // TODO(https://crbug.com/1146651): We should not leak any information at all
+ // to the parent frame. Send a message directly to Devtools instead (without
+ // passing through a renderer): that can also contain more information (like
+ // the full blocked url).
auto* frame = static_cast<RenderFrameHostImpl*>(
navigation_handle()->GetRenderFrameHost());
ParentForAncestorThrottle(frame)->AddMessageToConsole(
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index d81076da5ef7701475ef1158b528d02d3992ff0d..10d1a58f143906a77df33ae8da3cc1df7605c07b 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -7109,12 +7109,26 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
"document.querySelector('iframe').onload = "
" function() { document.title = 'loaded'; };"));
+ // The blocked url reported in the console message should only contain the
+ // origin, in order to avoid sensitive data being leaked to the parent frame.
+ //
+ // TODO(https://crbug.com/1146651): We should not leak any information at all
+ // to the parent frame. Instead, we should send a message directly to Devtools
+ // (without passing through a renderer): that can also contain more
+ // information (like the full blocked url).
+ GURL reported_blocked_url = embedded_test_server()->GetURL("b.com", "/");
const struct {
const char* url;
bool use_error_page;
+ std::string expected_console_message;
} kTestCases[] = {
- {"/frame-ancestors-none.html", false},
- {"/x-frame-options-deny.html", true},
+ {"/frame-ancestors-none.html", false,
+ "Refused to frame '" + reported_blocked_url.spec() +
+ "' because an ancestor violates the following Content Security "
+ "Policy directive: \"frame-ancestors 'none'\".\n"},
+ {"/x-frame-options-deny.html", true,
+ "Refused to display '" + reported_blocked_url.spec() +
+ "' in a frame because it set 'X-Frame-Options' to 'deny'."},
};
for (const auto& test : kTestCases) {
@@ -7123,6 +7137,9 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
base::string16 expected_title(base::UTF8ToUTF16("loaded"));
TitleWatcher title_watcher(shell()->web_contents(), expected_title);
+ WebContentsConsoleObserver console_observer(shell()->web_contents());
+ console_observer.SetPattern("Refused to*");
+
// Navigate the subframe to a blocked URL.
TestNavigationObserver load_observer(shell()->web_contents());
EXPECT_TRUE(ExecuteScript(
@@ -7150,6 +7167,8 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
// The blocked frame should still fire a load event in its parent's process.
EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
+ EXPECT_EQ(console_observer.GetMessageAt(0u), test.expected_console_message);
+
// Check that the current RenderFrameHost has stopped loading.
EXPECT_FALSE(root->child_at(0)->current_frame_host()->is_loading());
diff --git a/third_party/blink/web_tests/http/tests/security/XFrameOptions/x-frame-options-deny-delete-frame-in-load-event-expected.txt b/third_party/blink/web_tests/http/tests/security/XFrameOptions/x-frame-options-deny-delete-frame-in-load-event-expected.txt
index f2e5b68c997ca33da841aa7ba5795ef3b96fa02f..f7eea4a189ae8913921444428e26389dfd4de4da 100644
--- a/third_party/blink/web_tests/http/tests/security/XFrameOptions/x-frame-options-deny-delete-frame-in-load-event-expected.txt
+++ b/third_party/blink/web_tests/http/tests/security/XFrameOptions/x-frame-options-deny-delete-frame-in-load-event-expected.txt
@@ -1,2 +1,2 @@
-CONSOLE ERROR: Refused to display 'http://127.0.0.1:8000/security/XFrameOptions/resources/x-frame-options-deny.cgi' in a frame because it set 'X-Frame-Options' to 'deny'.
+CONSOLE ERROR: Refused to display 'http://127.0.0.1:8000/' in a frame because it set 'X-Frame-Options' to 'deny'.
Test that if an iframe is denied, we don't crash if the load event detaches the frame.

View File

@@ -0,0 +1,224 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Raymond Toy <rtoy@chromium.org>
Date: Tue, 2 Mar 2021 15:15:29 +0000
Subject: Convert AudioParam NaN values to the default value
If any output value of an AudioParam (including the intrinsic values
and any inputs to the AudioParam), should be NaN, replace the NaN
value with the associated defaultValue.
This causes some slowdowns so SIMD/NEON code was added to mitigate the
degradation. There is still some slowdown, but the worst case is now
about 7% slower on x86 and 10% on arm. Generally, the slowdown is less
than 2% and 5%, respectively. (Perversely, some results got faster,
and the differences are statistically significant.)
Full details can be found at
https://docs.google.com/spreadsheets/d/1EhbLHm-9cUoEO5aj1vYemVBLQ3Dh4dCJPPLTfZPrZt4/edit?usp=sharing
Manually tested the test case from the bug and the issue no longer
occurs.
(cherry picked from commit ab1862017b5717271a28376659944dddc602195c)
(cherry picked from commit eb0c0353bf245885797d8ce0d1b864d88a381fbb)
Bug: 1170531
Change-Id: I00d902b40a9ef9da990c6d68b664b1dcfc31b091
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2658724
Commit-Queue: Raymond Toy <rtoy@chromium.org>
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#851733}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2686369
Reviewed-by: Raymond Toy <rtoy@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4389@{#880}
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2727697
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1551}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/modules/webaudio/audio_param.cc b/third_party/blink/renderer/modules/webaudio/audio_param.cc
index c5d329479a412d52ee39167ff841b1cea417a217..135588f56ebceabd3e0a12f9f506955bb58b20ca 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_param.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_param.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/modules/webaudio/audio_param.h"
+#include "build/build_config.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node.h"
@@ -235,6 +236,49 @@ void AudioParamHandler::CalculateSampleAccurateValues(
CalculateFinalValues(values, number_of_values, IsAudioRate());
}
+// Replace NaN values in |values| with |default_value|.
+static void HandleNaNValues(float* values,
+ unsigned number_of_values,
+ float default_value) {
+ unsigned k = 0;
+#if defined(ARCH_CPU_X86_FAMILY)
+ if (number_of_values >= 4) {
+ __m128 defaults = _mm_set1_ps(default_value);
+ for (k = 0; k < number_of_values; k += 4) {
+ __m128 v = _mm_loadu_ps(values + k);
+ // cmpuord returns all 1's if v is NaN for each elmeent of v.
+ __m128 isnan = _mm_cmpunord_ps(v, v);
+ // Replace NaN parts with default.
+ __m128 result = _mm_and_ps(isnan, defaults);
+ // Merge in the parts that aren't NaN
+ result = _mm_or_ps(_mm_andnot_ps(isnan, v), result);
+ _mm_storeu_ps(values + k, result);
+ }
+ }
+#elif defined(CPU_ARM_NEON)
+ if (number_of_values >= 4) {
+ uint32x4_t defaults = static_cast<uint32x4_t>(vdupq_n_f32(default_value));
+ for (k = 0; k < number_of_values; k += 4) {
+ float32x4_t v = vld1q_f32(values + k);
+ // Returns true (all ones) if v is not NaN
+ uint32x4_t is_not_nan = vceqq_f32(v, v);
+ // Get the parts that are not NaN
+ uint32x4_t result = vandq_u32(is_not_nan, v);
+ // Replace the parts that are NaN with the default and merge with previous
+ // result. (Note: vbic_u32(x, y) = x and not y)
+ result = vorrq_u32(result, vbicq_u32(defaults, is_not_nan));
+ vst1q_f32(values + k, static_cast<float32x4_t>(result));
+ }
+ }
+#endif
+
+ for (; k < number_of_values; ++k) {
+ if (std::isnan(values[k])) {
+ values[k] = default_value;
+ }
+ }
+}
+
void AudioParamHandler::CalculateFinalValues(float* values,
unsigned number_of_values,
bool sample_accurate) {
@@ -297,10 +341,21 @@ void AudioParamHandler::CalculateFinalValues(float* values,
}
}
- // Clamp the values now to the nominal range
float min_value = MinValue();
float max_value = MaxValue();
+ if (NumberOfRenderingConnections() > 0) {
+ // AudioParams by themselves don't produce NaN because of the finite min
+ // and max values. But an input to an AudioParam could have NaNs.
+ //
+ // NaN values in AudioParams must be replaced by the AudioParam's
+ // defaultValue. Then these values must be clamped to lie in the nominal
+ // range between the AudioParam's minValue and maxValue.
+ //
+ // See https://webaudio.github.io/web-audio-api/#computation-of-value.
+ HandleNaNValues(values, number_of_values, DefaultValue());
+ }
+
vector_math::Vclip(values, 1, &min_value, &max_value, values, 1,
number_of_values);
}
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/nan-param.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/nan-param.html
new file mode 100644
index 0000000000000000000000000000000000000000..e9b8f0accbd1b0359275615f3ef12bd7e9317c4f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/nan-param.html
@@ -0,0 +1,92 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test Flushing of NaN to Zero in AudioParams</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/webaudio/resources/audit-util.js"></script>
+ <script src="/webaudio/resources/audit.js"></script>
+ </head>
+
+ <body>
+ <script>
+ let audit = Audit.createTaskRunner();
+
+ // See
+ // https://webaudio.github.io/web-audio-api/#computation-of-value.
+ //
+ // The computed value must replace NaN values in the output with
+ // the default value of the param.
+ audit.define('AudioParam NaN', async (task, should) => {
+ // For testing, we only need a small number of frames; and
+ // a low sample rate is perfectly fine. Use two channels.
+ // The first channel is for the AudioParam output. The
+ // second channel is for the AudioParam input.
+ let context = new OfflineAudioContext(
+ {numberOfChannels: 2, length: 256, sampleRate: 8192});
+ let merger = new ChannelMergerNode(
+ context, {numberOfInputs: context.destination.channelCount});
+ merger.connect(context.destination);
+
+ // A constant source with a huge value.
+ let mod = new ConstantSourceNode(context, {offset: 1e30});
+
+ // Gain nodes with a huge positive gain and huge negative
+ // gain. Combined with the huge offset in |mod|, the
+ // output of the gain nodes are +Infinity and -Infinity.
+ let gainPos = new GainNode(context, {gain: 1e30});
+ let gainNeg = new GainNode(context, {gain: -1e30});
+
+ mod.connect(gainPos);
+ mod.connect(gainNeg);
+
+ // Connect these to the second merger channel. This is a
+ // sanity check that the AudioParam input really is NaN.
+ gainPos.connect(merger, 0, 1);
+ gainNeg.connect(merger, 0, 1);
+
+ // Source whose AudioParam is connected to the graph
+ // that produces NaN values. Use a non-default value offset
+ // just in case something is wrong we get default for some
+ // other reason.
+ let src = new ConstantSourceNode(context, {offset: 100});
+
+ gainPos.connect(src.offset);
+ gainNeg.connect(src.offset);
+
+ // AudioParam output goes to channel 1 of the destination.
+ src.connect(merger, 0, 0);
+
+ // Let's go!
+ mod.start();
+ src.start();
+
+ let buffer = await context.startRendering();
+
+ let input = buffer.getChannelData(1);
+ let output = buffer.getChannelData(0);
+
+ // Have to test manually for NaN values in the input because
+ // NaN fails all comparisons.
+ let isNaN = true;
+ for (let k = 0; k < input.length; ++k) {
+ if (!Number.isNaN(input[k])) {
+ isNaN = false;
+ break;
+ }
+ }
+
+ should(isNaN, 'AudioParam input contains only NaN').beTrue();
+
+ // Output of the AudioParam should have all NaN values
+ // replaced by the default.
+ should(output, 'AudioParam output')
+ .beConstantValueOf(src.offset.defaultValue);
+
+ task.done();
+ });
+
+ audit.run();
+ </script>
+ </body>
+</html>

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,46 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jana Grill <janagrill@google.com>
Date: Wed, 14 Apr 2021 08:40:10 +0000
Subject: Forbid script execution while updating the paint lifecycle.
(cherry picked from commit 5425d3b100fab533ea9ddc2ed8fbfc4870db0587)
Bug: 1196781
Change-Id: Idc8d24792d5c413691977b09ca821de4e13887ad
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2812000
Commit-Queue: Adrian Taylor <adetaylor@chromium.org>
Commit-Queue: Robert Flack <flackr@chromium.org>
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#870275}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2821879
Reviewed-by: Robert Flack <flackr@chromium.org>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Jana Grill <janagrill@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1601}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 9a4c7a5249424b021759bf7895dd3f343b9641e6..37054d34157e7f4b4d65b022cdb83c832deb26a8 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2648,11 +2648,14 @@ void LocalFrameView::RunPaintLifecyclePhase() {
for (PaintLayerScrollableArea* area : *animating_scrollable_areas)
area->UpdateCompositorScrollAnimations();
}
- frame_view.GetLayoutView()
- ->GetDocument()
- .GetDocumentAnimations()
- .UpdateAnimations(DocumentLifecycle::kPaintClean,
- paint_artifact_compositor_.get());
+ {
+ ScriptForbiddenScope forbid_script;
+ frame_view.GetLayoutView()
+ ->GetDocument()
+ .GetDocumentAnimations()
+ .UpdateAnimations(DocumentLifecycle::kPaintClean,
+ paint_artifact_compositor_.get());
+ }
});
// Initialize animation properties in the newly created paint property

View File

@@ -0,0 +1,56 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yuri Wiitala <miu@chromium.org>
Date: Thu, 10 Dec 2020 18:07:39 +0000
Subject: Minor UI logic changes to prevent a UAF bug when starting tab
capture.
See discussion in crbug 1155426 for details. Changes:
MediaStreamCaptureIndicator::UIDelegate: Ignore multiple calls to
OnStarted().
TabSharingUIViews: Unconditionally execute clean-up tasks in destructor.
Bug: 1155426
Change-Id: I392fba38118ce51744ba36b4dec19ebfe39f1fbe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2581028
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
Reviewed-by: Marina Ciocea <marinaciocea@chromium.org>
Commit-Queue: Yuri Wiitala <miu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#835736}
diff --git a/chrome/browser/media/webrtc/media_stream_capture_indicator.cc b/chrome/browser/media/webrtc/media_stream_capture_indicator.cc
index ce93d308a3d1099d9edbeea88ce8d05e60158117..99203ebb36edc21697518d172d67831deed8ba04 100644
--- a/chrome/browser/media/webrtc/media_stream_capture_indicator.cc
+++ b/chrome/browser/media/webrtc/media_stream_capture_indicator.cc
@@ -186,7 +186,12 @@ class MediaStreamCaptureIndicator::UIDelegate : public content::MediaStreamUI {
gfx::NativeViewId OnStarted(
base::OnceClosure stop_callback,
content::MediaStreamUI::SourceCallback source_callback) override {
- DCHECK(!started_);
+ if (started_) {
+ // Ignore possibly-compromised renderers that might call
+ // MediaStreamDispatcherHost::OnStreamStarted() more than once.
+ // See: https://crbug.com/1155426
+ return 0;
+ }
started_ = true;
if (device_usage_) {
diff --git a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc
index 1582ccedd3fac5368e7adf94ec222e5d85b18aab..35e4f3e93c41f52fb50599da4050c0f3c25dd0d4 100644
--- a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc
+++ b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc
@@ -134,8 +134,10 @@ TabSharingUIViews::TabSharingUIViews(const content::DesktopMediaID& media_id,
}
TabSharingUIViews::~TabSharingUIViews() {
- if (!infobars_.empty())
- StopSharing();
+ // Unconditionally call StopSharing(), to ensure all clean-up has been
+ // performed if tasks race (e.g., OnStarted() is called after
+ // OnInfoBarRemoved()). See: https://crbug.com/1155426
+ StopSharing();
}
gfx::NativeViewId TabSharingUIViews::OnStarted(

View File

@@ -0,0 +1,100 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Tue, 20 Apr 2021 15:46:33 +0000
Subject: M86-LTS: Mojo: Properly validate broadcast events
This corrects broadcast event deserialization by adding a missing
validation step when decoding the outer message header.
(cherry picked from commit 6740adb28374ddeee13febfd5e5d20cb8a365979)
Fixed: 1195308
Change-Id: Ia67a20e48614e7ef00b1b32f7f4e5f20235be310
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2808678
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Original-Commit-Position: refs/heads/master@{#870238}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2837712
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Auto-Submit: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1614}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/mojo/core/node_channel.cc b/mojo/core/node_channel.cc
index 061ea1026e95d1b1f80a762ce377aebdd97e1b42..07e3b8b21f7ef70b64d214ec03e0dd1eb807fad6 100644
--- a/mojo/core/node_channel.cc
+++ b/mojo/core/node_channel.cc
@@ -191,13 +191,16 @@ Channel::MessagePtr NodeChannel::CreateEventMessage(size_t capacity,
}
// static
-void NodeChannel::GetEventMessageData(Channel::Message* message,
+bool NodeChannel::GetEventMessageData(Channel::Message& message,
void** data,
size_t* num_data_bytes) {
- // NOTE: OnChannelMessage guarantees that we never accept a Channel::Message
- // with a payload of fewer than |sizeof(Header)| bytes.
- *data = reinterpret_cast<Header*>(message->mutable_payload()) + 1;
- *num_data_bytes = message->payload_size() - sizeof(Header);
+ // NOTE: Callers must guarantee that the payload in `message` must be at least
+ // large enough to hold a Header.
+ if (message.payload_size() < sizeof(Header))
+ return false;
+ *data = reinterpret_cast<Header*>(message.mutable_payload()) + 1;
+ *num_data_bytes = message.payload_size() - sizeof(Header);
+ return true;
}
void NodeChannel::Start() {
diff --git a/mojo/core/node_channel.h b/mojo/core/node_channel.h
index 58ab42bd01fc856856d171985dac50934d4e00b2..7ae08e3e73110667f0eafe0fe4f70242bfeece39 100644
--- a/mojo/core/node_channel.h
+++ b/mojo/core/node_channel.h
@@ -90,7 +90,9 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeChannel
void** payload,
size_t num_handles);
- static void GetEventMessageData(Channel::Message* message,
+ // Retrieves address and size of an Event message's underlying message data.
+ // Returns `false` if the message is not a valid Event message.
+ static bool GetEventMessageData(Channel::Message& message,
void** data,
size_t* num_data_bytes);
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc
index c333ed64f71f0dfe5d0012b07bcedccfd94cd5e9..a8b8520729510408dc822532271d0ff4a36a7151 100644
--- a/mojo/core/node_controller.cc
+++ b/mojo/core/node_controller.cc
@@ -76,7 +76,9 @@ ports::ScopedEvent DeserializeEventMessage(
Channel::MessagePtr channel_message) {
void* data;
size_t size;
- NodeChannel::GetEventMessageData(channel_message.get(), &data, &size);
+ bool valid = NodeChannel::GetEventMessageData(*channel_message, &data, &size);
+ if (!valid)
+ return nullptr;
auto event = ports::Event::Deserialize(data, size);
if (!event)
return nullptr;
diff --git a/mojo/core/user_message_impl.cc b/mojo/core/user_message_impl.cc
index 2f1665e55cf0af69c58c21f2e0d602a93e79052e..a6b35b2cd812bb0da7026b088aa0d96acbbc6a2f 100644
--- a/mojo/core/user_message_impl.cc
+++ b/mojo/core/user_message_impl.cc
@@ -415,7 +415,14 @@ Channel::MessagePtr UserMessageImpl::FinalizeEventMessage(
if (channel_message) {
void* data;
size_t size;
- NodeChannel::GetEventMessageData(channel_message.get(), &data, &size);
+ // The `channel_message` must either be produced locally or must have
+ // already been validated by the caller, as is done for example by
+ // NodeController::DeserializeEventMessage before
+ // NodeController::OnBroadcast re-serializes each copy of the message it
+ // received.
+ bool result =
+ NodeChannel::GetEventMessageData(*channel_message, &data, &size);
+ DCHECK(result);
message_event->Serialize(data);
}

View File

@@ -0,0 +1,326 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Adam Rice <ricea@chromium.org>
Date: Fri, 4 Dec 2020 10:19:12 +0000
Subject: Correctly handle detach during (de)compression
Sometimes CompressionStream and DecompressionStream enqueue multiple
output chunks for a single input chunk. When this happens, JavaScript
code can detach the input ArrayBuffer while the stream is processing it.
This will cause an error when zlib tries to read the buffer again
afterwards.
To prevent this, buffer output chunks until the entire input chunk has
been processed, and then enqueue them all at once.
Bug: 1151298
Change-Id: I03fca26fc641d54b09067e3994b76ee8efca6839
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2567539
Commit-Queue: Adam Rice <ricea@chromium.org>
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
Cr-Commit-Position: refs/heads/master@{#833659}
diff --git a/third_party/blink/renderer/modules/compression/deflate_transformer.cc b/third_party/blink/renderer/modules/compression/deflate_transformer.cc
index e663e563d58e90cdce5185636d1b1aa75491195c..e806b84afbb6cd82c53832e0c0b455ae0767a34a 100644
--- a/third_party/blink/renderer/modules/compression/deflate_transformer.cc
+++ b/third_party/blink/renderer/modules/compression/deflate_transformer.cc
@@ -111,6 +111,10 @@ void DeflateTransformer::Deflate(const uint8_t* start,
// Zlib treats this pointer as const, so this cast is safe.
stream_.next_in = const_cast<uint8_t*>(start);
+ // enqueue() may execute JavaScript which may invalidate the input buffer. So
+ // accumulate all the output before calling enqueue().
+ HeapVector<Member<DOMUint8Array>, 1u> buffers;
+
do {
stream_.avail_out = out_buffer_.size();
stream_.next_out = out_buffer_.data();
@@ -120,16 +124,21 @@ void DeflateTransformer::Deflate(const uint8_t* start,
wtf_size_t bytes = out_buffer_.size() - stream_.avail_out;
if (bytes) {
- controller->enqueue(
- script_state_,
- ScriptValue::From(script_state_,
- DOMUint8Array::Create(out_buffer_.data(), bytes)),
- exception_state);
- if (exception_state.HadException()) {
- return;
- }
+ buffers.push_back(DOMUint8Array::Create(out_buffer_.data(), bytes));
}
} while (stream_.avail_out == 0);
+
+ DCHECK_EQ(stream_.avail_in, 0u);
+
+ // JavaScript may be executed inside this loop, however it is safe because
+ // |buffers| is a local variable that JavaScript cannot modify.
+ for (DOMUint8Array* buffer : buffers) {
+ controller->enqueue(script_state_, ScriptValue::From(script_state_, buffer),
+ exception_state);
+ if (exception_state.HadException()) {
+ return;
+ }
+ }
}
void DeflateTransformer::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/compression/inflate_transformer.cc b/third_party/blink/renderer/modules/compression/inflate_transformer.cc
index f348a5086e4254bc972dd321109d9fbf676f1d5e..29667b5752250466cd71542ab8868d6e14961e81 100644
--- a/third_party/blink/renderer/modules/compression/inflate_transformer.cc
+++ b/third_party/blink/renderer/modules/compression/inflate_transformer.cc
@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/to_v8.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "v8/include/v8.h"
namespace blink {
@@ -93,11 +94,15 @@ ScriptPromise InflateTransformer::Flush(
TransformStreamDefaultController* controller,
ExceptionState& exception_state) {
DCHECK(!was_flush_called_);
+ was_flush_called_ = true;
Inflate(nullptr, 0u, IsFinished(true), controller, exception_state);
inflateEnd(&stream_);
- was_flush_called_ = true;
out_buffer_.clear();
+ if (exception_state.HadException()) {
+ return ScriptPromise();
+ }
+
if (!reached_end_) {
exception_state.ThrowTypeError("Compressed input was truncated.");
}
@@ -121,12 +126,22 @@ void InflateTransformer::Inflate(const uint8_t* start,
// Zlib treats this pointer as const, so this cast is safe.
stream_.next_in = const_cast<uint8_t*>(start);
+ // enqueue() may execute JavaScript which may invalidate the input buffer. So
+ // accumulate all the output before calling enqueue().
+ HeapVector<Member<DOMUint8Array>, 1u> buffers;
+
do {
stream_.avail_out = out_buffer_.size();
stream_.next_out = out_buffer_.data();
const int err = inflate(&stream_, finished ? Z_FINISH : Z_NO_FLUSH);
if (err != Z_OK && err != Z_STREAM_END && err != Z_BUF_ERROR) {
DCHECK_NE(err, Z_STREAM_ERROR);
+
+ EnqueueBuffers(controller, std::move(buffers), exception_state);
+ if (exception_state.HadException()) {
+ return;
+ }
+
if (err == Z_DATA_ERROR) {
exception_state.ThrowTypeError(
String("The compressed data was not valid: ") + stream_.msg + ".");
@@ -138,25 +153,44 @@ void InflateTransformer::Inflate(const uint8_t* start,
wtf_size_t bytes = out_buffer_.size() - stream_.avail_out;
if (bytes) {
- controller->enqueue(
- script_state_,
- ScriptValue::From(script_state_,
- DOMUint8Array::Create(out_buffer_.data(), bytes)),
- exception_state);
- if (exception_state.HadException()) {
- return;
- }
+ buffers.push_back(DOMUint8Array::Create(out_buffer_.data(), bytes));
}
if (err == Z_STREAM_END) {
reached_end_ = true;
- if (stream_.next_in < start + length) {
+ const bool junk_found = stream_.avail_in > 0;
+
+ EnqueueBuffers(controller, std::move(buffers), exception_state);
+ if (exception_state.HadException()) {
+ return;
+ }
+
+ if (junk_found) {
exception_state.ThrowTypeError(
"Junk found after end of compressed data.");
}
return;
}
} while (stream_.avail_out == 0);
+
+ DCHECK_EQ(stream_.avail_in, 0u);
+
+ EnqueueBuffers(controller, std::move(buffers), exception_state);
+}
+
+void InflateTransformer::EnqueueBuffers(
+ TransformStreamDefaultController* controller,
+ HeapVector<Member<DOMUint8Array>, 1u> buffers,
+ ExceptionState& exception_state) {
+ // JavaScript may be executed inside this loop, however it is safe because
+ // |buffers| is a local variable that JavaScript cannot modify.
+ for (DOMUint8Array* buffer : buffers) {
+ controller->enqueue(script_state_, ScriptValue::From(script_state_, buffer),
+ exception_state);
+ if (exception_state.HadException()) {
+ return;
+ }
+ }
}
void InflateTransformer::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/compression/inflate_transformer.h b/third_party/blink/renderer/modules/compression/inflate_transformer.h
index 290e91808dfcc16ed7ff6ec9e6e42eb412dfc969..c5df437f1684e6ca1201d9b3d32dff19903a0b5e 100644
--- a/third_party/blink/renderer/modules/compression/inflate_transformer.h
+++ b/third_party/blink/renderer/modules/compression/inflate_transformer.h
@@ -41,6 +41,10 @@ class InflateTransformer final : public TransformStreamTransformer {
TransformStreamDefaultController*,
ExceptionState&);
+ void EnqueueBuffers(TransformStreamDefaultController*,
+ HeapVector<Member<DOMUint8Array>, 1u> buffers,
+ ExceptionState&);
+
Member<ScriptState> script_state_;
z_stream stream_;
diff --git a/third_party/blink/web_tests/external/wpt/compression/compression-with-detach.tentative.any.js b/third_party/blink/web_tests/external/wpt/compression/compression-with-detach.tentative.any.js
new file mode 100644
index 0000000000000000000000000000000000000000..786bba21c800ca9f067a6d033f0345a52bfbb218
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/compression/compression-with-detach.tentative.any.js
@@ -0,0 +1,55 @@
+// META: global=window,worker
+// META: script=resources/concatenate-stream.js
+
+'use strict';
+
+const kInputLength = 500000;
+
+function createLargeRandomInput() {
+ const buffer = new ArrayBuffer(kInputLength);
+ // The getRandomValues API will only let us get 65536 bytes at a time, so call
+ // it multiple times.
+ const kChunkSize = 65536;
+ for (let offset = 0; offset < kInputLength; offset += kChunkSize) {
+ const length =
+ offset + kChunkSize > kInputLength ? kInputLength - offset : kChunkSize;
+ const view = new Uint8Array(buffer, offset, length);
+ crypto.getRandomValues(view);
+ }
+ return new Uint8Array(buffer);
+}
+
+function decompress(view) {
+ const ds = new DecompressionStream('deflate');
+ const writer = ds.writable.getWriter();
+ writer.write(view);
+ writer.close();
+ return concatenateStream(ds.readable);
+}
+
+promise_test(async () => {
+ const input = createLargeRandomInput();
+ const inputCopy = input.slice(0, input.byteLength);
+ const cs = new CompressionStream('deflate');
+ const writer = cs.writable.getWriter();
+ writer.write(input);
+ writer.close();
+ // Object.prototype.then will be looked up synchronously when the promise
+ // returned by read() is resolved.
+ Object.defineProperty(Object.prototype, 'then', {
+ get() {
+ // Cause input to become detached and unreferenced.
+ try {
+ postMessage(undefined, 'nowhere', [input.buffer]);
+ } catch (e) {
+ // It's already detached.
+ }
+ }
+ });
+ const output = await concatenateStream(cs.readable);
+ // Perform the comparison as strings since this is reasonably fast even when
+ // JITted JavaScript is running under an emulator.
+ assert_equals(
+ inputCopy.toString(), (await decompress(output)).toString(),
+ 'decompressing the output should return the input');
+}, 'data should be correctly compressed even if input is detached partway');
diff --git a/third_party/blink/web_tests/external/wpt/compression/decompression-with-detach.tentative.any.js b/third_party/blink/web_tests/external/wpt/compression/decompression-with-detach.tentative.any.js
new file mode 100644
index 0000000000000000000000000000000000000000..a2f8bda09148f0d323022b1f93be78d83c4aa654
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/compression/decompression-with-detach.tentative.any.js
@@ -0,0 +1,41 @@
+// META: global=window,worker
+// META: script=resources/concatenate-stream.js
+
+'use strict';
+
+const kInputLength = 1000000;
+
+async function createLargeCompressedInput() {
+ const cs = new CompressionStream('deflate');
+ // The input has to be large enough that it won't fit in a single chunk when
+ // decompressed.
+ const writer = cs.writable.getWriter();
+ writer.write(new Uint8Array(kInputLength));
+ writer.close();
+ return concatenateStream(cs.readable);
+}
+
+promise_test(async () => {
+ const input = await createLargeCompressedInput();
+ const ds = new DecompressionStream('deflate');
+ const writer = ds.writable.getWriter();
+ writer.write(input);
+ writer.close();
+ // Object.prototype.then will be looked up synchronously when the promise
+ // returned by read() is resolved.
+ Object.defineProperty(Object.prototype, 'then', {
+ get() {
+ // Cause input to become detached and unreferenced.
+ try {
+ postMessage(undefined, 'nowhere', [input.buffer]);
+ } catch (e) {
+ // It's already detached.
+ }
+ }
+ });
+ const output = await concatenateStream(ds.readable);
+ // If output successfully decompressed and gave the right length, we can be
+ // reasonably confident that no data corruption happened.
+ assert_equals(
+ output.byteLength, kInputLength, 'output should be the right length');
+}, 'data should be correctly decompressed even if input is detached partway');
diff --git a/third_party/blink/web_tests/external/wpt/compression/resources/concatenate-stream.js b/third_party/blink/web_tests/external/wpt/compression/resources/concatenate-stream.js
new file mode 100644
index 0000000000000000000000000000000000000000..a35bb1416e754893e331c0089d97720ae3b5af8e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/compression/resources/concatenate-stream.js
@@ -0,0 +1,25 @@
+'use strict';
+
+// Read all the chunks from a stream that returns BufferSource objects and
+// concatenate them into a single Uint8Array.
+async function concatenateStream(readableStream) {
+ const reader = readableStream.getReader();
+ let totalSize = 0;
+ const buffers = [];
+ while (true) {
+ const { value, done } = await reader.read();
+ if (done) {
+ break;
+ }
+ buffers.push(value);
+ totalSize += value.byteLength;
+ }
+ reader.releaseLock();
+ const concatenated = new Uint8Array(totalSize);
+ let offset = 0;
+ for (const buffer of buffers) {
+ concatenated.set(buffer, offset);
+ offset += buffer.byteLength;
+ }
+ return concatenated;
+}

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Harald Alvestrand <hta@chromium.org>
Date: Thu, 11 Mar 2021 18:54:23 +0000
Subject: Iterate more carefully over DTLS transports at close
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ensure that even if the set of DTLS transports is modified during
callbacks called from close, the process will be well-defined.
(cherry picked from commit 4f62c7bb28b0ce77b773a611c6ba02b361db1c85)
Bug: chromium:1167357
Change-Id: I712280e7382a647027912178156127831b437f75
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2639893
Reviewed-by: Henrik Boström <hbos@chromium.org>
Commit-Queue: Harald Alvestrand <hta@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#845122}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2752880
Reviewed-by: Adrian Taylor <adetaylor@chromium.org>
Cr-Commit-Position: refs/branch-heads/4389@{#1521}
Cr-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index 1503444ac2931a4205afe990f2e2dac11206de48..5d0b7e9cbe1f3459057b50879ab88d5a2ae12c20 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -3438,8 +3438,14 @@ void RTCPeerConnection::CloseInternal() {
if (sctp_transport_) {
sctp_transport_->Close();
}
- for (auto& dtls_transport_iter : dtls_transports_by_native_transport_) {
- dtls_transport_iter.value->Close();
+ // Since Close() can trigger JS-level callbacks, iterate over a copy
+ // of the transports list.
+ auto dtls_transports_copy = dtls_transports_by_native_transport_;
+ for (auto& dtls_transport_iter : dtls_transports_copy) {
+ // Since "value" is a WeakPtr, check if it's still valid.
+ if (dtls_transport_iter.value) {
+ dtls_transport_iter.value->Close();
+ }
}
feature_handle_for_scheduler_.reset();

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,48 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Palak Agarwal <agpalak@chromium.org>
Date: Wed, 31 Mar 2021 16:10:26 +0000
Subject: WebContents bug fix: Device capture only if web contents is valid
(cherry picked from commit a462be0883486431086c5f07cdafbd3607005a59)
(cherry picked from commit e6f11cafde08981e47ba77e71abf99a271f7a042)
Bug: 1181228
Change-Id: I0a4c9718a3c0ccb52cefa4565b9787e6912554c9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2752235
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
Commit-Queue: Palak Agarwal <agpalak@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#863828}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2782122
Auto-Submit: Guido Urdaneta <guidou@chromium.org>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Original-Commit-Position: refs/branch-heads/4389@{#1586}
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2795101
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
Auto-Submit: Artem Sumaneev <asumaneev@google.com>
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1585}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
index e3f7e784f0339581a1c8a50301f8dbfd465abbfd..1f0811610e155715cc5cd72bbaa7e703728a1fe5 100644
--- a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
+++ b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
@@ -248,6 +248,14 @@ void DesktopCaptureAccessHandler::ProcessScreenCaptureAccessRequest(
const bool display_notification =
display_notification_ && ShouldDisplayNotification(extension);
+ if (!content::WebContents::FromRenderFrameHost(
+ content::RenderFrameHost::FromID(request.render_process_id,
+ request.render_frame_id))) {
+ std::move(callback).Run(
+ devices, blink::mojom::MediaStreamRequestResult::INVALID_STATE,
+ std::move(ui));
+ return;
+ }
ui = GetDevicesForDesktopCapture(
web_contents, &devices, screen_id,
blink::mojom::MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE,

View File

@@ -0,0 +1,82 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brendon Tiszka <btiszka@gmail.com>
Date: Tue, 20 Apr 2021 15:45:03 +0000
Subject: M86-LTS: Ensure that BrowserContext is not used after it has been
freed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Previously, it was possible for the BrowserContext to be destroyed
before ReportAnchorElementMetricsOnClick attempted to access it.
The fix uses the fact that NavigationPredictor extends
WebContentsObserver and checks that web_contents is still alive
before dereferencing BrowserContext. WebContents will always
outlive BrowserContext.
R=lukasza@chromium.org, ryansturm@chromium.org
(cherry picked from commit 7313a810ae0b1361cbe8453bc5496654dee24c76)
Bug: 1197904
Change-Id: Iee4f126e92670a84d57c7a4ec7d6f702fb975c7e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2821639
Reviewed-by: Ryan Sturm <ryansturm@chromium.org>
Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org>
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#872021}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2838328
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Auto-Submit: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1613}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/AUTHORS b/AUTHORS
index 3aa101a8d38a899fefcca149e4ac8e658188e590..cccc1f6d1407183806e78cb99e56abe7bd93de82 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -145,6 +145,7 @@ Bobby Powers <bobbypowers@gmail.com>
Branden Archer <bma4@zips.uakron.edu>
Brendan Kirby <brendan.kirby@imgtec.com>
Brendan Long <self@brendanlong.com>
+Brendon Tiszka <btiszka@gmail.com>
Brian Clifton <clifton@brave.com>
Brian G. Merrell <bgmerrell@gmail.com>
Brian Konzman, SJ <b.g.konzman@gmail.com>
diff --git a/chrome/browser/navigation_predictor/navigation_predictor.cc b/chrome/browser/navigation_predictor/navigation_predictor.cc
index 495bb165a30f2b1bf690e6d0724ad8f347a76d44..b62a97501565555493f4db82ce4a1ababff19eb6 100644
--- a/chrome/browser/navigation_predictor/navigation_predictor.cc
+++ b/chrome/browser/navigation_predictor/navigation_predictor.cc
@@ -506,6 +506,9 @@ void NavigationPredictor::ReportAnchorElementMetricsOnClick(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(base::FeatureList::IsEnabled(blink::features::kNavigationPredictor));
+ if (!web_contents())
+ return;
+
if (browser_context_->IsOffTheRecord())
return;
@@ -652,6 +655,9 @@ void NavigationPredictor::ReportAnchorElementMetricsOnLoad(
// Each document should only report metrics once when page is loaded.
DCHECK(navigation_scores_map_.empty());
+ if (!web_contents())
+ return;
+
if (browser_context_->IsOffTheRecord())
return;
@@ -897,6 +903,9 @@ void NavigationPredictor::MaybeTakeActionOnLoad(
}
void NavigationPredictor::MaybePrefetch() {
+ if (!web_contents())
+ return;
+
// If prefetches aren't allowed here, this URL has already
// been prefetched, or the current tab is hidden,
// we shouldn't prefetch again.

View File

@@ -0,0 +1,71 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Koji Ishii <kojii@chromium.org>
Date: Thu, 11 Mar 2021 17:45:46 +0000
Subject: Mark additional RootInlineBox dirty when culled inline box is removed
When a |LayoutInline| is removed, |LineBoxList::
DirtyLinesFromChangedChild| tries to mark affected
|RootInlineBox| dirty.
When the |LayoutInline| to be removed is culled, it tries to
find the |RootInlineBox| from its previous siblings, then look
for its previous and next |RootInlineBox|es.
Occasionally, the next next line of the previous sibling is
wrapped at the |LayoutInline|, and that its |LineBreakObj()|
holds the reference to the |LayoutInline|. This patch marks
such |RootInlineBox| dirty.
(cherry picked from commit 2dbdabb28d647c8ee20cbe36e3c957e74aff663b)
Bug: 1186287
Change-Id: I8ca73ebb4f5e4f13e997662fffd803d6a74ef49a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2748756
Auto-Submit: Koji Ishii <kojii@chromium.org>
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#861724}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2749769
Commit-Queue: Krishna Govind <govind@chromium.org>
Cr-Commit-Position: refs/branch-heads/4389@{#1518}
Cr-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
diff --git a/third_party/blink/renderer/core/layout/line/line_box_list.cc b/third_party/blink/renderer/core/layout/line/line_box_list.cc
index 9d9d861f00cb9784041796acb91604d64dab1cb7..ed929849f721fbae25fd8c1106c95e563aca289b 100644
--- a/third_party/blink/renderer/core/layout/line/line_box_list.cc
+++ b/third_party/blink/renderer/core/layout/line/line_box_list.cc
@@ -359,14 +359,32 @@ void LineBoxList::DirtyLinesFromChangedChild(LineLayoutItem container,
// findNextLineBreak. findNextLineBreak, despite the name, actually returns
// the first LayoutObject after the BR. <rdar://problem/3849947> "Typing
// after pasting line does not appear until after window resize."
- if (RootInlineBox* prev_root_box = box->PrevRootBox())
+ if (RootInlineBox* prev_root_box = box->PrevRootBox()) {
prev_root_box->MarkDirty();
+#if DCHECK_IS_ON()
+ for (; prev_root_box; prev_root_box = prev_root_box->PrevRootBox()) {
+ DCHECK(prev_root_box->IsDirty() ||
+ prev_root_box->LineBreakObj() != child);
+ }
+#endif
+ }
// If |child| or any of its immediately previous siblings with culled
// lineboxes is the object after a line-break in |box| or the linebox after
// it then that means |child| actually sits on the linebox after |box| (or
// is its line-break object) and so we need to dirty it as well.
- if (RootInlineBox* next_root_box = box->NextRootBox())
+ if (RootInlineBox* next_root_box = box->NextRootBox()) {
next_root_box->MarkDirty();
+
+ next_root_box = next_root_box->NextRootBox();
+ if (next_root_box && next_root_box->LineBreakObj() == child)
+ next_root_box->MarkDirty();
+#if DCHECK_IS_ON()
+ for (; next_root_box; next_root_box = next_root_box->NextRootBox()) {
+ DCHECK(next_root_box->IsDirty() ||
+ next_root_box->LineBreakObj() != child);
+ }
+#endif
+ }
}
}

View File

@@ -0,0 +1,67 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sergei Glazunov <glazunov@google.com>
Date: Fri, 12 Feb 2021 16:37:12 +0000
Subject: Use a copy for transferring non detachable buffers
Currently, |DOMArrayBuffer::Transfer()| makes a copy, but still uses
the original buffer for transferring, thus making it possible to share a
regular ArrayBuffer (not SAB) with multiple threads.
(cherry picked from commit 0d289da12075592372940a366ad565b9a13d57ce)
Bug: 1177341
Change-Id: Idb48deb1698fe555f32531bc04b55dd3e1fb0a06
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2690630
Reviewed-by: Bill Budge <bbudge@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Sergei Glazunov <glazunov@google.com>
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#853272}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2691251
Reviewed-by: Krishna Govind <govind@chromium.org>
Commit-Queue: Krishna Govind <govind@chromium.org>
Cr-Commit-Position: refs/branch-heads/4389@{#980}
Cr-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
index 17fcf0f9034d09a53376ebb380c98589d52de8f4..c456d15f2f5084d7592326e151c1a478bc2ac1fc 100644
--- a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
+++ b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
@@ -47,6 +47,13 @@ bool DOMArrayBuffer::Transfer(v8::Isolate* isolate,
DOMArrayBuffer::Create(Content()->Data(), ByteLengthAsSizeT());
}
+ return to_transfer->TransferDetachable(isolate, result);
+}
+
+bool DOMArrayBuffer::TransferDetachable(v8::Isolate* isolate,
+ ArrayBufferContents& result) {
+ DCHECK(IsDetachable(isolate));
+
if (IsDetached()) {
result.Detach();
return false;
@@ -62,7 +69,7 @@ bool DOMArrayBuffer::Transfer(v8::Isolate* isolate,
Vector<v8::Local<v8::ArrayBuffer>, 4> buffer_handles;
v8::HandleScope handle_scope(isolate);
- AccumulateArrayBuffersForAllWorlds(isolate, to_transfer, buffer_handles);
+ AccumulateArrayBuffersForAllWorlds(isolate, this, buffer_handles);
for (const auto& buffer_handle : buffer_handles)
buffer_handle->Detach();
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h
index 00ba385dafcfd476805e39e4c138cdac8f071ef6..e9a85d38d4d46d26a41cf4d394a92d1a7b511c02 100644
--- a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h
+++ b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h
@@ -78,6 +78,9 @@ class CORE_EXPORT DOMArrayBuffer final : public DOMArrayBufferBase {
v8::Local<v8::Value> Wrap(v8::Isolate*,
v8::Local<v8::Object> creation_context) override;
+
+ private:
+ bool TransferDetachable(v8::Isolate*, ArrayBufferContents& result);
};
} // namespace blink

View File

@@ -0,0 +1,197 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hongchan Choi <hongchan@chromium.org>
Date: Tue, 8 Dec 2020 01:42:34 +0000
Subject: Fail gracefully if |parameter| object has an invalid array topology
AudioWorkletProcessor::CopyParamValueMapToObject() assumed the array
topology is always valid (DCHECK), but if the user code actively mangles
the parameter descriptor getter the array to return invalid content
this assumption becomes invalid.
The fix is to fail gracefully when the object type or the array content
is not correct.
Bug: 1151069
Test: The repro case does not reproduce any more after 1 hour run.
Change-Id: I3f8decd3721e9b00ba201e2f76751e4bc941e05d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2569788
Reviewed-by: Raymond Toy <rtoy@chromium.org>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#834503}
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
index 9ac9bcc91967e2228516e6cdc7065b83316c25e7..3518f24ea248862ea9d96ab8e6bbfecfe001fb33 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
@@ -107,8 +107,13 @@ bool AudioWorkletProcessor::Process(
DCHECK(!params_.IsEmpty());
DCHECK(params_.NewLocal(isolate)->IsObject());
- // Copies |param_value_map| to the internal |params_| object;
- CopyParamValueMapToObject(isolate, context, *param_value_map, params_);
+ // Copies |param_value_map| to the internal |params_| object. This operation
+ // could fail if the getter of parameterDescriptors is overridden by user code
+ // and returns incompatible data. (crbug.com/1151069)
+ if (!CopyParamValueMapToObject(isolate, context, *param_value_map, params_)) {
+ SetErrorState(AudioWorkletProcessorErrorState::kProcessError);
+ return false;
+ }
// Performs the user-defined AudioWorkletProcessor.process() function.
v8::TryCatch try_catch(isolate);
@@ -444,6 +449,7 @@ bool AudioWorkletProcessor::CloneParamValueMapToObject(
break;
}
}
+ DCHECK(array_size == 1 || array_size == param_float_array->size());
v8::Local<v8::ArrayBuffer> array_buffer =
v8::ArrayBuffer::New(isolate, array_size * sizeof(float));
@@ -482,18 +488,23 @@ bool AudioWorkletProcessor::CopyParamValueMapToObject(
v8::Local<v8::Value> param_array_value;
if (!params_object->Get(context, V8String(isolate, param_name))
- .ToLocal(&param_array_value)) {
+ .ToLocal(&param_array_value) ||
+ !param_array_value->IsFloat32Array()) {
return false;
}
- DCHECK(param_array_value->IsFloat32Array());
+
v8::Local<v8::Float32Array> float32_array =
param_array_value.As<v8::Float32Array>();
+ size_t array_length = float32_array->Length();
+
+ // The |float32_array| is neither 1 nor 128 frames, or the array buffer is
+ // trasnferred/detached, do not proceed.
+ if ((array_length != 1 && array_length != param_array->size()) ||
+ float32_array->Buffer()->ByteLength() == 0)
+ return false;
- // The Float32Array is either 1 or 128 frames, but it always should be
- // less than equal to the size of the given AudioFloatArray.
- DCHECK_LE(float32_array->Length(), param_array->size());
memcpy(float32_array->Buffer()->GetContents().Data(), param_array->Data(),
- float32_array->Length() * sizeof(float));
+ array_length * sizeof(float));
}
return true;
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-param-getter-overridden.https.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-param-getter-overridden.https.html
new file mode 100644
index 0000000000000000000000000000000000000000..e3fb6e533df8ccaa88564f836239e0c9e9c1d5e4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-param-getter-overridden.https.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>
+ Test if AudioWorkletProcessor with invalid parameters array getter
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/webaudio/resources/audit.js"></script>
+ </head>
+ <body>
+ <script id="layout-test-code">
+ let audit = Audit.createTaskRunner();
+
+ // Arbitrarily determined. Any numbers should work.
+ let sampleRate = 16000;
+ let renderLength = 1280;
+ let context;
+ let filePath = 'processors/invalid-param-array-processor.js';
+
+ audit.define('Initializing AudioWorklet and Context', async (task) => {
+ context = new OfflineAudioContext(1, renderLength, sampleRate);
+ await context.audioWorklet.addModule(filePath);
+ task.done();
+ });
+
+ audit.define('Verifying AudioParam in AudioWorkletNode',
+ async (task, should) => {
+ let buffer = context.createBuffer(1, 2, context.sampleRate);
+ buffer.getChannelData(0)[0] = 1;
+
+ let source = new AudioBufferSourceNode(context);
+ source.buffer = buffer;
+ source.loop = true;
+ source.start();
+
+ let workletNode1 =
+ new AudioWorkletNode(context, 'invalid-param-array-1');
+ let workletNode2 =
+ new AudioWorkletNode(context, 'invalid-param-array-2');
+ workletNode1.connect(workletNode2).connect(context.destination);
+
+ // Manually invoke the param getter.
+ source.connect(workletNode2.parameters.get('invalidParam'));
+
+ const renderedBuffer = await context.startRendering();
+
+ // |workletNode2| should be no-op after the parameter getter is
+ // invoked. Therefore, the rendered result should be silent.
+ should(renderedBuffer.getChannelData(0), 'The rendered buffer')
+ .beConstantValueOf(0);
+ task.done();
+ }
+ );
+
+ audit.run();
+ </script>
+ </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/invalid-param-array-processor.js b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/invalid-param-array-processor.js
new file mode 100644
index 0000000000000000000000000000000000000000..e4a5dc39ba16b282e254eba84e8038ae59a6471d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/processors/invalid-param-array-processor.js
@@ -0,0 +1,47 @@
+/**
+ * @class InvalidParamArrayProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor intentionally returns an array with an invalid size when the
+ * processor's getter is queried.
+ */
+let singleton = undefined;
+let secondFetch = false;
+let useDescriptor = false;
+let processCounter = 0;
+
+class InvalidParamArrayProcessor extends AudioWorkletProcessor {
+ static get parameterDescriptors() {
+ if (useDescriptor)
+ return [{name: 'invalidParam'}];
+ useDescriptor = true;
+ return [];
+ }
+
+ constructor() {
+ super();
+ if (singleton === undefined)
+ singleton = this;
+ return singleton;
+ }
+
+ process(inputs, outputs, parameters) {
+ const output = outputs[0];
+ for (let channel = 0; channel < output.length; ++channel)
+ output[channel].fill(1);
+ return false;
+ }
+}
+
+// This overridden getter is invoked under the hood before process() gets
+// called. After this gets called, process() method above will be invalidated,
+// and mark the worklet node non-functional. (i.e. in an error state)
+Object.defineProperty(Object.prototype, 'invalidParam', {'get': () => {
+ if (secondFetch)
+ return new Float32Array(256);
+ secondFetch = true;
+ return new Float32Array(128);
+}});
+
+registerProcessor('invalid-param-array-1', InvalidParamArrayProcessor);
+registerProcessor('invalid-param-array-2', InvalidParamArrayProcessor);

View File

@@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marijn Kruisselbrink <mek@chromium.org>
Date: Tue, 23 Feb 2021 22:17:17 +0000
Subject: Don't store BlobStorageLimits as a reference in transport strategy.
Rather than storing a const reference to something of unclear lifetime,
just make a copy. We could just copy the specific limits we need, but
there shouldn't be many TransportStrategy instances alive at the same
time anyway, so the cost of duplicating shouldn't be too high.
(cherry picked from commit 9a10c68a381d78088532953aa8e0de0a5ff47316)
(cherry picked from commit 7b51cb5e4e2c6cf9dcf19bd9d7599735efd48110)
Bug: 1180871
Change-Id: Ie1e31728b18f02c5d35df0ac0f285eb8f70cb268
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2713912
Reviewed-by: Olivier Yiptong <oyiptong@chromium.org>
Reviewed-by: Darwin Huang <huangdarwin@chromium.org>
Reviewed-by: Victor Costan <pwnall@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#856503}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2713891
Reviewed-by: Krishna Govind <govind@chromium.org>
Reviewed-by: Srinivas Sista <srinivassista@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4425@{#2}
Cr-Original-Branched-From: 4a7d24ec28ccb96c5a1cfd7b4b40b17070f2c396-refs/heads/master@{#856252}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2713958
Commit-Queue: Krishna Govind <govind@chromium.org>
Cr-Commit-Position: refs/branch-heads/4389@{#1327}
Cr-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
diff --git a/storage/browser/blob/blob_transport_strategy.cc b/storage/browser/blob/blob_transport_strategy.cc
index eb66014792246254db1c825b61bd18e3190970de..5ae41639f149f8ff3ead9633d3aa834ac05a8e5f 100644
--- a/storage/browser/blob/blob_transport_strategy.cc
+++ b/storage/browser/blob/blob_transport_strategy.cc
@@ -239,7 +239,7 @@ class DataPipeTransportStrategy : public BlobTransportStrategy {
}
}
- const BlobStorageLimits& limits_;
+ const BlobStorageLimits limits_;
base::circular_deque<base::OnceClosure> requests_;
mojo::ScopedDataPipeConsumerHandle consumer_handle_;
@@ -336,7 +336,7 @@ class FileTransportStrategy : public BlobTransportStrategy {
std::move(result_callback_).Run(BlobStatus::DONE);
}
- const BlobStorageLimits& limits_;
+ const BlobStorageLimits limits_;
// State used to assign bytes elements to individual files.
// The index of the first file that still has available space.

View File

@@ -0,0 +1,78 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Adam Rice <ricea@chromium.org>
Date: Sat, 5 Dec 2020 03:19:09 +0000
Subject: Update the restricted port list
Add ports 69, 137, 161, 554, 1719, 1720, 1723, 6566 to the restricted
ports list to match Firefox. See
https://hg.mozilla.org/mozilla-central/file/tip/netwerk/base/nsIOService.cpp.
Leave out port 10080 for now as it seems likely to cause compatibility
problems.
BUG=1148309
Change-Id: I16f9a61068dbe35334fd5ca2bf55b3ab0287df74
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2562905
Reviewed-by: David Schinazi <dschinazi@chromium.org>
Commit-Queue: Adam Rice <ricea@chromium.org>
Cr-Commit-Position: refs/heads/master@{#832169}
(cherry picked from commit c36c5078c41bd1a9e2455d747d69ac1703d977d3)
TBR=ricea@chromium.org
Change-Id: I9cc989e46ac63b3c656eb2eaed825add9b8346f8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2574877
Reviewed-by: Adam Rice <ricea@chromium.org>
Commit-Queue: Adam Rice <ricea@chromium.org>
Cr-Commit-Position: refs/branch-heads/4324@{#611}
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
diff --git a/net/base/port_util.cc b/net/base/port_util.cc
index 72af86dd6acf2db65a14b2f1bb2e3a241a1d043d..12bfd9a36a0e8e9331420c597faf670477100e47 100644
--- a/net/base/port_util.cc
+++ b/net/base/port_util.cc
@@ -37,6 +37,7 @@ const int kRestrictedPorts[] = {
42, // name
43, // nicname
53, // domain
+ 69, // tftp
77, // priv-rjs
79, // finger
87, // ttylink
@@ -54,8 +55,10 @@ const int kRestrictedPorts[] = {
119, // nntp
123, // NTP
135, // loc-srv /epmap
+ 137, // netbios
139, // netbios
143, // imap2
+ 161, // snmp
179, // BGP
389, // ldap
427, // SLP (Also used by Apple Filing Protocol)
@@ -70,6 +73,7 @@ const int kRestrictedPorts[] = {
532, // netnews
540, // uucp
548, // AFP (Apple Filing Protocol)
+ 554, // rtsp
556, // remotefs
563, // nntp+ssl
587, // smtp (rfc6409)
@@ -77,12 +81,16 @@ const int kRestrictedPorts[] = {
636, // ldap+ssl
993, // ldap+ssl
995, // pop3+ssl
+ 1719, // h323gatestat
+ 1720, // h323hostcall
+ 1723, // pptp
2049, // nfs
3659, // apple-sasl / PasswordServer
4045, // lockd
5060, // sip
5061, // sips
6000, // X11
+ 6566, // sane-port
6665, // Alternate IRC [Apple addition]
6666, // Alternate IRC [Apple addition]
6667, // Standard IRC [Apple addition]

View File

@@ -0,0 +1,143 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Scott Violet <sky@chromium.org>
Date: Wed, 31 Mar 2021 13:28:05 +0000
Subject: x11/ozone: fix two edge cases
WindowTreeHost::OnHostMovedInPixels() may trigger a nested message
loop (tab dragging), which when the stack unravels means this may
be deleted. This adds an early out if this happens.
X11WholeScreenMoveLoop has a similar issue, in so far as notifying
the delegate may delete this.
BUG=1185482
TEST=WindowTreeHostPlatform.DeleteHostFromOnHostMovedInPixels
(cherry picked from commit 5e3a738b1204941aab9f15c0eb3d06e20fefd96e)
(cherry picked from commit 8ad84a8e7882275fb32f938fd0adc04d1a2a5773)
Change-Id: Ieca1c90b3e4358da50b332abe2941fdbb50c5c25
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2743555
Reviewed-by: Thomas Anderson <thomasanderson@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#860852}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2779886
Cr-Original-Commit-Position: refs/branch-heads/4389@{#1583}
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2794391
Reviewed-by: Scott Violet <sky@chromium.org>
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1583}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/ui/aura/window_tree_host_platform.cc b/ui/aura/window_tree_host_platform.cc
index 917b45bf3f8554c63886af30b1483cd97670299c..c9053e7c7e7abb1cdbaf114028579a0484b1d4a9 100644
--- a/ui/aura/window_tree_host_platform.cc
+++ b/ui/aura/window_tree_host_platform.cc
@@ -214,13 +214,21 @@ void WindowTreeHostPlatform::OnBoundsChanged(const gfx::Rect& new_bounds) {
float current_scale = compositor()->device_scale_factor();
float new_scale = ui::GetScaleFactorForNativeView(window());
gfx::Rect old_bounds = bounds_in_pixels_;
+ auto weak_ref = GetWeakPtr();
bounds_in_pixels_ = new_bounds;
- if (bounds_in_pixels_.origin() != old_bounds.origin())
+ if (bounds_in_pixels_.origin() != old_bounds.origin()) {
OnHostMovedInPixels(bounds_in_pixels_.origin());
+ // Changing the bounds may destroy this.
+ if (!weak_ref)
+ return;
+ }
if (bounds_in_pixels_.size() != old_bounds.size() ||
current_scale != new_scale) {
pending_size_ = gfx::Size();
OnHostResizedInPixels(bounds_in_pixels_.size());
+ // Changing the size may destroy this.
+ if (!weak_ref)
+ return;
}
DCHECK_GT(on_bounds_changed_recursion_depth_, 0);
if (--on_bounds_changed_recursion_depth_ == 0) {
diff --git a/ui/aura/window_tree_host_platform_unittest.cc b/ui/aura/window_tree_host_platform_unittest.cc
index eda14e2f0cdf5015f366aa70ea68ae2a2c2b431e..4de039c88af8a6f0ac03df2f772cfea2dfe3514f 100644
--- a/ui/aura/window_tree_host_platform_unittest.cc
+++ b/ui/aura/window_tree_host_platform_unittest.cc
@@ -34,7 +34,7 @@ class TestWindowTreeHost : public WindowTreeHostPlatform {
// OnHostWill/DidProcessBoundsChange. Additionally, this triggers a bounds
// change from within OnHostResized(). Such a scenario happens in production
// code.
-class TestWindowTreeHostObserver : public aura::WindowTreeHostObserver {
+class TestWindowTreeHostObserver : public WindowTreeHostObserver {
public:
TestWindowTreeHostObserver(WindowTreeHostPlatform* host,
ui::PlatformWindow* platform_window)
@@ -51,7 +51,7 @@ class TestWindowTreeHostObserver : public aura::WindowTreeHostObserver {
return on_host_will_process_bounds_change_count_;
}
- // aura::WindowTreeHostObserver:
+ // WindowTreeHostObserver:
void OnHostResized(WindowTreeHost* host) override {
if (!should_change_bounds_in_on_resized_)
return;
@@ -92,5 +92,41 @@ TEST_F(WindowTreeHostPlatformTest, HostWillProcessBoundsChangeRecursion) {
EXPECT_EQ(1, observer.on_host_will_process_bounds_change_count());
}
+// Deletes WindowTreeHostPlatform from OnHostMovedInPixels().
+class DeleteHostWindowTreeHostObserver : public WindowTreeHostObserver {
+ public:
+ explicit DeleteHostWindowTreeHostObserver(
+ std::unique_ptr<TestWindowTreeHost> host)
+ : host_(std::move(host)) {
+ host_->AddObserver(this);
+ }
+ ~DeleteHostWindowTreeHostObserver() override = default;
+
+ TestWindowTreeHost* host() { return host_.get(); }
+
+ // WindowTreeHostObserver:
+ void OnHostMovedInPixels(WindowTreeHost* host,
+ const gfx::Point& new_origin_in_pixels) override {
+ host_->RemoveObserver(this);
+ host_.reset();
+ }
+
+ private:
+ std::unique_ptr<TestWindowTreeHost> host_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeleteHostWindowTreeHostObserver);
+};
+
+// Verifies WindowTreeHostPlatform can be safely deleted when calling
+// OnHostMovedInPixels().
+// Regression test for https://crbug.com/1185482
+TEST_F(WindowTreeHostPlatformTest, DeleteHostFromOnHostMovedInPixels) {
+ std::unique_ptr<TestWindowTreeHost> host =
+ std::make_unique<TestWindowTreeHost>();
+ DeleteHostWindowTreeHostObserver observer(std::move(host));
+ observer.host()->SetBoundsInPixels(gfx::Rect(1, 2, 3, 4));
+ EXPECT_EQ(nullptr, observer.host());
+}
+
} // namespace
} // namespace aura
diff --git a/ui/base/x/x11_whole_screen_move_loop.cc b/ui/base/x/x11_whole_screen_move_loop.cc
index 39f4d0c12aa1feb1702c3f4aa4ba0f62be591197..2bbb1f035b0db8de218ce629cc16aab91cf8519b 100644
--- a/ui/base/x/x11_whole_screen_move_loop.cc
+++ b/ui/base/x/x11_whole_screen_move_loop.cc
@@ -62,9 +62,13 @@ X11WholeScreenMoveLoop::~X11WholeScreenMoveLoop() = default;
void X11WholeScreenMoveLoop::DispatchMouseMovement() {
if (!last_motion_in_screen_)
return;
+ auto weak_ref = weak_factory_.GetWeakPtr();
delegate_->OnMouseMovement(last_motion_in_screen_->root_location(),
last_motion_in_screen_->flags(),
last_motion_in_screen_->time_stamp());
+ // The delegate may delete this during dispatch.
+ if (!weak_ref)
+ return;
last_motion_in_screen_.reset();
}

View File

@@ -0,0 +1,110 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Xiaocheng Hu <xiaochengh@chromium.org>
Date: Wed, 3 Feb 2021 14:56:15 +0000
Subject: Move FontPreloadManager to Oilpan
Currently, TimerBase cannot correctly track the lifetime of objects
embedded in GC-ed objects, like FontPreloadManager which is embedded in
Document. This causes some memory safety issues.
This patch moves FontPreloadManager to Oilpan to avoid the issue.
(cherry picked from commit d31bbf2910ee44e4a206d926ddae6827d16a2754)
(cherry picked from commit cdab130053839ffae4a02d00812c1c3a0ecf01bd)
Bug: 1154965
Change-Id: I490b416abc6a997034baaa7994cd3a50bca7e055
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2611755
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#841039}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2653946
Commit-Queue: Kentaro Hara <haraken@chromium.org>
Auto-Submit: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4324@{#2045}
Cr-Original-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2665939
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1536}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 2fea6ad5cb19e42dbb51a6432ce119b935c23d8f..f84f12cfa8ea70051bcdc82e723816d4ae266b5d 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -791,7 +791,7 @@ Document::Document(const DocumentInit& initializer,
MakeGarbageCollected<DisplayLockDocumentState>(this)),
permission_service_(GetExecutionContext()),
has_trust_tokens_answerer_(GetExecutionContext()),
- font_preload_manager_(*this) {
+ font_preload_manager_(MakeGarbageCollected<FontPreloadManager>(*this)) {
GetOriginTrialContext()->BindExecutionContext(GetExecutionContext());
if (dom_window_) {
@@ -6892,7 +6892,7 @@ void Document::BeginLifecycleUpdatesIfRenderingReady() {
return;
if (!HaveRenderBlockingResourcesLoaded())
return;
- font_preload_manager_.WillBeginRendering();
+ font_preload_manager_->WillBeginRendering();
View()->BeginLifecycleUpdates();
}
@@ -7660,7 +7660,7 @@ bool Document::HaveScriptBlockingStylesheetsLoaded() const {
bool Document::HaveRenderBlockingResourcesLoaded() const {
return HaveImportsLoaded() &&
style_engine_->HaveRenderBlockingStylesheetsLoaded() &&
- !font_preload_manager_.HasPendingRenderBlockingFonts();
+ !font_preload_manager_->HasPendingRenderBlockingFonts();
}
Locale& Document::GetCachedLocale(const AtomicString& locale) {
@@ -8503,7 +8503,7 @@ void Document::ClearUseCounterForTesting(mojom::WebFeature feature) {
}
void Document::FontPreloadingFinishedOrTimedOut() {
- DCHECK(!font_preload_manager_.HasPendingRenderBlockingFonts());
+ DCHECK(!font_preload_manager_->HasPendingRenderBlockingFonts());
if (IsA<HTMLDocument>(this) && body()) {
// For HTML, we resume only when we're past the body tag, so that we should
// have something to paint now.
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index b197ad6e06c6ba1b609607a78aa798f1cc397a3e..b092be4c8bd55567c14d81c9bee343da432747a0 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -1647,7 +1647,7 @@ class CORE_EXPORT Document : public ContainerNode,
unsigned new_length);
void NotifyChangeChildren(const ContainerNode& container);
- FontPreloadManager& GetFontPreloadManager() { return font_preload_manager_; }
+ FontPreloadManager& GetFontPreloadManager() { return *font_preload_manager_; }
void FontPreloadingFinishedOrTimedOut();
void IncrementAsyncScriptCount() { async_script_count_++; }
@@ -2230,7 +2230,7 @@ class CORE_EXPORT Document : public ContainerNode,
HeapHashSet<Member<ScriptPromiseResolver>>
pending_has_trust_tokens_resolvers_;
- FontPreloadManager font_preload_manager_;
+ Member<FontPreloadManager> font_preload_manager_;
int async_script_count_ = 0;
bool first_paint_recorded_ = false;
diff --git a/third_party/blink/renderer/core/loader/font_preload_manager.h b/third_party/blink/renderer/core/loader/font_preload_manager.h
index 3e98fc931a205b7e20b119e7af5a5bbac1eee2b5..631f0f95e7e70d3e1bf73c78f725fdf756a721eb 100644
--- a/third_party/blink/renderer/core/loader/font_preload_manager.h
+++ b/third_party/blink/renderer/core/loader/font_preload_manager.h
@@ -20,9 +20,8 @@ class ResourceFinishObserver;
// API) and notifies the relevant document, so that it can manage the first
// rendering timing to work with preloaded fonts.
// Design doc: https://bit.ly/36E8UKB
-class CORE_EXPORT FontPreloadManager final {
- DISALLOW_NEW();
-
+class CORE_EXPORT FontPreloadManager final
+ : public GarbageCollected<FontPreloadManager> {
public:
explicit FontPreloadManager(Document&);
~FontPreloadManager() = default;

View File

@@ -0,0 +1,195 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Tue, 12 Jan 2021 18:36:22 +0000
Subject: Mojo: Fix UAF on NodeChannel
TBR=rockot@google.com
(cherry picked from commit 9c8a98b3983dd1c7828ceae2fc8a5a2e9bad1f68)
(cherry picked from commit 06fe641d21bda1b5869a46e59b13873762ce1324)
Fixed: 1162198
Change-Id: Ief850903a7e6ba3d7c5c0129704d1f80aa3467ce
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2612085
Commit-Queue: Ken Rockot <rockot@google.com>
Reviewed-by: Ken Rockot <rockot@google.com>
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#840942}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2621996
Cr-Original-Commit-Position: refs/branch-heads/4324@{#1637}
Cr-Original-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2623929
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1517}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/mojo/core/BUILD.gn b/mojo/core/BUILD.gn
index c42daf24d62b3a1c8479466d1bc4efe753099136..a7f574455ac02b656a451257cdc11a2968dd5b68 100644
--- a/mojo/core/BUILD.gn
+++ b/mojo/core/BUILD.gn
@@ -309,6 +309,7 @@ source_set("test_sources") {
"data_pipe_unittest.cc",
"invitation_unittest.cc",
"multiprocess_message_pipe_unittest.cc",
+ "node_controller_unittest.cc",
"platform_wrapper_unittest.cc",
]
}
diff --git a/mojo/core/core.cc b/mojo/core/core.cc
index 6d06ab1fdee75c8fc8670ff7a35923aa90c4bf8c..5eed4e1be13df656897c60378dde8ec024e81a59 100644
--- a/mojo/core/core.cc
+++ b/mojo/core/core.cc
@@ -137,7 +137,7 @@ void Core::SetIOTaskRunner(
NodeController* Core::GetNodeController() {
base::AutoLock lock(node_controller_lock_);
if (!node_controller_)
- node_controller_.reset(new NodeController(this));
+ node_controller_ = std::make_unique<NodeController>();
return node_controller_.get();
}
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc
index ff93f0c3a6b2bf4a340e027ee803b9006152f031..c7646fa4dc5c5062e8a8a620e55839301af51bed 100644
--- a/mojo/core/node_controller.cc
+++ b/mojo/core/node_controller.cc
@@ -21,7 +21,6 @@
#include "mojo/core/broker.h"
#include "mojo/core/broker_host.h"
#include "mojo/core/configuration.h"
-#include "mojo/core/core.h"
#include "mojo/core/request_context.h"
#include "mojo/core/user_message_impl.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
@@ -146,10 +145,8 @@ class ThreadDestructionObserver
NodeController::~NodeController() = default;
-NodeController::NodeController(Core* core)
- : core_(core),
- name_(GetRandomNodeName()),
- node_(new ports::Node(name_, this)) {
+NodeController::NodeController()
+ : name_(GetRandomNodeName()), node_(new ports::Node(name_, this)) {
DVLOG(1) << "Initializing node " << name_;
}
@@ -587,10 +584,17 @@ void NodeController::AddPeer(const ports::NodeName& name,
}
}
-void NodeController::DropPeer(const ports::NodeName& name,
+void NodeController::DropPeer(const ports::NodeName& node_name,
NodeChannel* channel) {
DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
+ // NOTE: Either the `peers_` erasure or the `pending_invitations_` erasure
+ // below, if executed, may drop the last reference to the named NodeChannel
+ // and thus result in its deletion. The passed `node_name` argument may be
+ // owned by that same NodeChannel, so we make a copy of it here to avoid
+ // potentially unsafe references further below.
+ ports::NodeName name = node_name;
+
{
base::AutoLock lock(peers_lock_);
auto it = peers_.find(name);
diff --git a/mojo/core/node_controller.h b/mojo/core/node_controller.h
index 9494de5b809e0216fde750960cd5f86c2f14b46e..6f9f0680062db679587ab1846c768846f0fbcb13 100644
--- a/mojo/core/node_controller.h
+++ b/mojo/core/node_controller.h
@@ -52,11 +52,10 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
};
// |core| owns and out-lives us.
- explicit NodeController(Core* core);
+ NodeController();
~NodeController() override;
const ports::NodeName& name() const { return name_; }
- Core* core() const { return core_; }
ports::Node* node() const { return node_.get(); }
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner() const {
return io_task_runner_;
@@ -135,6 +134,8 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
base::span<const unsigned char> data);
static void DeserializeMessageAsEventForFuzzer(Channel::MessagePtr message);
+ scoped_refptr<NodeChannel> GetBrokerChannel();
+
private:
friend Core;
@@ -176,7 +177,6 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
scoped_refptr<NodeChannel> GetPeerChannel(const ports::NodeName& name);
scoped_refptr<NodeChannel> GetInviterChannel();
- scoped_refptr<NodeChannel> GetBrokerChannel();
void AddPeer(const ports::NodeName& name,
scoped_refptr<NodeChannel> channel,
@@ -254,7 +254,6 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
void ForceDisconnectProcessForTestingOnIOThread(base::ProcessId process_id);
// These are safe to access from any thread as long as the Node is alive.
- Core* const core_;
const ports::NodeName name_;
const std::unique_ptr<ports::Node> node_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
@@ -319,7 +318,7 @@ class MOJO_SYSTEM_IMPL_EXPORT NodeController : public ports::NodeDelegate,
AtomicFlag shutdown_callback_flag_;
// All other fields below must only be accessed on the I/O thread, i.e., the
- // thread on which core_->io_task_runner() runs tasks.
+ // thread on which `io_task_runner_` runs tasks.
// Channels to invitees during handshake.
NodeMap pending_invitations_;
diff --git a/mojo/core/node_controller_unittest.cc b/mojo/core/node_controller_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..316e162376323f27f83868d6b943c40e395511bb
--- /dev/null
+++ b/mojo/core/node_controller_unittest.cc
@@ -0,0 +1,42 @@
+// Copyright 2013 The Chromium 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 "base/logging.h"
+#include "mojo/core/core.h"
+#include "mojo/core/test/mojo_test_base.h"
+#include "mojo/public/c/system/types.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace core {
+namespace {
+
+using NodeControllerTest = test::MojoTestBase;
+
+TEST_F(NodeControllerTest, AcceptInvitationFailure) {
+ // Spawn a child process that will send an invalid AcceptInvitation
+ // NodeChannel message. This is a regression test for
+ // https://crbug.com/1162198.
+ RunTestClient("SendInvalidAcceptInvitation",
+ [&](MojoHandle h) { WriteMessage(h, "hi"); });
+}
+
+DEFINE_TEST_CLIENT_TEST_WITH_PIPE(SendInvalidAcceptInvitation,
+ NodeControllerTest,
+ h) {
+ // A little communication to synchronize against Mojo bringup. By the time
+ // this read completes, we must have an internal NodeController with the
+ // parent test process connected as its broker.
+ EXPECT_EQ("hi", ReadMessage(h));
+
+ // Send an unexpected AcceptInvitation message to the parent process. This
+ // exercises the regression code path in the parent process.
+ NodeController* controller = Core::Get()->GetNodeController();
+ scoped_refptr<NodeChannel> channel = controller->GetBrokerChannel();
+ channel->AcceptInvitation(ports::NodeName{0, 0}, ports::NodeName{0, 0});
+}
+
+} // namespace
+} // namespace core
+} // namespace mojo

View File

@@ -0,0 +1,73 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Harald Alvestrand <hta@chromium.org>
Date: Tue, 2 Mar 2021 17:33:49 +0000
Subject: Fix GetP2PSocketManager ownership
Let it return a mojo::SharedRemote<> instead of a raw pointer - this is
a decoration around a shared_refptr.
(cherry picked from commit 82cdc0781ceb4c22ef5903cf3115bea518a5523b)
(cherry picked from commit 6ed1c0c425e03172c77ba0f1465fe3ade79f2b2a)
Bug: chromium:1172054
Change-Id: I49bd22a0dc949bf869744d2ad25c1afcaea7fdbc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2692532
Reviewed-by: Guido Urdaneta <guidou@chromium.org>
Commit-Queue: Harald Alvestrand <hta@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#854050}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2709590
Reviewed-by: Harald Alvestrand <hta@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4389@{#1280}
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2726713
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1555}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc b/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc
index 29884a255f24556f4dc8b41b22304938a4f0d775..72ec477f57871b460adf83ea9e1a4bd217d5eebe 100644
--- a/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc
+++ b/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc
@@ -36,7 +36,7 @@ void P2PSocketDispatcher::RemoveNetworkListObserver(
network_list_observers_->RemoveObserver(network_list_observer);
}
-network::mojom::blink::P2PSocketManager*
+mojo::SharedRemote<network::mojom::blink::P2PSocketManager>
P2PSocketDispatcher::GetP2PSocketManager() {
base::AutoLock lock(p2p_socket_manager_lock_);
if (!p2p_socket_manager_) {
@@ -56,7 +56,7 @@ P2PSocketDispatcher::GetP2PSocketManager() {
*main_task_runner_.get(), FROM_HERE,
CrossThreadBindOnce(&P2PSocketDispatcher::RequestInterfaceIfNecessary,
scoped_refptr<P2PSocketDispatcher>(this)));
- return p2p_socket_manager_.get();
+ return p2p_socket_manager_;
}
void P2PSocketDispatcher::NetworkListChanged(
diff --git a/third_party/blink/renderer/platform/p2p/socket_dispatcher.h b/third_party/blink/renderer/platform/p2p/socket_dispatcher.h
index c250d2af99d5291f34a7e3bfdb63fcbb70a5bd73..84e9c34c0896db5039d9cf8f51167d69ceec9be2 100644
--- a/third_party/blink/renderer/platform/p2p/socket_dispatcher.h
+++ b/third_party/blink/renderer/platform/p2p/socket_dispatcher.h
@@ -66,7 +66,8 @@ class PLATFORM_EXPORT P2PSocketDispatcher
void RemoveNetworkListObserver(
blink::NetworkListObserver* network_list_observer) override;
- network::mojom::blink::P2PSocketManager* GetP2PSocketManager();
+ mojo::SharedRemote<network::mojom::blink::P2PSocketManager>
+ GetP2PSocketManager();
private:
friend class base::RefCountedThreadSafe<P2PSocketDispatcher>;
@@ -95,7 +96,7 @@ class PLATFORM_EXPORT P2PSocketDispatcher
mojo::PendingReceiver<network::mojom::blink::P2PSocketManager>
p2p_socket_manager_receiver_;
mojo::SharedRemote<network::mojom::blink::P2PSocketManager>
- p2p_socket_manager_;
+ p2p_socket_manager_ GUARDED_BY(p2p_socket_manager_lock_);
base::Lock p2p_socket_manager_lock_;
// Cached from last |NetworkListChanged| call.

View File

@@ -0,0 +1,171 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hongchan Choi <hongchan@chromium.org>
Date: Tue, 2 Mar 2021 15:17:19 +0000
Subject: Introduce AudioBuffers for user access in ScriptProcessorNode
This CL adds new AudioBuffers for the access from the user code.
(cherry picked from commit b9e60ddc7606689e508f295077656389380288ba)
(cherry picked from commit c281886ca9ff22f6e75c8c1967dab9bf18b9942d)
(cherry picked from commit 33861dcf6d15415b6abf2152440906fafb74a27a)
Bug: 1177465
Test: The local ASAN build doesn't reproduce on given POCs.
Change-Id: Id9a3505ddb9ab61b4442385d0b830ef56f65f797
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2718543
Auto-Submit: Hongchan Choi <hongchan@chromium.org>
Reviewed-by: Raymond Toy <rtoy@chromium.org>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Original-Original-Original-Commit-Position: refs/heads/master@{#857817}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2719239
Reviewed-by: Krishna Govind <govind@chromium.org>
Cr-Original-Original-Commit-Position: refs/branch-heads/4429@{#2}
Cr-Original-Original-Branched-From: 19b974fae7ec51a60e2f1044d81e2e1b32be179b-refs/heads/master@{#857666}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2721252
Reviewed-by: Adrian Taylor <adetaylor@google.com>
Commit-Queue: Krishna Govind <govind@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4324@{#2250}
Cr-Original-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2727696
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1553}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
index 6e80b23a32dd1895a0d51d08ee16c8cb2d44fc55..d46e17440a9f3c2de488432bf3efdba5ac01f193 100644
--- a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
@@ -42,6 +42,28 @@
namespace blink {
+namespace {
+
+bool IsAudioBufferDetached(AudioBuffer* buffer) {
+ bool is_buffer_detached = false;
+ for (unsigned channel = 0; channel < buffer->numberOfChannels(); ++channel) {
+ if (buffer->getChannelData(channel)->buffer()->IsDetached()) {
+ is_buffer_detached = true;
+ break;
+ }
+ }
+
+ return is_buffer_detached;
+}
+
+bool BufferTopologyMatches(AudioBuffer* buffer_1, AudioBuffer* buffer_2) {
+ return (buffer_1->numberOfChannels() == buffer_2->numberOfChannels()) &&
+ (buffer_1->length() == buffer_2->length()) &&
+ (buffer_1->sampleRate() == buffer_2->sampleRate());
+}
+
+} // namespace
+
ScriptProcessorHandler::ScriptProcessorHandler(
AudioNode& node,
float sample_rate,
@@ -335,6 +357,12 @@ ScriptProcessorNode::ScriptProcessorNode(BaseAudioContext& context,
input_buffers_.push_back(input_buffer);
output_buffers_.push_back(output_buffer);
}
+
+ external_input_buffer_ = AudioBuffer::Create(
+ number_of_input_channels, buffer_size, sample_rate);
+ external_output_buffer_ = AudioBuffer::Create(
+ number_of_output_channels, buffer_size, sample_rate);
+
SetHandler(ScriptProcessorHandler::Create(
*this, sample_rate, buffer_size, number_of_input_channels,
number_of_output_channels, input_buffers_, output_buffers_));
@@ -476,11 +504,62 @@ uint32_t ScriptProcessorNode::bufferSize() const {
void ScriptProcessorNode::DispatchEvent(double playback_time,
uint32_t double_buffer_index) {
- AudioBuffer* input_buffer = input_buffers_.at(double_buffer_index).Get();
- AudioBuffer* output_buffer = output_buffers_.at(double_buffer_index).Get();
- DCHECK(output_buffer);
+ DCHECK(IsMainThread());
+
+ AudioBuffer* backing_input_buffer =
+ input_buffers_.at(double_buffer_index).Get();
+
+ // The backing buffer can be nullptr, when the number of input channels is 0.
+ if (backing_input_buffer) {
+ // Also the author code might have transferred |external_input_buffer| to
+ // other threads or replaced it with a different AudioBuffer object. Then
+ // re-create a new buffer instance.
+ if (IsAudioBufferDetached(external_input_buffer_) ||
+ !BufferTopologyMatches(backing_input_buffer,
+ external_input_buffer_)) {
+ external_input_buffer_ = AudioBuffer::Create(
+ backing_input_buffer->numberOfChannels(),
+ backing_input_buffer->length(),
+ backing_input_buffer->sampleRate());
+ }
+
+ for (unsigned channel = 0;
+ channel < backing_input_buffer->numberOfChannels(); ++channel) {
+ const float* source = static_cast<float*>(
+ backing_input_buffer->getChannelData(channel)->buffer()->Data());
+ float* destination = static_cast<float*>(
+ external_input_buffer_->getChannelData(channel)->buffer()->Data());
+ memcpy(destination, source,
+ backing_input_buffer->length() * sizeof(float));
+ }
+ }
+
AudioNode::DispatchEvent(*AudioProcessingEvent::Create(
- input_buffer, output_buffer, playback_time));
+ external_input_buffer_, external_output_buffer_, playback_time));
+
+ AudioBuffer* backing_output_buffer =
+ output_buffers_.at(double_buffer_index).Get();
+
+ if (backing_output_buffer) {
+ if (IsAudioBufferDetached(external_output_buffer_) ||
+ !BufferTopologyMatches(backing_output_buffer,
+ external_output_buffer_)) {
+ external_output_buffer_ = AudioBuffer::Create(
+ backing_output_buffer->numberOfChannels(),
+ backing_output_buffer->length(),
+ backing_output_buffer->sampleRate());
+ }
+
+ for (unsigned channel = 0;
+ channel < backing_output_buffer->numberOfChannels(); ++channel) {
+ const float* source = static_cast<float*>(
+ external_output_buffer_->getChannelData(channel)->buffer()->Data());
+ float* destination = static_cast<float*>(
+ backing_output_buffer->getChannelData(channel)->buffer()->Data());
+ memcpy(destination, source,
+ backing_output_buffer->length() * sizeof(float));
+ }
+ }
}
bool ScriptProcessorNode::HasPendingActivity() const {
@@ -499,6 +578,8 @@ bool ScriptProcessorNode::HasPendingActivity() const {
void ScriptProcessorNode::Trace(Visitor* visitor) const {
visitor->Trace(input_buffers_);
visitor->Trace(output_buffers_);
+ visitor->Trace(external_input_buffer_);
+ visitor->Trace(external_output_buffer_);
AudioNode::Trace(visitor);
}
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node.h b/third_party/blink/renderer/modules/webaudio/script_processor_node.h
index a93dbacc70709c063b452be3e5fe4b56fcaf7c4a..ea5ad1c326d6eb202ba6b8eba0ac5b5d0f1f61b1 100644
--- a/third_party/blink/renderer/modules/webaudio/script_processor_node.h
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_node.h
@@ -169,6 +169,8 @@ class ScriptProcessorNode final
private:
HeapVector<Member<AudioBuffer>> input_buffers_;
HeapVector<Member<AudioBuffer>> output_buffers_;
+ Member<AudioBuffer> external_input_buffer_;
+ Member<AudioBuffer> external_output_buffer_;
};
} // namespace blink

View File

@@ -0,0 +1,163 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christoph Schwering <schwering@google.com>
Date: Thu, 4 Mar 2021 17:21:46 +0000
Subject: Limit preview and filling only for non-state fields.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The number of times a value is filled into different fields is limited.
The exception are state fields because websites sometimes have one
state select box for each country and display the relevant select
box once the respective country has been selected.
This CL simplifies this mechanism and makes it more explicit by
encoding the type-dependent limits in TypeValueFormFillingLimit().
As a side effect, the limits apply not just to filled fields but also
unfilled fields of the same type.
(cherry picked from commit 18d3f86206e88156e2eb20c1f691b3b40a779150)
Bug: 1075734, 1084903
Change-Id: Icc5e8e082850ed44d9c7fbbc911d03a95033d81f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2557977
Commit-Queue: Matthias Körber <koerber@google.com>
Reviewed-by: Matthias Körber <koerber@google.com>
Auto-Submit: Christoph Schwering <schwering@google.com>
Cr-Original-Commit-Position: refs/heads/master@{#830778}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2731409
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1560}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 4e8321b85e329139012a5026b044d2c070750151..ded9c514894eee34a34eb562b08e7484673dfc4a 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -20,6 +20,7 @@
#include "base/check_op.h"
#include "base/command_line.h"
#include "base/containers/adapters.h"
+#include "base/containers/flat_map.h"
#include "base/feature_list.h"
#include "base/files/file_util.h"
#include "base/guid.h"
@@ -424,9 +425,15 @@ const char* SubmissionSourceToString(SubmissionSource source) {
// Returns how many fields with type |field_type| may be filled in a form at
// maximum.
-int TypeValueFormFillingLimit(ServerFieldType field_type) {
- return field_type == CREDIT_CARD_NUMBER ? kCreditCardTypeValueFormFillingLimit
- : kTypeValueFormFillingLimit;
+size_t TypeValueFormFillingLimit(ServerFieldType field_type) {
+ switch (field_type) {
+ case CREDIT_CARD_NUMBER:
+ return kCreditCardTypeValueFormFillingLimit;
+ case ADDRESS_HOME_STATE:
+ return kStateTypeValueFormFillingLimit;
+ default:
+ return kTypeValueFormFillingLimit;
+ }
}
} // namespace
@@ -1757,7 +1764,8 @@ void AutofillManager::FillOrPreviewDataModelForm(
// Count the number of times the value of a specific type was filled into the
// form.
- std::map<ServerFieldType, int> type_filling_count;
+ base::flat_map<ServerFieldType, size_t> type_filling_count;
+ type_filling_count.reserve(form_structure->field_count());
for (size_t i = 0; i < form_structure->field_count(); ++i) {
std::string field_number = base::StringPrintf("Field %zu", i);
@@ -1841,7 +1849,7 @@ void AutofillManager::FillOrPreviewDataModelForm(
// A field with a specific type is only allowed to be filled a limited
// number of times given by |TypeValueFormFillingLimit(field_type)|.
- if (type_filling_count[field_type] >=
+ if (++type_filling_count[field_type] >
TypeValueFormFillingLimit(field_type)) {
buffer << Tr{} << field_number
<< "Skipped: field-type filling-limit reached";
@@ -1877,10 +1885,6 @@ void AutofillManager::FillOrPreviewDataModelForm(
bool has_value_after = !result.fields[i].value.empty();
bool is_autofilled_after = result.fields[i].is_autofilled;
- // If the field was actually filled, increment the filling counter.
- if (is_autofilled_after)
- type_filling_count[field_type]++;
-
buffer << Tr{} << field_number
<< base::StringPrintf(
"Fillable - has value: %d->%d; autofilled: %d->%d. %s",
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
index 79f827e5c8ea473d8c6e9bcef42d58427e278fc7..fd5973da9c997dc4c74489dd112b541f86d9bf57 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -2903,6 +2903,14 @@ TEST_F(AutofillManagerTest, OnlyCountFilledSelectionBoxesForTypeFillingLimit) {
form.fields.push_back(field);
}
+ // Create a selection box for the state that hat the correct entry to be
+ // filled with user data. Note, TN is the official abbreviation for Tennessee.
+ for (int i = 0; i < 20; ++i) {
+ test::CreateTestSelectField("Country", "country", "", {"DE", "FR", "US"},
+ {"DE", "FR", "US"}, 3, &field);
+ form.fields.push_back(field);
+ }
+
std::vector<FormData> forms(1, form);
FormsSeen(forms);
@@ -2939,17 +2947,18 @@ TEST_F(AutofillManagerTest, OnlyCountFilledSelectionBoxesForTypeFillingLimit) {
response_data.fields[4 + i]);
}
- // Verify that the next 8 selection boxes are correctly filled again.
- for (int i = 0; i < 8; i++) {
+ // Verify that the remaining selection boxes are correctly filled again
+ // because there's no limit on filling ADDRESS_HOME_STATE fields.
+ for (int i = 0; i < 20; i++) {
ExpectFilledField("State", "state", "TN", "select-one",
response_data.fields[24 + i]);
}
- // Verify that the last 12 boxes are not filled because the filling limit for
- // the state type is already reached.
- for (int i = 0; i < 12; i++) {
- ExpectFilledField("State", "state", "", "select-one",
- response_data.fields[32 + i]);
+ // Verify that only the first 9 of the remaining selection boxes are
+ // correctly filled due to the limit on filling ADDRESS_HOME_COUNTRY fields.
+ for (int i = 0; i < 20; i++) {
+ ExpectFilledField("Country", "country", i < 9 ? "US" : "", "select-one",
+ response_data.fields[44 + i]);
}
}
diff --git a/components/autofill/core/common/autofill_constants.h b/components/autofill/core/common/autofill_constants.h
index 84c5b916b0330ab8305db7b1831b42fa42843708..2d6ade5e6bea81ec4383d0345863514e1b551ea8 100644
--- a/components/autofill/core/common/autofill_constants.h
+++ b/components/autofill/core/common/autofill_constants.h
@@ -68,12 +68,14 @@ const int64_t kAutocompleteRetentionPolicyPeriodInDays = 14 * 31;
// Limits the number of times the value of a specific type can be filled into a
// form.
-constexpr int kTypeValueFormFillingLimit = 9;
-
// Credit card numbers are sometimes distributed between up to 19 individual
-// fields. Therefore, credit cards need a higher limit compared to
-// |kTypeValueFormFillingLimit|.
-constexpr int kCreditCardTypeValueFormFillingLimit = 19;
+// fields. Therefore, credit cards need a higher limit.
+// State fields are effecectively unlimited because there are sometimes hidden
+// fields select boxes, each with a list of states for one specific countries,
+// which are displayed only upon country selection.
+constexpr size_t kTypeValueFormFillingLimit = 9;
+constexpr size_t kCreditCardTypeValueFormFillingLimit = 19;
+constexpr size_t kStateTypeValueFormFillingLimit = 1000;
} // namespace autofill

View File

@@ -0,0 +1,70 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lukasz Anforowicz <lukasza@chromium.org>
Date: Thu, 4 Mar 2021 17:07:16 +0000
Subject: M86-LTS: Destroy `url_loader_factories_` before other NetworkContext
fields
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[M86 Merge]: Fixed conflict in network_context.h.
(cherry picked from commit f2b091f02593c67fd67db936452f363102b8d035)
(cherry picked from commit ffeb0731f83f8c4fa72776b658df45f0e6da041c)
Bug: 1174943
Change-Id: I7488c7779f51a3f0d82ecad3d65446032c065b26
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2679230
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
Reviewed-by: Matt Menke <mmenke@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#852311}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2692489
Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Original-Commit-Position: refs/branch-heads/4389@{#986}
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2731372
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1559}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/services/network/network_context.h b/services/network/network_context.h
index 0d9c4cce09db485b5e750921eed703c75ffdf15a..3a88fd24b421411f086a31db34c07ed0f175d14f 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -604,13 +604,6 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
std::set<std::unique_ptr<ProxyLookupRequest>, base::UniquePtrComparator>
proxy_lookup_requests_;
- // This must be below |url_request_context_| so that the URLRequestContext
- // outlives all the URLLoaderFactories and URLLoaders that depend on it;
- // for the same reason, it must also be below |network_context_|.
- std::set<std::unique_ptr<cors::CorsURLLoaderFactory>,
- base::UniquePtrComparator>
- url_loader_factories_;
-
std::set<std::unique_ptr<QuicTransport>, base::UniquePtrComparator>
quic_transports_;
@@ -721,6 +714,19 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
// HttpAuthHandle via |NetworkContext::CreateHttpAuthHandlerFactory|.
net::HttpAuthPreferences http_auth_merged_preferences_;
+ // CorsURLLoaderFactory assumes that fields owned by the NetworkContext always
+ // live longer than the factory. Therefore we want the factories to be
+ // destroyed before other fields above. In particular:
+ // - This must be below |url_request_context_| so that the URLRequestContext
+ // outlives all the URLLoaderFactories and URLLoaders that depend on it;
+ // for the same reason, it must also be below |network_context_|.
+ // - This must be below |loader_count_per_process_| that is touched by
+ // CorsURLLoaderFactory::DestroyURLLoader (see also
+ // https://crbug.com/1174943).
+ std::set<std::unique_ptr<cors::CorsURLLoaderFactory>,
+ base::UniquePtrComparator>
+ url_loader_factories_;
+
base::WeakPtrFactory<NetworkContext> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(NetworkContext);

View File

@@ -0,0 +1,110 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Achuith Bhandarkar <achuith@chromium.org>
Date: Wed, 13 Jan 2021 21:27:05 +0000
Subject: content-visibility: Don't adjust position of a locked hittest result
node.
This patch ensures that if we have a hittest result that has a locked
node, we don't try to recurse into its subtree. This can happen when we
do a PositionWithAffinity check.
R=chrishtr@chromium.org
(cherry picked from commit 8483cf6944e38203c3b247163c54cfa105e89c56)
(cherry picked from commit 3f7b67374a1121b6756ccfd2e4e414987f167489)
Bug: 1162131
Change-Id: I357bd7032c6c2b6c9405bf26c49a36bda22d6a0d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2611453
Reviewed-by: Chris Harrelson <chrishtr@chromium.org>
Commit-Queue: vmpstr <vmpstr@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#840727}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2618603
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: Krishna Govind <govind@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4324@{#1566}
Cr-Original-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2618982
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1520}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/core/layout/hit_test_result.cc b/third_party/blink/renderer/core/layout/hit_test_result.cc
index 1359aa6bdd532028d8280b093a4381a70e4a7577..9d02cabafa3b8acc19ae2c0007c0eb6b86f1fb5d 100644
--- a/third_party/blink/renderer/core/layout/hit_test_result.cc
+++ b/third_party/blink/renderer/core/layout/hit_test_result.cc
@@ -21,12 +21,14 @@
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
#include "third_party/blink/renderer/core/dom/pseudo_element.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/position_with_affinity.h"
+#include "third_party/blink/renderer/core/editing/text_affinity.h"
#include "third_party/blink/renderer/core/editing/visible_units.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
@@ -144,6 +146,20 @@ PositionWithAffinity HitTestResult::GetPosition() const {
LayoutObject* layout_object = GetLayoutObject();
if (!layout_object)
return PositionWithAffinity();
+
+ // We should never have a layout object that is within a locked subtree.
+ CHECK(!DisplayLockUtilities::NearestLockedExclusiveAncestor(*layout_object));
+
+ // If the layout object is blocked by display lock, we return the beginning of
+ // the node as the position. This is because we don't paint contents of the
+ // element. Furthermore, any caret adjustments below can access layout-dirty
+ // state in the subtree of this object.
+ if (layout_object->PaintBlockedByDisplayLock(
+ DisplayLockLifecycleTarget::kChildren)) {
+ return PositionWithAffinity(Position(*inner_node_, 0),
+ TextAffinity::kDefault);
+ }
+
if (inner_possibly_pseudo_node_->IsPseudoElement() &&
inner_possibly_pseudo_node_->GetPseudoId() == kPseudoIdBefore) {
return PositionWithAffinity(MostForwardCaretPosition(
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-080.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-080.html
new file mode 100644
index 0000000000000000000000000000000000000000..d3cea5fb83767ddfc236850097387644e0f74c8e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-080.html
@@ -0,0 +1,31 @@
+<!doctype HTML>
+<html id=html>
+<meta charset="utf8">
+<title>Content Visibility: caret position with html hidden</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
+<meta name="assert" content="caretRangeFromPoint works even if html has content-visibility hidden">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<meter></meter>
+<iframe></iframe>
+<style>
+* {
+ all: initial;
+ content-visibility: hidden;
+}
+</style>
+
+<script>
+test(() => {
+ const range = document.caretRangeFromPoint();
+ assert_not_equals(range, null, "range exists");
+ assert_equals(range.startContainer, html, "startContainer is html");
+ assert_equals(range.startOffset, 0, "startOffset is zero");
+ assert_equals(range.endContainer, html, "endContainer is html");
+ assert_equals(range.endOffset, 0, "endOffset is zero");
+}, "Caret range from point");
+</script>
+</html>

View File

@@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Raymond Toy <rtoy@chromium.org>
Date: Mon, 7 Dec 2020 17:55:30 +0000
Subject: Clear handlers when the base context goes away.
Previously, in BaseAudioContext::Clear() we called
GetDeferredTaskHandler().ClearHandlersToBeDeleted(). But this was
also called in DeferredTaskHandler::ContextWillBeDestroyed(), which is
called in BaseAudioContext::~BaseAudioContext().
There's no need to call this twice while handling the audio context
going away.
Manually verified that the tests from issue 1125635 and 1153658 work,
and the deadlock in issue 1136571 is gone.
Bug: 1150065, 1153658
Change-Id: Iee15c31dc637bf82d66bfd79d5238b1f80813153
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2575418
Commit-Queue: Raymond Toy <rtoy@chromium.org>
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#834265}
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
index e203973a516c630af3decaddc1080ab9697c634a..cd16a1f31fb4d8469f35a8c5e08c51d15efb0cf8 100644
--- a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
+++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
@@ -142,9 +142,8 @@ void BaseAudioContext::Initialize() {
void BaseAudioContext::Clear() {
destination_node_.Clear();
- // The audio rendering thread is dead. Nobody will schedule AudioHandler
- // deletion. Let's do it ourselves.
- GetDeferredTaskHandler().ClearHandlersToBeDeleted();
+ // Make a note that we've cleared out the context so that there's no pending
+ // activity.
is_cleared_ = true;
}

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,81 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniele Castagna <dcastagna@chromium.org>
Date: Mon, 14 Dec 2020 23:03:31 +0000
Subject: viz: Destroy |gpu_memory_buffer_factory_| on IOThread
|gpu_memory_buffer_factory_| weak pointers are checked on the
IOThread.
Weak pointers should be invalidated on the same thread that
checks them.
This CL moves the destruction of |gpu_memory_buffer_factory_|
on the IOThread to avoid possible use after free issues.
Bug: 1152645
Change-Id: I0d42814f0e435a3746728515da1f32d08a1252cf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2563077
Commit-Queue: Daniele Castagna <dcastagna@chromium.org>
Reviewed-by: Andres Calderon Jaramillo <andrescj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836827}
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc
index 98cdbff9bf021f9665abdb339a25753b2e7b4807..6ab1e86035089b748eb636cc5e654702ee19fd9e 100644
--- a/components/viz/service/gl/gpu_service_impl.cc
+++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -428,16 +428,18 @@ GpuServiceImpl::~GpuServiceImpl() {
GetLogMessageManager()->ShutdownLogging();
// Destroy the receiver on the IO thread.
- base::WaitableEvent wait;
- auto destroy_receiver_task = base::BindOnce(
- [](mojo::Receiver<mojom::GpuService>* receiver,
- base::WaitableEvent* wait) {
- receiver->reset();
- wait->Signal();
- },
- &receiver_, &wait);
- if (io_runner_->PostTask(FROM_HERE, std::move(destroy_receiver_task)))
- wait.Wait();
+ {
+ base::WaitableEvent wait;
+ auto destroy_receiver_task = base::BindOnce(
+ [](mojo::Receiver<mojom::GpuService>* receiver,
+ base::WaitableEvent* wait) {
+ receiver->reset();
+ wait->Signal();
+ },
+ &receiver_, base::Unretained(&wait));
+ if (io_runner_->PostTask(FROM_HERE, std::move(destroy_receiver_task)))
+ wait.Wait();
+ }
if (watchdog_thread_)
watchdog_thread_->OnGpuProcessTearDown();
@@ -445,6 +447,26 @@ GpuServiceImpl::~GpuServiceImpl() {
media_gpu_channel_manager_.reset();
gpu_channel_manager_.reset();
+ // Destroy |gpu_memory_buffer_factory_| on the IO thread since its weakptrs
+ // are checked there.
+ {
+ base::WaitableEvent wait;
+ auto destroy_gmb_factory = base::BindOnce(
+ [](std::unique_ptr<gpu::GpuMemoryBufferFactory> gmb_factory,
+ base::WaitableEvent* wait) {
+ gmb_factory.reset();
+ wait->Signal();
+ },
+ std::move(gpu_memory_buffer_factory_), base::Unretained(&wait));
+
+ if (io_runner_->PostTask(FROM_HERE, std::move(destroy_gmb_factory))) {
+ // |gpu_memory_buffer_factory_| holds a raw pointer to
+ // |vulkan_context_provider_|. Waiting here enforces the correct order
+ // of destruction.
+ wait.Wait();
+ }
+ }
+
// Scheduler must be destroyed before sync point manager is destroyed.
scheduler_.reset();
owned_sync_point_manager_.reset();

View File

@@ -0,0 +1,121 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hongchan Choi <hongchan@chromium.org>
Date: Tue, 2 Mar 2021 15:15:59 +0000
Subject: Prevent accessing shared buffers from audio rendering thread
The shared buffer in ScriptProcessorNode can be accessed by the
audio rendering thread when it is held by the main thread.
The solution suggested here is simply to expand the scope of
the mutex to minimize the code change. This is a deprecated
feature in Web Audio, so making significant changes is not
sensible. By locking the entire scope of Process() call, this
area would be immune to the similar problems in the future.
(cherry picked from commit 60987aa224f369fc0ea38c56e498389440921356)
(cherry picked from commit aeb6bc551b607e0c80c232ed4817c0ff5e9a7784)
Bug: 1174582
Test: The repro case doesn't crash on ASAN.
Change-Id: I2b292f94be65e6ec26c6eb0e0ed32b3fb2d88466
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2681193
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Reviewed-by: Raymond Toy <rtoy@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#852240}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2715585
Commit-Queue: Krishna Govind <govind@chromium.org>
Reviewed-by: Srinivas Sista <srinivassista@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4324@{#2238}
Cr-Original-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2726911
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1552}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
index b1ca691b07b53b927a92753906f7f25edebac919..6e80b23a32dd1895a0d51d08ee16c8cb2d44fc55 100644
--- a/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_node.cc
@@ -110,6 +110,14 @@ void ScriptProcessorHandler::Initialize() {
}
void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
+ // The main thread might be accessing the shared buffers. If so, silience
+ // the output and return.
+ MutexTryLocker try_locker(process_event_lock_);
+ if (!try_locker.Locked()) {
+ Output(0).Bus()->Zero();
+ return;
+ }
+
// Discussion about inputs and outputs:
// As in other AudioNodes, ScriptProcessorNode uses an AudioBus for its input
// and output (see inputBus and outputBus below). Additionally, there is a
@@ -181,47 +189,26 @@ void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
buffer_read_write_index_ =
(buffer_read_write_index_ + frames_to_process) % BufferSize();
- // m_bufferReadWriteIndex will wrap back around to 0 when the current input
- // and output buffers are full.
- // When this happens, fire an event and swap buffers.
+ // Fire an event and swap buffers when |buffer_read_write_index_| wraps back
+ // around to 0. It means the current input and output buffers are full.
if (!buffer_read_write_index_) {
- // Avoid building up requests on the main thread to fire process events when
- // they're not being handled. This could be a problem if the main thread is
- // very busy doing other things and is being held up handling previous
- // requests. The audio thread can't block on this lock, so we call
- // tryLock() instead.
- MutexTryLocker try_locker(process_event_lock_);
- if (!try_locker.Locked()) {
- // We're late in handling the previous request. The main thread must be
- // very busy. The best we can do is clear out the buffer ourself here.
- shared_output_buffer->Zero();
+ if (Context()->HasRealtimeConstraint()) {
+ // For a realtime context, fire an event and do not wait.
+ PostCrossThreadTask(
+ *task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&ScriptProcessorHandler::FireProcessEvent,
+ AsWeakPtr(), double_buffer_index_));
} else {
- // With the realtime context, execute the script code asynchronously
- // and do not wait.
- if (Context()->HasRealtimeConstraint()) {
- // Fire the event on the main thread with the appropriate buffer
- // index.
- PostCrossThreadTask(
- *task_runner_, FROM_HERE,
- CrossThreadBindOnce(&ScriptProcessorHandler::FireProcessEvent,
- AsWeakPtr(), double_buffer_index_));
- } else {
- // If this node is in the offline audio context, use the
- // waitable event to synchronize to the offline rendering thread.
- std::unique_ptr<base::WaitableEvent> waitable_event =
- std::make_unique<base::WaitableEvent>();
-
- PostCrossThreadTask(
- *task_runner_, FROM_HERE,
- CrossThreadBindOnce(
- &ScriptProcessorHandler::FireProcessEventForOfflineAudioContext,
- AsWeakPtr(), double_buffer_index_,
- CrossThreadUnretained(waitable_event.get())));
-
- // Okay to block the offline audio rendering thread since it is
- // not the actual audio device thread.
- waitable_event->Wait();
- }
+ // For an offline context, wait until the script execution is finished.
+ std::unique_ptr<base::WaitableEvent> waitable_event =
+ std::make_unique<base::WaitableEvent>();
+ PostCrossThreadTask(
+ *task_runner_, FROM_HERE,
+ CrossThreadBindOnce(
+ &ScriptProcessorHandler::FireProcessEventForOfflineAudioContext,
+ AsWeakPtr(), double_buffer_index_,
+ CrossThreadUnretained(waitable_event.get())));
+ waitable_event->Wait();
}
SwapBuffers();

View File

@@ -0,0 +1,146 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Artem Sumaneev <asumaneev@google.com>
Date: Wed, 3 Feb 2021 15:00:25 +0000
Subject: Fix navigation request reset logic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Do not delete navigation request which has started upon receiving
notification about beforeunload dialog being cancelled, as a) this
navigation request is not waiting for beforeunload and b) it might have
been this navigation request which canceled this beforeunload dialog.
M86 merge conflicts and resolution:
* content/browser/frame_host/*
In ToT files the affected under frame_host directory are moved to
renderer_host dir. Applied patch to frame_host, no further conflicts.
R=alexmos@chromium.org
BUG=1161705
(cherry picked from commit 23c110b5b81dc401ded5d4dcecfab65d5d88fdfa)
(cherry picked from commit 87550e04d9fed4bbedff4546f4161e3c02415d7e)
Change-Id: I7d385d4326fac6f67d17a003679471806b5ad3b2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2624733
Commit-Queue: Alexander Timin <altimin@chromium.org>
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#843343}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2652791
Commit-Queue: Alex Moshchuk <alexmos@chromium.org>
Auto-Submit: Alexander Timin <altimin@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4324@{#2040}
Cr-Original-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2666397
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1537}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc
index a1c72899b940d942bccf25c617ded87081f67901..754563aa43df66edc473e58106200a4b6923716a 100644
--- a/content/browser/frame_host/frame_tree_node.cc
+++ b/content/browser/frame_host/frame_tree_node.cc
@@ -578,10 +578,12 @@ void FrameTreeNode::BeforeUnloadCanceled() {
render_manager_.speculative_frame_host();
if (speculative_frame_host)
speculative_frame_host->ResetLoadingState();
- // Note: there is no need to set an error code on the NavigationHandle here
- // as it has not been created yet. It is only created when the
- // BeforeUnloadCompleted callback is invoked.
- if (navigation_request_)
+ // Note: there is no need to set an error code on the NavigationHandle as
+ // the observers have not been notified about its creation.
+ // We also reset navigation request only when this navigation request was
+ // responsible for this dialog, as a new navigation request might cancel
+ // existing unrelated dialog.
+ if (navigation_request_ && navigation_request_->IsWaitingForBeforeUnload())
ResetNavigationRequest(false);
}
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index 764e1f007b44bda5191e9021be59ab21446f6e55..498a8c3d8bcbea3b411901eaca9544ac5037308e 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -4899,4 +4899,8 @@ void NavigationRequest::UpdateCoopStatus(
}
}
+bool NavigationRequest::IsWaitingForBeforeUnload() {
+ return state_ < WILL_START_NAVIGATION;
+}
+
} // namespace content
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
index 9db96ba9e042507b465821dbb0632317f1f0de70..e6f6e83e7013bd13b504969a8ebfbf5f1428eb2f 100644
--- a/content/browser/frame_host/navigation_request.h
+++ b/content/browser/frame_host/navigation_request.h
@@ -670,6 +670,10 @@ class CONTENT_EXPORT NavigationRequest
// navigation or an error page.
bool IsWaitingToCommit();
+ // Whether this navigation request waits for the result of beforeunload before
+ // proceeding.
+ bool IsWaitingForBeforeUnload();
+
private:
friend class NavigationRequestTest;
diff --git a/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
index 089a0f08c96e7cb366659c633e2fdf5f61904f4c..bf7e8c0706f7694878b817312f4b7f8339d6645e 100644
--- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -1113,6 +1113,51 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBeforeUnloadBrowserTest,
namespace {
+class OnDidStartNavigation : public WebContentsObserver {
+ public:
+ OnDidStartNavigation(WebContents* web_contents,
+ base::RepeatingClosure callback)
+ : WebContentsObserver(web_contents), callback_(callback) {}
+
+ void DidStartNavigation(NavigationHandle* navigation) override {
+ callback_.Run();
+ }
+
+ private:
+ base::RepeatingClosure callback_;
+};
+
+} // namespace
+
+// This test closes beforeunload dialog due to a new navigation starting from
+// within WebContentsObserver::DidStartNavigation. This test succeeds if it
+// doesn't crash with a UAF while loading the second page.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBeforeUnloadBrowserTest,
+ DidStartNavigationClosesDialog) {
+ GURL url1 = embedded_test_server()->GetURL("a.com", "/title1.html");
+ GURL url2 = embedded_test_server()->GetURL("b.com", "/title1.html");
+
+ EXPECT_TRUE(NavigateToURL(shell(), url1));
+
+ // This matches the behaviour of TabModalDialogManager in
+ // components/javascript_dialogs.
+ OnDidStartNavigation close_dialog(web_contents(),
+ base::BindLambdaForTesting([&]() {
+ CloseDialogAndCancel();
+
+ // Check that web_contents() were not
+ // deleted.
+ DCHECK(web_contents()->GetMainFrame());
+ }));
+
+ web_contents()->GetMainFrame()->RunBeforeUnloadConfirm(true,
+ base::DoNothing());
+
+ EXPECT_TRUE(NavigateToURL(shell(), url2));
+}
+
+namespace {
+
// A helper to execute some script in a frame just before it is deleted, such
// that no message loops are pumped and no sync IPC messages are processed
// between script execution and the destruction of the RenderFrameHost .

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,140 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jana Grill <janagrill@google.com>
Date: Tue, 20 Apr 2021 18:23:33 +0000
Subject: M86-LTS: DevTools: expect PageHandler may be destroyed during
Page.navigate
(cherry picked from commit ff5e70191ec701cce4f84aaa25cd676376253a8a)
Bug: 1188889
Change-Id: I5c2fcca84834d66c46d77a70683212c2330177a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2787756
Commit-Queue: Andrey Kosyakov <caseq@chromium.org>
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
Reviewed-by: Karan Bhatia <karandeepb@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#867507}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2821536
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1618}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/chrome/browser/extensions/api/debugger/debugger_apitest.cc b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
index 71ce5a3399db29451e990d530736460aa28eeec0..b35accc8ce46f3465624898fe18d463529498d07 100644
--- a/chrome/browser/extensions/api/debugger/debugger_apitest.cc
+++ b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
@@ -24,6 +24,7 @@
#include "components/sessions/content/session_tab_helper.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/no_renderer_crashes_assertion.h"
#include "extensions/browser/extension_function.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
@@ -353,6 +354,19 @@ IN_PROC_BROWSER_TEST_F(DebuggerExtensionApiTest,
<< message_;
}
+// Tests that navigation to a forbidden URL is properly denied and
+// does not cause a crash.
+// This is a regression test for https://crbug.com/1188889.
+IN_PROC_BROWSER_TEST_F(DebuggerExtensionApiTest, DISABLED_NavigateToForbiddenUrl) {
+ content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
+ // We don't send a DevTools command callback before disconnecting the session,
+ // so the extension does not receive a callback either.
+ base::AutoReset<bool> ignore_did_respond(
+ &ExtensionFunction::ignore_all_did_respond_for_testing_do_not_use, true);
+ ASSERT_TRUE(RunExtensionTest("debugger_navigate_to_forbidden_url"))
+ << message_;
+}
+
class SitePerProcessDebuggerExtensionApiTest : public DebuggerExtensionApiTest {
public:
void SetUpCommandLine(base::CommandLine* command_line) override {
diff --git a/chrome/test/data/extensions/api_test/debugger_navigate_to_forbidden_url/background.js b/chrome/test/data/extensions/api_test/debugger_navigate_to_forbidden_url/background.js
new file mode 100644
index 0000000000000000000000000000000000000000..e2ef32fffd3e5d49e7dc10d53f8c891ddb0f3872
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/debugger_navigate_to_forbidden_url/background.js
@@ -0,0 +1,28 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+const protocolVersion = '1.3';
+const DETACHED_WHILE_HANDLING = 'Detached while handling command.';
+
+chrome.test.runTests([
+ async function testNavigateToForbiddenUrl() {
+ const {openTab} = await import('/_test_resources/test_util/tabs_util.js');
+ const tab = await openTab('about:blank');
+ const debuggee = {tabId: tab.id};
+ await new Promise(resolve =>
+ chrome.debugger.attach(debuggee, protocolVersion, resolve));
+ chrome.debugger.sendCommand(debuggee, 'Page.crash');
+ await new Promise(resolve =>
+ chrome.debugger.onEvent.addListener((source, method, params) => {
+ if (method === 'Inspector.targetCrashed')
+ resolve();
+ }));
+ const result = await new Promise(resolve =>
+ chrome.debugger.sendCommand(debuggee, 'Page.navigate', {
+ url: 'chrome://version'
+ }, resolve));
+ chrome.test.assertLastError(DETACHED_WHILE_HANDLING);
+ chrome.test.succeed();
+ }
+]);
diff --git a/chrome/test/data/extensions/api_test/debugger_navigate_to_forbidden_url/manifest.json b/chrome/test/data/extensions/api_test/debugger_navigate_to_forbidden_url/manifest.json
new file mode 100644
index 0000000000000000000000000000000000000000..05db294ed7f49893431b0039a5f338d20e08f27d
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/debugger_navigate_to_forbidden_url/manifest.json
@@ -0,0 +1,11 @@
+{
+ "name": "Debugger API test for CDP-initiated navigation to forbidden URLs",
+ "version": "1.0",
+ "manifest_version": 2,
+ "background": {
+ "scripts": ["background.js"]
+ },
+ "permissions": [
+ "debugger"
+ ]
+}
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc
index 630de0dd016fd3d054bcd40b22d75a242eeaa23e..a340d3e4519ada9edba279090ea11b57521ef0f4 100644
--- a/content/browser/devtools/protocol/page_handler.cc
+++ b/content/browser/devtools/protocol/page_handler.cc
@@ -496,7 +496,12 @@ void PageHandler::Navigate(const std::string& url,
params.referrer = Referrer(GURL(referrer.fromMaybe("")), policy);
params.transition_type = type;
params.frame_tree_node_id = frame_tree_node->frame_tree_node_id();
+ // Handler may be destroyed while navigating if the session
+ // gets disconnected as a result of access checks.
+ base::WeakPtr<PageHandler> weak_self = weak_factory_.GetWeakPtr();
frame_tree_node->navigator().GetController()->LoadURLWithParams(params);
+ if (!weak_self)
+ return;
base::UnguessableToken frame_token = frame_tree_node->devtools_frame_token();
auto navigate_callback = navigate_callbacks_.find(frame_token);
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index 52fdd0f1066699cc019c33de2517c23f12b4a616..8795c547717b206f4e459f655f6e62a7ba9229e0 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -472,8 +472,11 @@ void RenderFrameDevToolsAgentHost::UpdateFrameHost(
if (!ShouldAllowSession(session))
restricted_sessions.push_back(session);
}
- if (!restricted_sessions.empty())
+ scoped_refptr<RenderFrameDevToolsAgentHost> protect;
+ if (!restricted_sessions.empty()) {
+ protect = this;
ForceDetachRestrictedSessions(restricted_sessions);
+ }
UpdateFrameAlive();
}

View File

@@ -0,0 +1,291 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Wed, 31 Mar 2021 18:44:06 +0000
Subject: Don't use BigBuffer for IPC::Message transport
M86 merge conflicts and resolution:
* ipc/ipc_message_pipe_reader.cc
Fixed extra include.
(cherry picked from commit 85bd7c88523545ab0e497d5e7b3e929793813358)
(cherry picked from commit fad3b9ffe7c7ff82909d911c573bd185aa3b3b50)
Fixed: 1184399
Change-Id: Iddd91ae8d7ae63022b61c96239f5e39261dfb735
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2737012
Commit-Queue: Ken Rockot <rockot@google.com>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#860010}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2779918
Auto-Submit: Ken Rockot <rockot@google.com>
Reviewed-by: Adrian Taylor <adetaylor@chromium.org>
Reviewed-by: Alex Gough <ajgo@chromium.org>
Commit-Queue: Alex Gough <ajgo@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4389@{#1597}
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2794488
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Reviewed-by: Artem Sumaneev <asumaneev@google.com>
Reviewed-by: Ken Rockot <rockot@google.com>
Auto-Submit: Artem Sumaneev <asumaneev@google.com>
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1587}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/ipc/BUILD.gn b/ipc/BUILD.gn
index 994d45e84502670f544742a3011a8f9381a711bc..281e84df83ae73e8c4716fda1624cb4065342c76 100644
--- a/ipc/BUILD.gn
+++ b/ipc/BUILD.gn
@@ -187,10 +187,7 @@ mojom_component("mojom") {
output_prefix = "ipc_mojom"
macro_prefix = "IPC_MOJOM"
sources = [ "ipc.mojom" ]
- public_deps = [
- "//mojo/public/interfaces/bindings",
- "//mojo/public/mojom/base",
- ]
+ public_deps = [ "//mojo/public/interfaces/bindings" ]
cpp_typemaps = [
{
@@ -207,10 +204,7 @@ mojom_component("mojom") {
"//ipc/message_view.cc",
"//ipc/message_view.h",
]
- traits_public_deps = [
- "//ipc:message_support",
- "//mojo/public/cpp/base:shared_typemap_traits",
- ]
+ traits_public_deps = [ "//ipc:message_support" ]
},
]
diff --git a/ipc/ipc.mojom b/ipc/ipc.mojom
index c66799642fbee2cef3449ff5d52cd5f187808cfe..4606022b28bca1df06ba6eb8eaac025573475b10 100644
--- a/ipc/ipc.mojom
+++ b/ipc/ipc.mojom
@@ -4,7 +4,6 @@
module IPC.mojom;
-import "mojo/public/mojom/base/big_buffer.mojom";
import "mojo/public/interfaces/bindings/native_struct.mojom";
// A placeholder interface type since we don't yet support generic associated
@@ -14,7 +13,7 @@ interface GenericInterface {};
// Typemapped such that arbitrarily large IPC::Message objects can be sent and
// received with minimal copying.
struct Message {
- mojo_base.mojom.BigBuffer buffer;
+ array<uint8> bytes;
array<mojo.native.SerializedHandle>? handles;
};
@@ -24,6 +23,7 @@ interface Channel {
SetPeerPid(int32 pid);
// Transmits a classical Chrome IPC message.
+ [UnlimitedSize]
Receive(Message message);
// Requests a Channel-associated interface.
diff --git a/ipc/ipc_message_pipe_reader.cc b/ipc/ipc_message_pipe_reader.cc
index bdc5dd680d0f9107719765334d0a1ea3e864e200..cbf0363a9d941db1ab34ae835e707b7825447659 100644
--- a/ipc/ipc_message_pipe_reader.cc
+++ b/ipc/ipc_message_pipe_reader.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/containers/span.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
@@ -62,7 +63,9 @@ bool MessagePipeReader::Send(std::unique_ptr<Message> message) {
if (!sender_)
return false;
- sender_->Receive(MessageView(*message, std::move(handles)));
+ base::span<const uint8_t> bytes(static_cast<const uint8_t*>(message->data()),
+ message->size());
+ sender_->Receive(MessageView(bytes, std::move(handles)));
DVLOG(4) << "Send " << message->type() << ": " << message->size();
return true;
}
@@ -82,11 +85,12 @@ void MessagePipeReader::SetPeerPid(int32_t peer_pid) {
}
void MessagePipeReader::Receive(MessageView message_view) {
- if (!message_view.size()) {
+ if (message_view.bytes().empty()) {
delegate_->OnBrokenDataReceived();
return;
}
- Message message(message_view.data(), message_view.size());
+ Message message(reinterpret_cast<const char*>(message_view.bytes().data()),
+ message_view.bytes().size());
if (!message.IsValid()) {
delegate_->OnBrokenDataReceived();
return;
diff --git a/ipc/ipc_mojo_bootstrap_unittest.cc b/ipc/ipc_mojo_bootstrap_unittest.cc
index 47a7ad79a30165c76041075be10b9be8c13f5e75..b32941da752a54ba7317e439150982adbb9fbcad 100644
--- a/ipc/ipc_mojo_bootstrap_unittest.cc
+++ b/ipc/ipc_mojo_bootstrap_unittest.cc
@@ -77,7 +77,9 @@ class PeerPidReceiver : public IPC::mojom::Channel {
ASSERT_NE(MessageExpectation::kNotExpected, message_expectation_);
received_message_ = true;
- IPC::Message message(message_view.data(), message_view.size());
+ IPC::Message message(
+ reinterpret_cast<const char*>(message_view.bytes().data()),
+ message_view.bytes().size());
bool expected_valid =
message_expectation_ == MessageExpectation::kExpectedValid;
EXPECT_EQ(expected_valid, message.IsValid());
@@ -196,8 +198,7 @@ MULTIPROCESS_TEST_MAIN_WITH_SETUP(
uint8_t data = 0;
sender->Receive(
- IPC::MessageView(mojo_base::BigBufferView(base::make_span(&data, 0)),
- base::nullopt /* handles */));
+ IPC::MessageView(base::make_span(&data, 0), base::nullopt /* handles */));
base::RunLoop run_loop;
PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure());
diff --git a/ipc/message_mojom_traits.cc b/ipc/message_mojom_traits.cc
index 4aab9248e9ff6ca8e2d7d085ae3e996ac04666e8..d8ad4a2f919b01362e3e2746bfb7f4fae77b059d 100644
--- a/ipc/message_mojom_traits.cc
+++ b/ipc/message_mojom_traits.cc
@@ -4,15 +4,13 @@
#include "ipc/message_mojom_traits.h"
-#include "mojo/public/cpp/base/big_buffer_mojom_traits.h"
-
namespace mojo {
// static
-mojo_base::BigBufferView
-StructTraits<IPC::mojom::MessageDataView, IPC::MessageView>::buffer(
+base::span<const uint8_t>
+StructTraits<IPC::mojom::MessageDataView, IPC::MessageView>::bytes(
IPC::MessageView& view) {
- return view.TakeBufferView();
+ return view.bytes();
}
// static
@@ -26,14 +24,14 @@ StructTraits<IPC::mojom::MessageDataView, IPC::MessageView>::handles(
bool StructTraits<IPC::mojom::MessageDataView, IPC::MessageView>::Read(
IPC::mojom::MessageDataView data,
IPC::MessageView* out) {
- mojo_base::BigBufferView buffer_view;
- if (!data.ReadBuffer(&buffer_view))
- return false;
+ mojo::ArrayDataView<uint8_t> bytes;
+ data.GetBytesDataView(&bytes);
+
base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles;
if (!data.ReadHandles(&handles))
return false;
- *out = IPC::MessageView(std::move(buffer_view), std::move(handles));
+ *out = IPC::MessageView(bytes, std::move(handles));
return true;
}
diff --git a/ipc/message_mojom_traits.h b/ipc/message_mojom_traits.h
index 617ffbe37309946464e3f180a0ebde97f56dbd75..6b5064a12191e9a663519e7b5cb7c5f907a75054 100644
--- a/ipc/message_mojom_traits.h
+++ b/ipc/message_mojom_traits.h
@@ -7,10 +7,10 @@
#include <vector>
+#include "base/containers/span.h"
#include "base/optional.h"
#include "ipc/ipc.mojom-shared.h"
#include "ipc/message_view.h"
-#include "mojo/public/cpp/base/big_buffer.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "mojo/public/interfaces/bindings/native_struct.mojom.h"
@@ -19,7 +19,7 @@ namespace mojo {
template <>
class StructTraits<IPC::mojom::MessageDataView, IPC::MessageView> {
public:
- static mojo_base::BigBufferView buffer(IPC::MessageView& view);
+ static base::span<const uint8_t> bytes(IPC::MessageView& view);
static base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles(
IPC::MessageView& view);
diff --git a/ipc/message_view.cc b/ipc/message_view.cc
index 49a80878e7a92cda13105ea0f2fea36ad7ed05e6..39c6608dd507c3ca051b619d966ae521e95fe8e2 100644
--- a/ipc/message_view.cc
+++ b/ipc/message_view.cc
@@ -11,16 +11,9 @@ namespace IPC {
MessageView::MessageView() = default;
MessageView::MessageView(
- const Message& message,
+ base::span<const uint8_t> bytes,
base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles)
- : buffer_view_(base::make_span(static_cast<const uint8_t*>(message.data()),
- message.size())),
- handles_(std::move(handles)) {}
-
-MessageView::MessageView(
- mojo_base::BigBufferView buffer_view,
- base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles)
- : buffer_view_(std::move(buffer_view)), handles_(std::move(handles)) {}
+ : bytes_(bytes), handles_(std::move(handles)) {}
MessageView::MessageView(MessageView&&) = default;
diff --git a/ipc/message_view.h b/ipc/message_view.h
index 4ec059bf3639b9c75178f2300d0796b433e1d2ed..c7801bb963f06b03c51ba87bffc307792b592dae 100644
--- a/ipc/message_view.h
+++ b/ipc/message_view.h
@@ -11,7 +11,6 @@
#include "base/containers/span.h"
#include "base/macros.h"
#include "ipc/ipc_message.h"
-#include "mojo/public/cpp/base/big_buffer.h"
#include "mojo/public/interfaces/bindings/native_struct.mojom-forward.h"
namespace IPC {
@@ -20,30 +19,18 @@ class COMPONENT_EXPORT(IPC_MOJOM) MessageView {
public:
MessageView();
MessageView(
- const Message& message,
- base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles);
- MessageView(
- mojo_base::BigBufferView buffer_view,
+ base::span<const uint8_t> bytes,
base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles);
MessageView(MessageView&&);
~MessageView();
MessageView& operator=(MessageView&&);
- const char* data() const {
- return reinterpret_cast<const char*>(buffer_view_.data().data());
- }
-
- uint32_t size() const {
- return static_cast<uint32_t>(buffer_view_.data().size());
- }
-
- mojo_base::BigBufferView TakeBufferView() { return std::move(buffer_view_); }
-
+ base::span<const uint8_t> bytes() const { return bytes_; }
base::Optional<std::vector<mojo::native::SerializedHandlePtr>> TakeHandles();
private:
- mojo_base::BigBufferView buffer_view_;
+ base::span<const uint8_t> bytes_;
base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles_;
DISALLOW_COPY_AND_ASSIGN(MessageView);

View File

@@ -0,0 +1,447 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: David Van Cleve <davidvc@chromium.org>
Date: Thu, 4 Mar 2021 16:50:46 +0000
Subject: css: Make fetches from inline CSS use the document's URL as referrer
Right now, fetches from inline CSS use the inline CSS's base URL
instead of the URL from the context that embeds the inline CSS: for
instance, loading a source-site.com page with the following code
<base href="https://other-site.com">
<style type=text/css> @import('best-sheet.com') </style>
should lead to the best-sheet.com sheet getting fetched with a
source-site.com referrer, but it will currently provide an
other-site.com referrer. However, if the imported sheet from
best-sheet.com makes more nested fetches, those nested requests should
use best-sheet.com as the basis for their referrers (as they do
currently).
This CL updates CSSParserContext's referrer setting logic to roughly do
the following:
- inline CSS: use the embedding document's URL as the referrer, or, for
srcdoc iframes, walk up the frame tree until hitting a non-srcdoc frame
- requests from fetched stylesheets: just as currently, use the fetched
sheet's URL as the basis for constructing the referrer
This seemed like it required refactoring CSSParserContext slightly
because there are constructors that take both a Document and a base URL,
and it's not obvious from the constructor signature whether the
Document or the base URL should be the one that provides the referrer.
To resolve this ambiguity, the refactor updates these CSSParserContext
constructors to take caller-provided Referrer objects.
(cherry picked from commit 0b1539fcb923056624d4adc84b88140d367d92da)
Change-Id: If5a99d8057dff5e771e821d0e1f605566e28ff1d
Fixed: 1158645, 1158010
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2592447
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Reviewed-by: Matt Falkenhagen <falken@chromium.org>
Commit-Queue: David Van Cleve <davidvc@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#841509}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2731576
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Victor-Gabriel Savu <vsavu@google.com>
Cr-Commit-Position: refs/branch-heads/4240@{#1558}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.cc b/third_party/blink/renderer/core/css/css_style_sheet.cc
index c168b0a244865e3c390989e3e5af275fdef2a4cd..10efc5bd894c16de745b7f4bb07268719f443e73 100644
--- a/third_party/blink/renderer/core/css/css_style_sheet.cc
+++ b/third_party/blink/renderer/core/css/css_style_sheet.cc
@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/html/html_link_element.h"
#include "third_party/blink/renderer/core/html/html_style_element.h"
#include "third_party/blink/renderer/core/html_names.h"
@@ -138,9 +139,15 @@ CSSStyleSheet* CSSStyleSheet::CreateInline(Node& owner_node,
const KURL& base_url,
const TextPosition& start_position,
const WTF::TextEncoding& encoding) {
+ Document& owner_node_document = owner_node.GetDocument();
auto* parser_context = MakeGarbageCollected<CSSParserContext>(
- owner_node.GetDocument(), owner_node.GetDocument().BaseURL(),
- true /* origin_clean */, owner_node.GetDocument().GetReferrerPolicy(),
+ owner_node_document, owner_node_document.BaseURL(),
+ true /* origin_clean */,
+ Referrer(
+ owner_node_document.GetExecutionContext()
+ ? owner_node_document.GetExecutionContext()->OutgoingReferrer()
+ : String(), // GetExecutionContext() only returns null in tests.
+ owner_node.GetDocument().GetReferrerPolicy()),
encoding);
if (AdTracker::IsAdScriptExecutingInDocument(&owner_node.GetDocument()))
parser_context->SetIsAdRelated();
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_context.cc b/third_party/blink/renderer/core/css/parser/css_parser_context.cc
index 5c1292cf13b4265c3db36fd3c1a71a30b3c81c68..b636bd5388a871fd284a74b7926aeb5922e274e5 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_context.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser_context.cc
@@ -53,27 +53,25 @@ CSSParserContext::CSSParserContext(const CSSParserContext* other,
is_ad_related_ = other->is_ad_related_;
}
-CSSParserContext::CSSParserContext(
- const CSSParserContext* other,
- const KURL& base_url,
- bool origin_clean,
- network::mojom::ReferrerPolicy referrer_policy,
- const WTF::TextEncoding& charset,
- const Document* use_counter_document)
- : CSSParserContext(
- base_url,
- origin_clean,
- charset,
- other->mode_,
- other->match_mode_,
- other->profile_,
- Referrer(base_url.StrippedForUseAsReferrer(), referrer_policy),
- other->is_html_document_,
- other->use_legacy_background_size_shorthand_behavior_,
- other->secure_context_mode_,
- other->should_check_content_security_policy_,
- use_counter_document,
- other->resource_fetch_restriction_) {
+CSSParserContext::CSSParserContext(const CSSParserContext* other,
+ const KURL& base_url,
+ bool origin_clean,
+ const Referrer& referrer,
+ const WTF::TextEncoding& charset,
+ const Document* use_counter_document)
+ : CSSParserContext(base_url,
+ origin_clean,
+ charset,
+ other->mode_,
+ other->match_mode_,
+ other->profile_,
+ referrer,
+ other->is_html_document_,
+ other->use_legacy_background_size_shorthand_behavior_,
+ other->secure_context_mode_,
+ other->should_check_content_security_policy_,
+ use_counter_document,
+ other->resource_fetch_restriction_) {
is_ad_related_ = other->is_ad_related_;
}
@@ -96,18 +94,23 @@ CSSParserContext::CSSParserContext(CSSParserMode mode,
ResourceFetchRestriction::kNone) {}
CSSParserContext::CSSParserContext(const Document& document)
- : CSSParserContext(document,
- document.BaseURL(),
- true /* origin_clean */,
- document.GetReferrerPolicy(),
- WTF::TextEncoding(),
- kLiveProfile) {}
+ : CSSParserContext(
+ document,
+ document.BaseURL(),
+ true /* origin_clean */,
+ Referrer(document.GetExecutionContext()
+ ? document.GetExecutionContext()->OutgoingReferrer()
+ : String(), // GetExecutionContext() only returns null
+ // in tests.
+ document.GetReferrerPolicy()),
+ WTF::TextEncoding(),
+ kLiveProfile) {}
CSSParserContext::CSSParserContext(
const Document& document,
const KURL& base_url_override,
bool origin_clean,
- network::mojom::ReferrerPolicy referrer_policy_override,
+ const Referrer& referrer,
const WTF::TextEncoding& charset,
SelectorProfile profile,
enum ResourceFetchRestriction resource_fetch_restriction)
@@ -122,8 +125,7 @@ CSSParserContext::CSSParserContext(
: kHTMLStandardMode)
: document.InQuirksMode() ? kHTMLQuirksMode : kHTMLStandardMode,
profile,
- Referrer(base_url_override.StrippedForUseAsReferrer(),
- referrer_policy_override),
+ referrer,
IsA<HTMLDocument>(document),
document.GetSettings()
? document.GetSettings()
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_context.h b/third_party/blink/renderer/core/css/parser/css_parser_context.h
index 33b458f21910bcbfdb6956b02cd2ef56bb39778b..8d7ec9e6b7a14fffaaf72dcd0d2c0d0f062dbbfa 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_context.h
+++ b/third_party/blink/renderer/core/css/parser/css_parser_context.h
@@ -40,10 +40,15 @@ class CORE_EXPORT CSSParserContext final
explicit CSSParserContext(const CSSParserContext* other,
const Document* use_counter_document = nullptr);
+ // Creates a context with most of its constructor attributes provided by
+ // copying from |other|, except that the remaining constructor arguments take
+ // precedence over the corresponding characteristics of |other|. This is
+ // useful for initializing @imported sheets' contexts, which inherit most of
+ // their characteristics from their parents.
CSSParserContext(const CSSParserContext* other,
const KURL& base_url_override,
bool origin_clean,
- network::mojom::ReferrerPolicy referrer_policy_override,
+ const Referrer& referrer,
const WTF::TextEncoding& charset_override,
const Document* use_counter_document);
CSSParserContext(CSSParserMode,
@@ -54,7 +59,7 @@ class CORE_EXPORT CSSParserContext final
CSSParserContext(const Document&,
const KURL& base_url_override,
bool origin_clean,
- network::mojom::ReferrerPolicy referrer_policy_override,
+ const Referrer& referrer,
const WTF::TextEncoding& charset = WTF::TextEncoding(),
SelectorProfile = kLiveProfile,
ResourceFetchRestriction resource_fetch_restriction =
@@ -69,7 +74,7 @@ class CORE_EXPORT CSSParserContext final
CSSParserMode,
CSSParserMode match_mode,
SelectorProfile,
- const Referrer&,
+ const Referrer& referrer,
bool is_html_document,
bool use_legacy_background_size_shorthand_behavior,
SecureContextMode,
diff --git a/third_party/blink/renderer/core/css/selector_query.cc b/third_party/blink/renderer/core/css/selector_query.cc
index 722b751f19207b070664d79c5a9cc758f1c044f4..35d9d926f2e1ac0c2d032817b87c1079af9408ec 100644
--- a/third_party/blink/renderer/core/css/selector_query.cc
+++ b/third_party/blink/renderer/core/css/selector_query.cc
@@ -535,9 +535,8 @@ SelectorQuery* SelectorQueryCache::Add(const AtomicString& selectors,
CSSSelectorList selector_list = CSSParser::ParseSelector(
MakeGarbageCollected<CSSParserContext>(
- document, document.BaseURL(), true /* origin_clean */,
- document.GetReferrerPolicy(), WTF::TextEncoding(),
- CSSParserContext::kSnapshotProfile),
+ document, document.BaseURL(), true /* origin_clean */, Referrer(),
+ WTF::TextEncoding(), CSSParserContext::kSnapshotProfile),
nullptr, selectors);
if (!selector_list.First()) {
diff --git a/third_party/blink/renderer/core/css/selector_query_test.cc b/third_party/blink/renderer/core/css/selector_query_test.cc
index 8d701d91372e5c2fb4b1a30f190f629f95e1b0b2..bf14850baf8dd2e92f74b89b78963a367440a704 100644
--- a/third_party/blink/renderer/core/css/selector_query_test.cc
+++ b/third_party/blink/renderer/core/css/selector_query_test.cc
@@ -72,9 +72,8 @@ TEST(SelectorQueryTest, NotMatchingPseudoElement) {
CSSSelectorList selector_list = CSSParser::ParseSelector(
MakeGarbageCollected<CSSParserContext>(
- *document, NullURL(), true /* origin_clean */,
- network::mojom::ReferrerPolicy::kDefault, WTF::TextEncoding(),
- CSSParserContext::kSnapshotProfile),
+ *document, NullURL(), true /* origin_clean */, Referrer(),
+ WTF::TextEncoding(), CSSParserContext::kSnapshotProfile),
nullptr, "span::before");
std::unique_ptr<SelectorQuery> query =
SelectorQuery::Adopt(std::move(selector_list));
@@ -83,9 +82,8 @@ TEST(SelectorQueryTest, NotMatchingPseudoElement) {
selector_list = CSSParser::ParseSelector(
MakeGarbageCollected<CSSParserContext>(
- *document, NullURL(), true /* origin_clean */,
- network::mojom::ReferrerPolicy::kDefault, WTF::TextEncoding(),
- CSSParserContext::kSnapshotProfile),
+ *document, NullURL(), true /* origin_clean */, Referrer(),
+ WTF::TextEncoding(), CSSParserContext::kSnapshotProfile),
nullptr, "span");
query = SelectorQuery::Adopt(std::move(selector_list));
elm = query->QueryFirst(*document);
@@ -103,9 +101,8 @@ TEST(SelectorQueryTest, LastOfTypeNotFinishedParsing) {
CSSSelectorList selector_list = CSSParser::ParseSelector(
MakeGarbageCollected<CSSParserContext>(
- *document, NullURL(), true /* origin_clean */,
- network::mojom::ReferrerPolicy::kDefault, WTF::TextEncoding(),
- CSSParserContext::kSnapshotProfile),
+ *document, NullURL(), true /* origin_clean */, Referrer(),
+ WTF::TextEncoding(), CSSParserContext::kSnapshotProfile),
nullptr, "p:last-of-type");
std::unique_ptr<SelectorQuery> query =
SelectorQuery::Adopt(std::move(selector_list));
diff --git a/third_party/blink/renderer/core/css/style_rule_import.cc b/third_party/blink/renderer/core/css/style_rule_import.cc
index 447d130a9c29a698c81c0436b318058172b3a7ef..857fb15c74063613d467c29829eda0a8ea18b9bb 100644
--- a/third_party/blink/renderer/core/css/style_rule_import.cc
+++ b/third_party/blink/renderer/core/css/style_rule_import.cc
@@ -83,8 +83,9 @@ void StyleRuleImport::NotifyFinished(Resource* resource) {
CSSParserContext* context = MakeGarbageCollected<CSSParserContext>(
parent_context, cached_style_sheet->GetResponse().ResponseUrl(),
cached_style_sheet->GetResponse().IsCorsSameOrigin(),
- cached_style_sheet->GetReferrerPolicy(), cached_style_sheet->Encoding(),
- document);
+ Referrer(cached_style_sheet->GetResponse().ResponseUrl(),
+ cached_style_sheet->GetReferrerPolicy()),
+ cached_style_sheet->Encoding(), document);
if (cached_style_sheet->GetResourceRequest().IsAdResource())
context->SetIsAdRelated();
diff --git a/third_party/blink/renderer/core/dom/processing_instruction.cc b/third_party/blink/renderer/core/dom/processing_instruction.cc
index 739226d95f964ebf4ae35983c6e1cd5faa01b324..1a1ead65c7642350f7d13364046f665c021bc3b0 100644
--- a/third_party/blink/renderer/core/dom/processing_instruction.cc
+++ b/third_party/blink/renderer/core/dom/processing_instruction.cc
@@ -206,7 +206,9 @@ void ProcessingInstruction::NotifyFinished(Resource* resource) {
auto* parser_context = MakeGarbageCollected<CSSParserContext>(
GetDocument(), style_resource->GetResponse().ResponseUrl(),
style_resource->GetResponse().IsCorsSameOrigin(),
- style_resource->GetReferrerPolicy(), style_resource->Encoding());
+ Referrer(style_resource->GetResponse().ResponseUrl(),
+ style_resource->GetReferrerPolicy()),
+ style_resource->Encoding());
if (style_resource->GetResourceRequest().IsAdResource())
parser_context->SetIsAdRelated();
diff --git a/third_party/blink/renderer/core/html/link_style.cc b/third_party/blink/renderer/core/html/link_style.cc
index 5036ac1f0cb9613772c704a6dc5c5e2496ab5567..5e3b7e361ae1ebe2ff89f10448eac4fe33352031 100644
--- a/third_party/blink/renderer/core/html/link_style.cc
+++ b/third_party/blink/renderer/core/html/link_style.cc
@@ -88,7 +88,9 @@ void LinkStyle::NotifyFinished(Resource* resource) {
auto* parser_context = MakeGarbageCollected<CSSParserContext>(
GetDocument(), cached_style_sheet->GetResponse().ResponseUrl(),
cached_style_sheet->GetResponse().IsCorsSameOrigin(),
- cached_style_sheet->GetReferrerPolicy(), cached_style_sheet->Encoding());
+ Referrer(cached_style_sheet->GetResponse().ResponseUrl(),
+ cached_style_sheet->GetReferrerPolicy()),
+ cached_style_sheet->Encoding());
if (cached_style_sheet->GetResourceRequest().IsAdResource()) {
parser_context->SetIsAdRelated();
}
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
index 0b6e9b6b8b66029f46ca79f24a2519f13e611005..e492003c470af4c7b96551f6dfee79d26f8b7c77 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc
@@ -244,9 +244,8 @@ VTTParser::ParseState VTTParser::CollectRegionSettings(const String& line) {
VTTParser::ParseState VTTParser::CollectStyleSheet(const String& line) {
if (line.IsEmpty() || line.Contains("-->")) {
auto* parser_context = MakeGarbageCollected<CSSParserContext>(
- *document_, NullURL(), true /* origin_clean */,
- document_->GetReferrerPolicy(), UTF8Encoding(),
- CSSParserContext::kLiveProfile,
+ *document_, NullURL(), true /* origin_clean */, Referrer(),
+ UTF8Encoding(), CSSParserContext::kLiveProfile,
ResourceFetchRestriction::kOnlyDataUrls);
auto* style_sheet_contents =
MakeGarbageCollected<StyleSheetContents>(parser_context);
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index acf5033054cecc1099068e2452cfbef8f1ffbd95..0e9ac683c48befe5f3e740e0632bf93e7569c686 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3245,6 +3245,7 @@ virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-restartIce-onneg
# See also crbug.com/920100 (sheriff 2019-01-09).
crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout Failure ]
crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout Failure ]
+crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/inline-style-with-differentorigin-base-tag.tentative.html [ Timeout Failure ]
crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout Failure ]
crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout Failure ]
crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/processing-instruction.html [ Timeout Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/referrer-policy/css-integration/image/inline-style-with-differentorigin-base-tag.tentative.html b/third_party/blink/web_tests/external/wpt/referrer-policy/css-integration/image/inline-style-with-differentorigin-base-tag.tentative.html
new file mode 100644
index 0000000000000000000000000000000000000000..091afd832ab35a76136b4242df1c1ec73aee109d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/referrer-policy/css-integration/image/inline-style-with-differentorigin-base-tag.tentative.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<title>CSS integration - image from inline style from document with base tag</title>
+<link rel="help" href="https://crbug.com/1158645" />
+
+<head>
+ <meta name="referrer" content="origin">
+</head>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<!-- Common global functions for referrer-policy tests. -->
+<script src="/common/security-features/resources/common.sub.js"></script>
+
+<!-- This has to follow the <script> tags, or it will make the js files fail to load. -->
+<base href="http://other-site.example" />
+
+<p>Check that resources from inline styles are loaded with
+ the referrer and referrer policy from the document and, in
+ particular, not with the different base URL set in the base tag.</p>
+
+<div class="styled"></div>
+
+<script>
+ 'use strict';
+ promise_test(function(css_test) {
+ var id = token();
+ var css_url = location.protocol + "//www1." + location.hostname + ":" + location.port + "/common/security-features/subresource/image.py" + "?id=" + id;
+ var img_url = css_url + "&report-headers";
+
+ var div = document.querySelector("div.styled");
+ div.style = "content:url(" + css_url + ")";
+ return timeoutPromise(css_test, 1000)
+ .then(() => requestViaXhr(img_url))
+ .then(function(message) {
+ assert_own_property(message, "headers");
+ assert_own_property(message, "referrer");
+ assert_equals(message.referrer, location.origin + "/");
+ });
+ }, "Image from inline styles.");
+</script>
+
+<div id="log"></div>
+
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/referrer-policy/css-integration/svg/inline-style-with-differentorigin-base-tag.tentative.html b/third_party/blink/web_tests/external/wpt/referrer-policy/css-integration/svg/inline-style-with-differentorigin-base-tag.tentative.html
new file mode 100644
index 0000000000000000000000000000000000000000..9a8bc6da418bc7302138daba8cf06cb449bd2dfe
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/referrer-policy/css-integration/svg/inline-style-with-differentorigin-base-tag.tentative.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>CSS integration - styling SVG from inline style on page with different-origin base tag</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/utils.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ <!-- Helper functions for referrer-policy css tests. -->
+ <script src="/referrer-policy/css-integration/css-test-helper.js"></script>
+ <meta name="referrer" content="origin">
+</head>
+
+<base href="http://other-page.example/" />
+
+<body>
+ <p>Check that resources from inline styles are loaded with
+ the referrer and referrer policy from the document and, in
+ particular, not from the document's overridden base URL.</p>
+ <script>
+ function setInlineStyle(test) {
+ test.expected = location.origin + "/";
+ let svg = createSvg();
+ document.body.appendChild(svg);
+ let element = svg.getElementsByTagName('path')[0];
+ element.style = test.property + ": url(" + url_prefix + "svg.py?id=" +
+ test.id + "#invalidFragment);";
+ }
+
+ runSvgTests(svg_test_properties,
+ "Styling SVG from inline styles",
+ setInlineStyle);
+ </script>
+
+ <div id="log"></div>
+</body>
+
+</html>
diff --git a/third_party/blink/web_tests/http/tests/css/resources/referrer-check.php b/third_party/blink/web_tests/http/tests/css/resources/referrer-check.php
index 69483e01544c842f56a51d00d1b2ee5dc24b4162..7a517de692f418c3c8b365d0f7aefb9e585c9da0 100644
--- a/third_party/blink/web_tests/http/tests/css/resources/referrer-check.php
+++ b/third_party/blink/web_tests/http/tests/css/resources/referrer-check.php
@@ -31,7 +31,7 @@ $expectedReferrerPaths = array(
"document" => "/css/css-resources-referrer.html",
"sheet" => "/css/resources/css-resources-referrer.css",
"importedSheet" => "/css/resources/css-resources-referrer-import.css",
- "iframe" => "/from/iframe.html"
+ "iframe" => "/css/css-resources-referrer-srcdoc.html"
);
$from = $_GET["from"];

View File

@@ -0,0 +1,73 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kai Ninomiya <kainino@chromium.org>
Date: Thu, 11 Feb 2021 02:24:04 +0000
Subject: Disable GPU acceleration on all Mesa software rasterizers
The previous entry only disabled acceleration on swrast, but softpipe
and llvmpipe shouldn't be used for "GPU" acceleration either.
This should apply to Linux but not ChromeOS, AFAICT.
This only improves an existing software rendering list entry, but here
is the rationale: We prefer to rely on our own (domain specific, so more
efficient) software paths, at least for everything other than WebGL. And
for WebGL, SwiftShader avoids unknown factors like
llvmpipe/softpipe/swrast.
If you are running a Mesa GL driver (not e.g. NVIDIA) then you can force
these configurations with:
- LIBGL_ALWAYS_SOFTWARE=1
https://docs.mesa3d.org/envvars.html#libgl-environment-variables:~:text=LIBGL_ALWAYS_SOFTWARE
- GALLIUM_DRIVER=llvmpipe, softpipe, or swr (though swr didn't work for me)
https://docs.mesa3d.org/envvars.html#gallium-environment-variables:~:text=GALLIUM_DRIVER
The GL_RENDERER strings are:
- swrast: "Software Rasterizer" (couldn't test this locally; found this online)
- softpipe: "softpipe" (on one machine)
- llvmpipe: "llvmpipe (LLVM 10.0.0, 256 bits)" (on one machine)
Drive-by updates the description of another item to be more accurate
(SVGA3D is virtualized over hardware; it's not a software renderer).
# Unrelated CQ failures on branch
(cherry picked from commit 7c7eccfc85e387a0dcd154a2a9c2389177982837)
No-Try: True
Bug: 1155974
Change-Id: I0571c1a1bf526260f7ea6cd53f88eec768973b13
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2645491
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Auto-Submit: Kai Ninomiya <kainino@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#846422}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2651183
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Cr-Commit-Position: refs/branch-heads/4324@{#2176}
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
diff --git a/gpu/config/software_rendering_list.json b/gpu/config/software_rendering_list.json
index 5b5c542dbc95e49f9f0e5330f99b94ab4ea72321..dd87f7c0cc928bd330ac156bce9391a36bca2db0 100644
--- a/gpu/config/software_rendering_list.json
+++ b/gpu/config/software_rendering_list.json
@@ -21,11 +21,11 @@
{
"id": 3,
"description": "GL driver is software rendered. GPU acceleration is disabled",
- "cr_bugs": [59302, 315217],
+ "cr_bugs": [59302, 315217, 1155974],
"os": {
"type": "linux"
},
- "gl_renderer": "(?i).*software.*",
+ "gl_renderer": "(?i).*(software|llvmpipe|softpipe).*",
"features": [
"all"
]
@@ -353,7 +353,7 @@
},
{
"id": 50,
- "description": "Disable VMware software renderer on older Mesa",
+ "description": "Disable VMware virtualized renderer on older Mesa",
"cr_bugs": [145531, 332596, 571899, 629434],
"os": {
"type": "linux"

View File

@@ -0,0 +1,72 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nathan Zabriskie <nazabris@microsoft.com>
Date: Fri, 5 Feb 2021 20:44:16 +0000
Subject: Fix heap overflow in VideoFrameYUVConverter
Currently with some texture sizes GLES2Util::ComputeImageDataSizesES3
will attempt to add row padding when calculating the size of a
VideoFrame plane. This is because it's currently assumed that each row
aligns on a 4 byte boundary based on GL_UNPACK_ALIGNMENT but
VideoFrames make no such guarantee as they may be densely packed.
This CL removes the GL_UNPACK_ALIGNMENT assumption so that we only use
the VideoFrame's stride when calculating padding.
(cherry picked from commit 7de5d0ecb5a4f73aeffe15d825bf694d0d8e2a08)
Bug: 1166504, 1161131
Change-Id: I2484f5dfd2ad85b088fee57758776a5c9bd01d95
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2642765
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Commit-Queue: Nathan Zabriskie <nazabris@microsoft.com>
Cr-Original-Commit-Position: refs/heads/master@{#846298}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2679121
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Nathan Zabriskie <nazabris@microsoft.com>
Cr-Commit-Position: refs/branch-heads/4324@{#2115}
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 49d050e7e0d8efabeb7cf1ed46041931394d43b4..4e5f869203d6b99b3368d3264830799d2d62006b 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -840,7 +840,9 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) {
case GL_GPU_DISJOINT_EXT:
*params = static_cast<GLint>(query_tracker_->CheckAndResetDisjoint());
return true;
-
+ case GL_UNPACK_ALIGNMENT:
+ *params = unpack_alignment_;
+ return true;
case GL_VIEWPORT:
if (state_.viewport_width > 0 && state_.viewport_height > 0 &&
capabilities_.max_viewport_width > 0 &&
@@ -922,7 +924,6 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) {
case GL_STENCIL_VALUE_MASK:
case GL_STENCIL_WRITEMASK:
case GL_SUBPIXEL_BITS:
- case GL_UNPACK_ALIGNMENT:
return false;
default:
break;
diff --git a/gpu/command_buffer/client/raster_implementation_gles.cc b/gpu/command_buffer/client/raster_implementation_gles.cc
index 299dd4f9874bf7f68563d524167db7180a200e14..f7d794ffbca21b055a9be91fa4b77be79896a730 100644
--- a/gpu/command_buffer/client/raster_implementation_gles.cc
+++ b/gpu/command_buffer/client/raster_implementation_gles.cc
@@ -178,6 +178,9 @@ void RasterImplementationGLES::WritePixels(const gpu::Mailbox& dest_mailbox,
BeginSharedImageAccessDirectCHROMIUM(
texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
+ GLint old_align = 0;
+ gl_->GetIntegerv(GL_UNPACK_ALIGNMENT, &old_align);
+ gl_->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
gl_->PixelStorei(GL_UNPACK_ROW_LENGTH, row_bytes / src_info.bytesPerPixel());
gl_->BindTexture(texture_target, texture_id);
gl_->TexSubImage2D(texture_target, 0, dst_x_offset, dst_y_offset,
@@ -186,6 +189,7 @@ void RasterImplementationGLES::WritePixels(const gpu::Mailbox& dest_mailbox,
SkColorTypeToGLDataType(src_info.colorType()), src_pixels);
gl_->BindTexture(texture_target, 0);
gl_->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ gl_->PixelStorei(GL_UNPACK_ALIGNMENT, old_align);
EndSharedImageAccessDirectCHROMIUM(texture_id);
DeleteGpuRasterTexture(texture_id);

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,109 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kent Tamura <tkent@chromium.org>
Date: Mon, 14 Dec 2020 17:37:14 +0000
Subject: LayoutNG: Fix an incorrect cache-hit for line boxes
If an IFC contains an item for an orthogonal writing-mode root,
NGFragmentItems::DirtyLinesFromNeedsLayout() failed to mark it as dirty
because NeedsLayout flag for the item was already cleared in the
ComputeMinMaxSizes() step.
This CL avoids this issue by assuming orthogonal writing-mode roots
dirty regardless of NeedsLayout flag.
(cherry picked from commit 21976a78429ccd8325acb00b41b4120271580bfb)
Bug: 1125870, 1147357
Change-Id: I603bdd76f9015fbcde46da8e09fb6757b4b0222b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2544326
Reviewed-by: Koji Ishii <kojii@chromium.org>
Commit-Queue: Kent Tamura <tkent@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#828237}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2584928
Reviewed-by: Kent Tamura <tkent@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1483}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index cdd49a53f8138572d746d87ba7116880eca850ef..b6915f3501150bc2d4fca79c21fb358d01f9f88e 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1235,6 +1235,7 @@ jumbo_source_set("unit_tests") {
"layout/ng/inline/ng_bidi_paragraph_test.cc",
"layout/ng/inline/ng_caret_position_test.cc",
"layout/ng/inline/ng_fragment_item_test.cc",
+ "layout/ng/inline/ng_fragment_items_test.cc",
"layout/ng/inline/ng_inline_cursor_test.cc",
"layout/ng/inline/ng_inline_fragment_traversal_test.cc",
"layout/ng/inline/ng_inline_items_builder_test.cc",
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
index cfe1900729d4dacc5dad8d94f39b8f80114f6104..de2bc38dc0fe41ef16340642a60208e327173fe2 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
@@ -249,9 +249,15 @@ void NGFragmentItems::DirtyLinesFromNeedsLayout(
// opportunities. Doing this complicates the logic, especially when culled
// inline is involved, and common case is to append to large IFC. Choose
// simpler logic and faster to check over more reuse opportunities.
+ const auto writing_mode = container->StyleRef().GetWritingMode();
for (LayoutObject* child = container->FirstChild(); child;
child = child->NextSibling()) {
- if (child->NeedsLayout()) {
+ // NeedsLayout is not helpful for an orthogonal writing-mode root because
+ // its NeedsLayout flag is cleared during the ComputeMinMaxSizes() step of
+ // the container.
+ if (child->NeedsLayout() ||
+ !IsParallelWritingMode(writing_mode,
+ child->StyleRef().GetWritingMode())) {
DirtyLinesFromChangedChild(child);
return;
}
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0a36ada712c0bbc9afe0edad70dfb68c5028d84e
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_test.cc
@@ -0,0 +1,43 @@
+// Copyright 2020 The Chromium 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 "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_layout_test.h"
+
+namespace blink {
+
+class NGFragmentItemsTest : public NGLayoutTest {};
+
+// crbug.com/1147357
+// DirtyLinesFromNeedsLayout() didn't work well with an orthogonal writing-mode
+// root as a child, and it caused a failure of OOF descendants propagation.
+TEST_F(NGFragmentItemsTest,
+ DirtyLinesFromNeedsLayoutWithOrthogonalWritingMode) {
+ SetBodyInnerHTML(R"HTML(
+<style>
+button {
+ font-size: 100px;
+}
+#span1 {
+ position: absolute;
+}
+code {
+ writing-mode: vertical-rl;
+}
+</style>
+<rt id="rt1"><span id="span1"></span></rt>
+<button>
+<code><ruby id="ruby1"></ruby></code>
+b AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+</button>)HTML");
+ RunDocumentLifecycle();
+
+ GetDocument().getElementById("ruby1")->appendChild(
+ GetDocument().getElementById("rt1"));
+ RunDocumentLifecycle();
+
+ EXPECT_TRUE(GetLayoutObjectByElementId("span1")->EverHadLayout());
+}
+
+} // namespace blink

View File

@@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lan Wei <lanwei@chromium.org>
Date: Tue, 20 Apr 2021 17:08:53 +0000
Subject: M86-LTS: Add null pointer check in RenderWidgetHostInputEventRouter
We have some crashes in RenderWidgetHostInputEventRouter class, we are
adding some null pointer check in this class to avoid the crash.
(cherry picked from commit 5f47666b79ac7ded20e1c7657037498561bd3352)
Bug: 1155297
Change-Id: I3b63d5748523ae2ce8ab469832adfc75d586e411
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2818680
Reviewed-by: Charlie Reis <creis@chromium.org>
Commit-Queue: Lan Wei <lanwei@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#871108}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2838329
Reviewed-by: Lan Wei <lanwei@chromium.org>
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1617}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
index f45da60a8f8cdeb6406e123554c05c4f399b0433..d88d28c2d4b09a00a9a42b59acad898d6516c158 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -1949,7 +1949,7 @@ void RenderWidgetHostInputEventRouter::OnAggregatedHitTestRegionListUpdated(
const std::vector<viz::AggregatedHitTestRegion>& hit_test_data) {
for (auto& region : hit_test_data) {
auto iter = owner_map_.find(region.frame_sink_id);
- if (iter != owner_map_.end())
+ if (iter != owner_map_.end() && iter->second)
iter->second->NotifyHitTestRegionUpdated(region);
}
}

View File

@@ -0,0 +1,168 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lan Wei <lanwei@chromium.org>
Date: Tue, 20 Apr 2021 16:32:33 +0000
Subject: M86-LTS: Add weak pointer to RWHIER::FrameSinkIdOwnerMap and
RWHIER::TargetMap
In RWHIER::FrameSinkIdOwnerMap and RWHIER::TargetMap, we change raw
pointer of RenderWidgetHostViewBase to weak pointer, such as
using FrameSinkIdOwnerMap = std::unordered_map<viz::FrameSinkId,
base::WeakPtr<RenderWidgetHostViewBase>,
viz::FrameSinkIdHash>;
using TargetMap = std::map<uint32_t,
base::WeakPtr<RenderWidgetHostViewBase>>;
This CL should fix the crash of stale pointer.
(cherry picked from commit 3e3e3cf7036d7e33a4d68b8416ae25730f9eee1d)
Bug: 1155297
Change-Id: I5b3270882ef06ae48c86bd460261723c7113953d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2792344
Reviewed-by: James MacLean <wjmaclean@chromium.org>
Reviewed-by: Aaron Colwell <acolwell@chromium.org>
Commit-Queue: Lan Wei <lanwei@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#870013}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2838587
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Auto-Submit: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Lan Wei <lanwei@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1616}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
index d88d28c2d4b09a00a9a42b59acad898d6516c158..0a19dfd63474bcc7da579bee850f92f642d525c7 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -345,7 +345,7 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
// Remove this view from the owner_map.
for (auto entry : owner_map_) {
- if (entry.second == view) {
+ if (entry.second.get() == view) {
owner_map_.erase(entry.first);
// There will only be one instance of a particular view in the map.
break;
@@ -368,7 +368,7 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
// replace it with nullptr so that we maintain the 1:1 correspondence between
// map entries and the touch sequences that underly them.
for (auto it : touchscreen_gesture_target_map_) {
- if (it.second == view)
+ if (it.second.get() == view)
it.second = nullptr;
}
@@ -417,8 +417,10 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
void RenderWidgetHostInputEventRouter::ClearAllObserverRegistrations() {
// Since we're shutting down, it's safe to call RenderWidgetHostViewBase::
// RemoveObserver() directly here.
- for (auto entry : owner_map_)
- entry.second->RemoveObserver(this);
+ for (auto entry : owner_map_) {
+ if (entry.second)
+ entry.second->RemoveObserver(this);
+ }
owner_map_.clear();
viz::HostFrameSinkManager* manager = GetHostFrameSinkManager();
if (manager)
@@ -840,7 +842,7 @@ void RenderWidgetHostInputEventRouter::DispatchTouchEvent(
touch_event.unique_touch_event_id) ==
touchscreen_gesture_target_map_.end());
touchscreen_gesture_target_map_[touch_event.unique_touch_event_id] =
- touch_target_;
+ touch_target_->GetWeakPtr();
} else if (touch_event.GetType() == blink::WebInputEvent::Type::kTouchStart) {
active_touches_ += CountChangedTouchPoints(touch_event);
}
@@ -1352,7 +1354,7 @@ void RenderWidgetHostInputEventRouter::AddFrameSinkIdOwner(
// We want to be notified if the owner is destroyed so we can remove it from
// our map.
owner->AddObserver(this);
- owner_map_.insert(std::make_pair(id, owner));
+ owner_map_.insert(std::make_pair(id, owner->GetWeakPtr()));
}
void RenderWidgetHostInputEventRouter::RemoveFrameSinkIdOwner(
@@ -1364,7 +1366,8 @@ void RenderWidgetHostInputEventRouter::RemoveFrameSinkIdOwner(
// stale values if the view destructs and isn't an observer anymore.
// Note: the view the iterator points at will be deleted in the following
// call, and shouldn't be used after this point.
- OnRenderWidgetHostViewBaseDestroyed(it_to_remove->second);
+ if (it_to_remove->second)
+ OnRenderWidgetHostViewBaseDestroyed(it_to_remove->second.get());
}
}
@@ -1415,7 +1418,7 @@ RenderWidgetHostInputEventRouter::FindTouchscreenGestureEventTarget(
bool RenderWidgetHostInputEventRouter::IsViewInMap(
const RenderWidgetHostViewBase* view) const {
DCHECK(!is_registered(view->GetFrameSinkId()) ||
- owner_map_.find(view->GetFrameSinkId())->second == view);
+ owner_map_.find(view->GetFrameSinkId())->second.get() == view);
return is_registered(view->GetFrameSinkId());
}
@@ -1552,7 +1555,7 @@ void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent(
target = result.view;
fallback_target_location = transformed_point;
} else if (is_gesture_start) {
- target = gesture_target_it->second;
+ target = gesture_target_it->second.get();
touchscreen_gesture_target_map_.erase(gesture_target_it);
// Abort any scroll bubbling in progress to avoid double entry.
@@ -1738,7 +1741,7 @@ RenderWidgetHostInputEventRouter::FindViewFromFrameSinkId(
// If the point hit a Surface whose namspace is no longer in the map, then
// it likely means the RenderWidgetHostView has been destroyed but its
// parent frame has not sent a new compositor frame since that happened.
- return iter == owner_map_.end() ? nullptr : iter->second;
+ return iter == owner_map_.end() ? nullptr : iter->second.get();
}
bool RenderWidgetHostInputEventRouter::ShouldContinueHitTesting(
@@ -1758,8 +1761,10 @@ bool RenderWidgetHostInputEventRouter::ShouldContinueHitTesting(
std::vector<RenderWidgetHostView*>
RenderWidgetHostInputEventRouter::GetRenderWidgetHostViewsForTests() const {
std::vector<RenderWidgetHostView*> hosts;
- for (auto entry : owner_map_)
- hosts.push_back(entry.second);
+ for (auto entry : owner_map_) {
+ DCHECK(entry.second);
+ hosts.push_back(entry.second.get());
+ }
return hosts;
}
@@ -1928,8 +1933,10 @@ void RenderWidgetHostInputEventRouter::SetCursor(const WebCursor& cursor) {
last_device_scale_factor_ =
last_mouse_move_root_view_->current_device_scale_factor();
if (auto* cursor_manager = last_mouse_move_root_view_->GetCursorManager()) {
- for (auto it : owner_map_)
- cursor_manager->UpdateCursor(it.second, cursor);
+ for (auto it : owner_map_) {
+ if (it.second)
+ cursor_manager->UpdateCursor(it.second.get(), cursor);
+ }
}
}
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.h b/content/browser/renderer_host/render_widget_host_input_event_router.h
index 42629b133b883865bebfa27f5d29eb5e2d153d0b..c4ce54a5a6beb509d6242ee0e5ebdf4c88f01251 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.h
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.h
@@ -195,10 +195,11 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
FRIEND_TEST_ALL_PREFIXES(BrowserSideFlingBrowserTest,
InertialGSUBubblingStopsWhenParentCannotScroll);
- using FrameSinkIdOwnerMap = std::unordered_map<viz::FrameSinkId,
- RenderWidgetHostViewBase*,
- viz::FrameSinkIdHash>;
- using TargetMap = std::map<uint32_t, RenderWidgetHostViewBase*>;
+ using FrameSinkIdOwnerMap =
+ std::unordered_map<viz::FrameSinkId,
+ base::WeakPtr<RenderWidgetHostViewBase>,
+ viz::FrameSinkIdHash>;
+ using TargetMap = std::map<uint32_t, base::WeakPtr<RenderWidgetHostViewBase>>;
void ClearAllObserverRegistrations();
RenderWidgetTargetResult FindViewAtLocation(

View File

@@ -0,0 +1,174 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chris Cunningham <chcunningham@chromium.org>
Date: Tue, 5 Jan 2021 21:23:21 +0000
Subject: MediaCapabilities: Use threadsafe static wtf::String
This replaces DEFINE_THREAD_SAFE_STATIC_LOCAL(const String, ...).
StringImpl ref counting (behind that macro) is not currently threadsafe.
(cherry picked from commit f9add3b8e53c440129f7be4a181a22c440e856bc)
Bug: 1160534
Change-Id: I70f4aa796aaefabbee36db4fcdf0fbf0defe4959
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2606399
Commit-Queue: Chrome Cunningham <chcunningham@chromium.org>
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
Auto-Submit: Chrome Cunningham <chcunningham@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#839863}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2611646
Reviewed-by: Chrome Cunningham <chcunningham@chromium.org>
Cr-Commit-Position: refs/branch-heads/4324@{#1460}
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn
index 0f08d60394f526b883a91c3994bea5dbe6a7d3e8..d38dc0f47cc186cc5bf45704a668438450797a8c 100644
--- a/third_party/blink/renderer/modules/BUILD.gn
+++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -21,12 +21,18 @@ config("modules_implementation") {
defines = [ "BLINK_MODULES_IMPLEMENTATION=1" ]
}
-make_names("module_names") {
+make_names("indexed_db_names") {
in_files = [ "indexeddb/indexed_db_names.json5" ]
output_dir = blink_modules_output_dir
deps = [] # Don't use default deps (otherwise it will be circular).
}
+make_names("media_capabilities_names") {
+ in_files = [ "media_capabilities/media_capabilities_names.json5" ]
+ output_dir = blink_modules_output_dir
+ deps = [] # Don't use default deps (otherwise it will be circular).
+}
+
jumbo_component("modules") {
output_name = "blink_modules"
@@ -42,8 +48,9 @@ jumbo_component("modules") {
"modules_initializer.h",
]
- # Compile sources generated by module_names script.
- sources += get_target_outputs(":module_names")
+ # Compile sources generated by make_names script.
+ sources += get_target_outputs(":indexed_db_names")
+ sources += get_target_outputs(":media_capabilities_names")
sources += bindings_modules_v8_files
sources += rebase_path(
@@ -165,8 +172,9 @@ jumbo_component("modules") {
}
deps = [
+ ":indexed_db_names",
":make_modules_generated",
- ":module_names",
+ ":media_capabilities_names",
"//jingle:webrtc_glue",
"//net:net",
"//third_party/blink/renderer/bindings/modules:generated",
@@ -249,7 +257,8 @@ jumbo_source_set("modules_testing") {
group("make_modules_generated") {
public_deps = [
- ":module_names",
+ ":indexed_db_names",
+ ":media_capabilities_names",
"//third_party/blink/renderer/bindings/modules:bindings_modules_generated",
"//third_party/blink/renderer/core:core_event_interfaces",
]
diff --git a/third_party/blink/renderer/modules/media_capabilities/DEPS b/third_party/blink/renderer/modules/media_capabilities/DEPS
index 3b8d2749b4f486c4b0b207d4e20f966b5e573e07..1a5a3e9e3b6a031c4752cd92cf87426cae72f1d2 100644
--- a/third_party/blink/renderer/modules/media_capabilities/DEPS
+++ b/third_party/blink/renderer/modules/media_capabilities/DEPS
@@ -12,6 +12,7 @@ include_rules = [
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/encryptedmedia",
"+third_party/blink/renderer/modules/media_capabilities",
+ "+third_party/blink/renderer/modules/media_capabilities_names.h",
"+third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h",
"+third_party/blink/renderer/modules/modules_export.h",
]
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
index d571e60943092c746a7f4136b9e626128839abfc..9515ae2f71a415bb81a7e786c9d7fb2b623bd852 100644
--- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
+++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
@@ -53,6 +53,7 @@
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h"
+#include "third_party/blink/renderer/modules/media_capabilities_names.h"
#include "third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -296,9 +297,9 @@ WebAudioConfiguration ToWebAudioConfiguration(
DCHECK(parsed_content_type.IsValid());
DCHECK(!parsed_content_type.GetParameters().HasDuplicatedNames());
- DEFINE_THREAD_SAFE_STATIC_LOCAL(const String, codecs, ("codecs"));
web_configuration.mime_type = parsed_content_type.MimeType().LowerASCII();
- web_configuration.codec = parsed_content_type.ParameterValueForName(codecs);
+ web_configuration.codec = parsed_content_type.ParameterValueForName(
+ media_capabilities_names::kCodecs);
// |channels| is optional and will be set to a null WebString if not present.
web_configuration.channels = configuration->hasChannels()
@@ -324,9 +325,9 @@ WebVideoConfiguration ToWebVideoConfiguration(
DCHECK(parsed_content_type.IsValid());
DCHECK(!parsed_content_type.GetParameters().HasDuplicatedNames());
- DEFINE_THREAD_SAFE_STATIC_LOCAL(const String, codecs, ("codecs"));
web_configuration.mime_type = parsed_content_type.MimeType().LowerASCII();
- web_configuration.codec = parsed_content_type.ParameterValueForName(codecs);
+ web_configuration.codec = parsed_content_type.ParameterValueForName(
+ media_capabilities_names::kCodecs);
DCHECK(configuration->hasWidth());
web_configuration.width = configuration->width();
@@ -586,9 +587,9 @@ bool ParseContentType(const String& content_type,
return false;
}
- DEFINE_THREAD_SAFE_STATIC_LOCAL(const String, codecs, ("codecs"));
*mime_type = parsed_content_type.MimeType().LowerASCII();
- *codec = parsed_content_type.ParameterValueForName(codecs);
+ *codec = parsed_content_type.ParameterValueForName(
+ media_capabilities_names::kCodecs);
return true;
}
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities_names.json5 b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_names.json5
new file mode 100644
index 0000000000000000000000000000000000000000..01f9a0f705da3fad7708cccbd22c9a8c1789ff0c
--- /dev/null
+++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_names.json5
@@ -0,0 +1,9 @@
+{
+ metadata: {
+ namespace: "media_capabilities_names",
+ },
+
+ data: [
+ "codecs",
+ ],
+}
diff --git a/third_party/blink/renderer/modules/modules_initializer.cc b/third_party/blink/renderer/modules/modules_initializer.cc
index df76ac04d4c64697cf5979609a55372b025adadb..5b830fd8c312bdbefe8a52b2e896b194aedb63c6 100644
--- a/third_party/blink/renderer/modules/modules_initializer.cc
+++ b/third_party/blink/renderer/modules/modules_initializer.cc
@@ -62,6 +62,7 @@
#include "third_party/blink/renderer/modules/launch/file_handling_expiry_impl.h"
#include "third_party/blink/renderer/modules/launch/web_launch_service_impl.h"
#include "third_party/blink/renderer/modules/manifest/manifest_manager.h"
+#include "third_party/blink/renderer/modules/media_capabilities_names.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_client.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_controller.h"
@@ -117,6 +118,7 @@ void ModulesInitializer::Initialize() {
Document::RegisterEventFactory(EventModulesFactory::Create());
ModuleBindingsInitializer::Init();
indexed_db_names::Init();
+ media_capabilities_names::Init();
AXObjectCache::Init(AXObjectCacheImpl::Create);
DraggedIsolatedFileSystem::Init(
DraggedIsolatedFileSystemImpl::PrepareForDataObject);

View File

@@ -0,0 +1,152 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Markus Handell <handellm@google.com>
Date: Tue, 23 Feb 2021 18:45:55 +0000
Subject: MediaRecorder: tolerate non-GMB NV12 frames for H264.
The VPX video track recorders were updated to tolerate non-GMB NV12
input in crrev/c/2425748, but the H264 encoder was left neglected,
which hurts Mac users that have disabled hardware acceleration. This
change adds that support to it.
[TBR landing because mcasas@chromium.org is OOO]
TBR=mcasas@chromium.org
(cherry picked from commit de865890bf6a12c74ae9943ede6132d25c7a33dd)
Bug: 1177593
Change-Id: I608c76b1de8261dcc44463fe896e3b63d5fd329e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2694407
Reviewed-by: ccameron <ccameron@chromium.org>
Reviewed-by: Evan Shrubsole <eshr@google.com>
Reviewed-by: Miguel Casas <mcasas@chromium.org>
Commit-Queue: Markus Handell <handellm@google.com>
Cr-Original-Commit-Position: refs/heads/master@{#854709}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2715222
Cr-Commit-Position: refs/branch-heads/4389@{#1320}
Cr-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
diff --git a/media/base/video_util.cc b/media/base/video_util.cc
index 3daa1cb27d5705d56d0075e82a9ecd0bfb86c366..d5a0f1b578e22822089d704fcd7b98cbb26bb405 100644
--- a/media/base/video_util.cc
+++ b/media/base/video_util.cc
@@ -13,6 +13,7 @@
#include "base/numerics/safe_math.h"
#include "media/base/video_frame.h"
#include "third_party/libyuv/include/libyuv.h"
+#include "ui/gfx/gpu_memory_buffer.h"
namespace media {
@@ -424,6 +425,38 @@ void CopyRGBToVideoFrame(const uint8_t* source,
region_in_frame.width(), region_in_frame.height());
}
+scoped_refptr<VideoFrame> ConvertToMemoryMappedFrame(
+ scoped_refptr<VideoFrame> video_frame) {
+ DCHECK(video_frame);
+ DCHECK(video_frame->HasGpuMemoryBuffer());
+ auto* gmb = video_frame->GetGpuMemoryBuffer();
+ if (!gmb->Map())
+ return nullptr;
+ const size_t num_planes = VideoFrame::NumPlanes(video_frame->format());
+ uint8_t* plane_addrs[VideoFrame::kMaxPlanes] = {};
+ for (size_t i = 0; i < num_planes; i++)
+ plane_addrs[i] = static_cast<uint8_t*>(gmb->memory(i));
+ auto mapped_frame = VideoFrame::WrapExternalYuvDataWithLayout(
+ video_frame->layout(), video_frame->visible_rect(),
+ video_frame->natural_size(), plane_addrs[0], plane_addrs[1],
+ plane_addrs[2], video_frame->timestamp());
+ if (!mapped_frame) {
+ gmb->Unmap();
+ return nullptr;
+ }
+ mapped_frame->set_color_space(video_frame->ColorSpace());
+ mapped_frame->metadata()->MergeMetadataFrom(video_frame->metadata());
+ // Pass |video_frame| so that it outlives |mapped_frame| and the mapped buffer
+ // is unmapped on destruction.
+ mapped_frame->AddDestructionObserver(base::BindOnce(
+ [](scoped_refptr<VideoFrame> frame) {
+ DCHECK(frame->HasGpuMemoryBuffer());
+ frame->GetGpuMemoryBuffer()->Unmap();
+ },
+ std::move(video_frame)));
+ return mapped_frame;
+}
+
scoped_refptr<VideoFrame> WrapAsI420VideoFrame(
scoped_refptr<VideoFrame> frame) {
DCHECK_EQ(VideoFrame::STORAGE_OWNED_MEMORY, frame->storage_type());
diff --git a/media/base/video_util.h b/media/base/video_util.h
index 42e060a25b711fca8bba3cef8ade9bbaa2092c55..2681163c55618ae8738d91987bb46a4e8bcc541b 100644
--- a/media/base/video_util.h
+++ b/media/base/video_util.h
@@ -134,6 +134,12 @@ MEDIA_EXPORT gfx::Size GetRectSizeFromOrigin(const gfx::Rect& rect);
MEDIA_EXPORT gfx::Size PadToMatchAspectRatio(const gfx::Size& size,
const gfx::Size& target);
+// A helper function to map GpuMemoryBuffer-based VideoFrame. This function
+// maps the given GpuMemoryBuffer of |frame| as-is without converting pixel
+// format. The returned VideoFrame owns the |frame|.
+MEDIA_EXPORT scoped_refptr<VideoFrame> ConvertToMemoryMappedFrame(
+ scoped_refptr<VideoFrame> frame);
+
// Copy an RGB bitmap into the specified |region_in_frame| of a YUV video frame.
// Fills the regions outside |region_in_frame| with black.
MEDIA_EXPORT void CopyRGBToVideoFrame(const uint8_t* source,
diff --git a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
index 401e696e886f68fc4a9bb9ac0614959f0a8673a8..c323faab804ad421b1c8f8d7789222304c4d44e6 100644
--- a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
+++ b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
@@ -54,9 +54,13 @@ void H264Encoder::EncodeOnEncodingTaskRunner(
base::TimeTicks capture_timestamp) {
TRACE_EVENT0("media", "H264Encoder::EncodeOnEncodingTaskRunner");
DCHECK(encoding_task_runner_->BelongsToCurrentThread());
+ DCHECK(frame->format() == media::VideoPixelFormat::PIXEL_FORMAT_NV12 ||
+ frame->format() == media::VideoPixelFormat::PIXEL_FORMAT_I420 ||
+ frame->format() == media::VideoPixelFormat::PIXEL_FORMAT_I420A);
- if (frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER)
+ if (frame->format() == media::PIXEL_FORMAT_NV12)
frame = ConvertToI420ForSoftwareEncoder(frame);
+ DCHECK(frame->IsMappable());
const gfx::Size frame_size = frame->visible_rect().size();
if (!openh264_encoder_ || configured_size_ != frame_size) {
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
index 0397c605efbb2a669e0235898e1b3029e3b4f0e8..7a7683092919b3712b2c09a86b06fd9c724f8aac 100644
--- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
+++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
@@ -415,20 +415,17 @@ bool VideoTrackRecorderImpl::Encoder::CanEncodeAlphaChannel() {
scoped_refptr<media::VideoFrame>
VideoTrackRecorderImpl::Encoder::ConvertToI420ForSoftwareEncoder(
scoped_refptr<media::VideoFrame> frame) {
- DCHECK_EQ(frame->storage_type(),
- media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER);
- // NV12 is currently the only supported pixel format for GpuMemoryBuffer.
DCHECK_EQ(frame->format(), media::VideoPixelFormat::PIXEL_FORMAT_NV12);
- auto* gmb = frame->GetGpuMemoryBuffer();
- if (!gmb->Map())
- return frame;
+ if (frame->GetGpuMemoryBuffer())
+ frame = media::ConvertToMemoryMappedFrame(frame);
+
scoped_refptr<media::VideoFrame> i420_frame = media::VideoFrame::CreateFrame(
media::VideoPixelFormat::PIXEL_FORMAT_I420, frame->coded_size(),
frame->visible_rect(), frame->natural_size(), frame->timestamp());
auto ret = libyuv::NV12ToI420(
- static_cast<const uint8_t*>(gmb->memory(0)), gmb->stride(0),
- static_cast<const uint8_t*>(gmb->memory(1)), gmb->stride(1),
+ static_cast<const uint8_t*>(frame->data(0)), frame->stride(0),
+ static_cast<const uint8_t*>(frame->data(1)), frame->stride(1),
i420_frame->data(media::VideoFrame::kYPlane),
i420_frame->stride(media::VideoFrame::kYPlane),
i420_frame->data(media::VideoFrame::kUPlane),
@@ -436,7 +433,6 @@ VideoTrackRecorderImpl::Encoder::ConvertToI420ForSoftwareEncoder(
i420_frame->data(media::VideoFrame::kVPlane),
i420_frame->stride(media::VideoFrame::kVPlane),
frame->coded_size().width(), frame->coded_size().height());
- gmb->Unmap();
if (ret)
return frame;
return i420_frame;

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

@@ -0,0 +1,342 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dominik=20R=C3=B6ttsches?= <drott@chromium.org>
Date: Mon, 11 Jan 2021 12:27:12 +0000
Subject: Backport maxp sanitization
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Backport [1] to perform additional sanitization on maxp values.
[1] https://github.com/khaledhosny/ots/pull/227
(cherry picked from commit 6d0e7d799a46336c6bc297d4075a27dd0e7c235d)
Bug: 1153329
Change-Id: I4bc2288574802559f6c9c67a52b6dfcd8cc7467a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2588339
Auto-Submit: Dominik Röttsches <drott@chromium.org>
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
Reviewed-by: Koji Ishii <kojii@chromium.org>
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#836679}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2620800
Commit-Queue: Dominik Röttsches <drott@chromium.org>
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/branch-heads/4324@{#1620}
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
diff --git a/third_party/ots/README.chromium b/third_party/ots/README.chromium
index 8e8aaba85b508110eb9662d5714712dd481e037c..c35d4f71f5af26c19675a3a5d8ef8ee3730c94da 100644
--- a/third_party/ots/README.chromium
+++ b/third_party/ots/README.chromium
@@ -11,4 +11,7 @@ Local Modifications:
- BUILD.gn: Added.
- fuzz/: Added.
- ots.cc: Allow CFF2 outlines, upstreamed in
- https://github.com/khaledhosny/ots/pull/161
\ No newline at end of file
+ https://github.com/khaledhosny/ots/pull/161
+- glyf.h, glyf.cc - Backport of "Sanitise values for fonts with invalid
+ maxPoints and maxComponentPoints"
+ https://github.com/khaledhosny/ots/pull/227
diff --git a/third_party/ots/src/glyf.cc b/third_party/ots/src/glyf.cc
index b8fb2866da7d16c2cafc470dcc10277a19bd325a..8d2e498ea8f48160e06de8200f2afc6e598252df 100644
--- a/third_party/ots/src/glyf.cc
+++ b/third_party/ots/src/glyf.cc
@@ -99,6 +99,11 @@ bool OpenTypeGLYF::ParseSimpleGlyph(Buffer &glyph,
num_flags = tmp_index + 1;
}
+ if (num_flags > this->maxp->max_points) {
+ Warning("Number of contour points exceeds maxp maxPoints, adjusting limit.");
+ this->maxp->max_points = num_flags;
+ }
+
uint16_t bytecode_length = 0;
if (!glyph.ReadU16(&bytecode_length)) {
return Error("Can't read bytecode length");
@@ -143,7 +148,9 @@ bool OpenTypeGLYF::ParseSimpleGlyph(Buffer &glyph,
#define WE_HAVE_A_TWO_BY_TWO (1u << 7)
#define WE_HAVE_INSTRUCTIONS (1u << 8)
-bool OpenTypeGLYF::ParseCompositeGlyph(Buffer &glyph) {
+bool OpenTypeGLYF::ParseCompositeGlyph(
+ Buffer &glyph,
+ ComponentPointCount* component_point_count) {
uint16_t flags = 0;
uint16_t gid = 0;
do {
@@ -192,6 +199,10 @@ bool OpenTypeGLYF::ParseCompositeGlyph(Buffer &glyph) {
return Error("Can't read transform");
}
}
+
+ // Push inital components on stack at level 1
+ // to traverse them in parent function.
+ component_point_count->gid_stack.push_back({gid, 1});
} while (flags & MORE_COMPONENTS);
if (flags & WE_HAVE_INSTRUCTIONS) {
@@ -241,29 +252,16 @@ bool OpenTypeGLYF::Parse(const uint8_t *data, size_t length) {
uint32_t current_offset = 0;
for (unsigned i = 0; i < num_glyphs; ++i) {
- const unsigned gly_offset = offsets[i];
- // The LOCA parser checks that these values are monotonic
- const unsigned gly_length = offsets[i + 1] - offsets[i];
- if (!gly_length) {
- // this glyph has no outline (e.g. the space charactor)
+
+ Buffer glyph(GetGlyphBufferSection(data, length, offsets, i));
+ if (!glyph.buffer())
+ return false;
+
+ if (!glyph.length()) {
resulting_offsets[i] = current_offset;
continue;
}
- if (gly_offset >= length) {
- return Error("Glyph %d offset %d too high %ld", i, gly_offset, length);
- }
- // Since these are unsigned types, the compiler is not allowed to assume
- // that they never overflow.
- if (gly_offset + gly_length < gly_offset) {
- return Error("Glyph %d length (%d < 0)!", i, gly_length);
- }
- if (gly_offset + gly_length > length) {
- return Error("Glyph %d length %d too high", i, gly_length);
- }
-
- Buffer glyph(data + gly_offset, gly_length);
-
int16_t num_contours, xmin, ymin, xmax, ymax;
if (!glyph.ReadS16(&num_contours) ||
!glyph.ReadS16(&xmin) ||
@@ -300,9 +298,56 @@ bool OpenTypeGLYF::Parse(const uint8_t *data, size_t length) {
return Error("Failed to parse glyph %d", i);
}
} else {
- if (!ParseCompositeGlyph(glyph)) {
+
+ ComponentPointCount component_point_count;
+ if (!ParseCompositeGlyph(glyph, &component_point_count)) {
return Error("Failed to parse glyph %d", i);
}
+
+ // Check maxComponentDepth and validate maxComponentPoints.
+ // ParseCompositeGlyph placed the first set of component glyphs on the
+ // component_point_count.gid_stack, which we start to process below. If a
+ // nested glyph is in turn a component glyph, additional glyphs are placed
+ // on the stack.
+ while (component_point_count.gid_stack.size()) {
+ GidAtLevel stack_top_gid = component_point_count.gid_stack.back();
+ component_point_count.gid_stack.pop_back();
+
+ Buffer points_count_glyph(GetGlyphBufferSection(
+ data,
+ length,
+ offsets,
+ stack_top_gid.gid));
+
+ if (!points_count_glyph.buffer())
+ return false;
+
+ if (!points_count_glyph.length())
+ continue;
+
+ if (!TraverseComponentsCountingPoints(points_count_glyph,
+ i,
+ stack_top_gid.level,
+ &component_point_count)) {
+ return Error("Error validating component points and depth.");
+ }
+
+ if (component_point_count.accumulated_component_points >
+ std::numeric_limits<uint16_t>::max()) {
+ return Error("Illegal composite points value "
+ "exceeding 0xFFFF for base glyph %d.", i);
+ } else if (component_point_count.accumulated_component_points >
+ this->maxp->max_c_points) {
+ Warning("Number of composite points in glyph %d exceeds "
+ "maxp maxCompositePoints: %d vs %d, adjusting limit.",
+ i,
+ component_point_count.accumulated_component_points,
+ this->maxp->max_c_points
+ );
+ this->maxp->max_c_points =
+ component_point_count.accumulated_component_points;
+ }
+ }
}
size_t new_size = glyph.offset();
@@ -342,6 +387,122 @@ bool OpenTypeGLYF::Parse(const uint8_t *data, size_t length) {
return true;
}
+bool OpenTypeGLYF::TraverseComponentsCountingPoints(
+ Buffer &glyph,
+ uint16_t base_glyph_id,
+ uint32_t level,
+ ComponentPointCount* component_point_count) {
+
+ int16_t num_contours;
+ if (!glyph.ReadS16(&num_contours) ||
+ !glyph.Skip(8)) {
+ return Error("Can't read glyph header.");
+ }
+
+ if (num_contours <= -2) {
+ return Error("Bad number of contours %d in glyph.", num_contours);
+ }
+
+ if (num_contours == 0)
+ return true;
+
+ // FontTools counts a component level for each traversed recursion. We start
+ // counting at level 0. If we reach a level that's deeper than
+ // maxComponentDepth, we expand maxComponentDepth unless it's larger than
+ // the maximum possible depth.
+ if (level > std::numeric_limits<uint16_t>::max()) {
+ return Error("Illegal component depth exceeding 0xFFFF in base glyph id %d.",
+ base_glyph_id);
+ } else if (level > this->maxp->max_c_depth) {
+ this->maxp->max_c_depth = level;
+ Warning("Component depth exceeds maxp maxComponentDepth "
+ "in glyph %d, adjust limit to %d.",
+ base_glyph_id, level);
+ }
+
+ if (num_contours > 0) {
+ uint16_t num_points = 0;
+ for (int i = 0; i < num_contours; ++i) {
+ // Simple glyph, add contour points.
+ uint16_t tmp_index = 0;
+ if (!glyph.ReadU16(&tmp_index)) {
+ return Error("Can't read contour index %d", i);
+ }
+ num_points = tmp_index + 1;
+ }
+
+ component_point_count->accumulated_component_points += num_points;
+ return true;
+ } else {
+ assert(num_contours == -1);
+
+ // Composite glyph, add gid's to stack.
+ uint16_t flags = 0;
+ uint16_t gid = 0;
+ do {
+ if (!glyph.ReadU16(&flags) || !glyph.ReadU16(&gid)) {
+ return Error("Can't read composite glyph flags or glyphIndex");
+ }
+
+ size_t skip_bytes = 0;
+ skip_bytes += flags & ARG_1_AND_2_ARE_WORDS ? 4 : 2;
+
+ if (flags & WE_HAVE_A_SCALE) {
+ skip_bytes += 2;
+ } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
+ skip_bytes += 4;
+ } else if (flags & WE_HAVE_A_TWO_BY_TWO) {
+ skip_bytes += 8;
+ }
+
+ if (!glyph.Skip(skip_bytes)) {
+ return Error("Failed to parse component glyph.");
+ }
+
+ if (gid >= this->maxp->num_glyphs) {
+ return Error("Invalid glyph id used in composite glyph: %d", gid);
+ }
+
+ component_point_count->gid_stack.push_back({gid, level + 1u});
+ } while (flags & MORE_COMPONENTS);
+ return true;
+ }
+}
+
+Buffer OpenTypeGLYF::GetGlyphBufferSection(
+ const uint8_t *data,
+ size_t length,
+ const std::vector<uint32_t>& loca_offsets,
+ unsigned glyph_id) {
+
+ Buffer null_buffer(nullptr, 0);
+
+ const unsigned gly_offset = loca_offsets[glyph_id];
+ // The LOCA parser checks that these values are monotonic
+ const unsigned gly_length = loca_offsets[glyph_id + 1] - loca_offsets[glyph_id];
+ if (!gly_length) {
+ // this glyph has no outline (e.g. the space character)
+ return Buffer(data + gly_offset, 0);
+ }
+
+ if (gly_offset >= length) {
+ Error("Glyph %d offset %d too high %ld", glyph_id, gly_offset, length);
+ return null_buffer;
+ }
+ // Since these are unsigned types, the compiler is not allowed to assume
+ // that they never overflow.
+ if (gly_offset + gly_length < gly_offset) {
+ Error("Glyph %d length (%d < 0)!", glyph_id, gly_length);
+ return null_buffer;
+ }
+ if (gly_offset + gly_length > length) {
+ Error("Glyph %d length %d too high", glyph_id, gly_length);
+ return null_buffer;
+ }
+
+ return Buffer(data + gly_offset, gly_length);
+}
+
bool OpenTypeGLYF::Serialize(OTSStream *out) {
for (unsigned i = 0; i < this->iov.size(); ++i) {
if (!out->Write(this->iov[i].first, this->iov[i].second)) {
diff --git a/third_party/ots/src/glyf.h b/third_party/ots/src/glyf.h
index 1da94e4b9455c47371ffb07a39921be1aaca61e8..08c585df349db447a7b9bfa0fd2e8dde31728e5d 100644
--- a/third_party/ots/src/glyf.h
+++ b/third_party/ots/src/glyf.h
@@ -23,12 +23,38 @@ class OpenTypeGLYF : public Table {
bool Serialize(OTSStream *out);
private:
+ struct GidAtLevel {
+ uint16_t gid;
+ uint32_t level;
+ };
+
+ struct ComponentPointCount {
+ ComponentPointCount() : accumulated_component_points(0) {};
+ uint32_t accumulated_component_points;
+ std::vector<GidAtLevel> gid_stack;
+ };
+
bool ParseFlagsForSimpleGlyph(Buffer &glyph,
uint32_t num_flags,
uint32_t *flag_index,
uint32_t *coordinates_length);
bool ParseSimpleGlyph(Buffer &glyph, int16_t num_contours);
- bool ParseCompositeGlyph(Buffer &glyph);
+ bool ParseCompositeGlyph(
+ Buffer &glyph,
+ ComponentPointCount* component_point_count);
+
+
+ bool TraverseComponentsCountingPoints(
+ Buffer& glyph,
+ uint16_t base_glyph_id,
+ uint32_t level,
+ ComponentPointCount* component_point_count);
+
+ Buffer GetGlyphBufferSection(
+ const uint8_t *data,
+ size_t length,
+ const std::vector<uint32_t>& loca_offsets,
+ unsigned glyph_id);
OpenTypeMAXP* maxp;

View File

@@ -0,0 +1,68 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dominik=20R=C3=B6ttsches?= <drott@chromium.org>
Date: Mon, 11 Jan 2021 14:33:32 +0000
Subject: Backport of "[glyf] Guard access to maxp version 1 field"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
(cherry picked from commit fac68744a85e8c601f60f1ef73a6e9ddf150855e)
Bug: 1153329, 1158774
Change-Id: I6acd298f841f92a751f606d710415fe32343825f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2593261
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Auto-Submit: Dominik Röttsches <drott@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#837353}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2621064
Commit-Queue: Dominik Röttsches <drott@chromium.org>
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/branch-heads/4324@{#1625}
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
diff --git a/third_party/ots/README.chromium b/third_party/ots/README.chromium
index c35d4f71f5af26c19675a3a5d8ef8ee3730c94da..43ddc08a0e1a65bb084b60d66c641c911cfba279 100644
--- a/third_party/ots/README.chromium
+++ b/third_party/ots/README.chromium
@@ -15,3 +15,5 @@ Local Modifications:
- glyf.h, glyf.cc - Backport of "Sanitise values for fonts with invalid
maxPoints and maxComponentPoints"
https://github.com/khaledhosny/ots/pull/227
+- glyf.cc - Backport of "[glyf] Guard access to maxp version 1 field"
+ Upstream commit 1141c81c411b599e40496679129d0884715e8650
diff --git a/third_party/ots/src/glyf.cc b/third_party/ots/src/glyf.cc
index 8d2e498ea8f48160e06de8200f2afc6e598252df..ab9232ea2dcb5fe0ea2b4d3274b11103c85e51fa 100644
--- a/third_party/ots/src/glyf.cc
+++ b/third_party/ots/src/glyf.cc
@@ -99,7 +99,8 @@ bool OpenTypeGLYF::ParseSimpleGlyph(Buffer &glyph,
num_flags = tmp_index + 1;
}
- if (num_flags > this->maxp->max_points) {
+ if (this->maxp->version_1 &&
+ num_flags > this->maxp->max_points) {
Warning("Number of contour points exceeds maxp maxPoints, adjusting limit.");
this->maxp->max_points = num_flags;
}
@@ -336,7 +337,8 @@ bool OpenTypeGLYF::Parse(const uint8_t *data, size_t length) {
std::numeric_limits<uint16_t>::max()) {
return Error("Illegal composite points value "
"exceeding 0xFFFF for base glyph %d.", i);
- } else if (component_point_count.accumulated_component_points >
+ } else if (this->maxp->version_1 &&
+ component_point_count.accumulated_component_points >
this->maxp->max_c_points) {
Warning("Number of composite points in glyph %d exceeds "
"maxp maxCompositePoints: %d vs %d, adjusting limit.",
@@ -413,7 +415,8 @@ bool OpenTypeGLYF::TraverseComponentsCountingPoints(
if (level > std::numeric_limits<uint16_t>::max()) {
return Error("Illegal component depth exceeding 0xFFFF in base glyph id %d.",
base_glyph_id);
- } else if (level > this->maxp->max_c_depth) {
+ } else if (this->maxp->version_1 &&
+ level > this->maxp->max_c_depth) {
this->maxp->max_c_depth = level;
Warning("Component depth exceeds maxp maxComponentDepth "
"in glyph %d, adjust limit to %d.",

View File

@@ -0,0 +1,476 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marijn Kruisselbrink <mek@chromium.org>
Date: Tue, 8 Dec 2020 07:20:47 +0000
Subject: Reland "Reland "[FSA] Add IsSafePathComponent checks to
GetFile/GetDirectoryHandle.""
This is a reland of 2d41c3952d2851948a09ddcf3e97bae6c419b024
The added test was modified to no longer assert that all unsafe files
were written to disk successfully. This should make the test pass (albeit
with less stringent checks) on file systems/platforms that don't allow
all unsafe file names.
Original change's description:
> Reland "[FSA] Add IsSafePathComponent checks to GetFile/GetDirectoryHandle."
>
> This is a reland of 004377929febd7cf7392932b01df7f4a0a362679
>
> The main difference is to make sure iterating over a directory doesn't
> return files we don't want to expose either (and not CHECK failing if
> such files are found when iterating).
>
> Original change's description:
> > [FSA] Add IsSafePathComponent checks to GetFile/GetDirectoryHandle.
> >
> > This isn't directly using net::IsSafePortablePathComponent since what
> > is safe for the File System Access API is not the same as what is safe
> > for Downloads. As such currently this duplicates a lot of the
> > implementation of this method, but in a followup we should attempt to
> > unify these two implementations as much as possible.
> >
> > Bug: 1150810, 1154757
> > Change-Id: Iba4c92ef5f1cd924aa22b9dd201762d48b4bbc3b
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2568383
> > Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
> > Reviewed-by: Victor Costan <pwnall@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#833042}
>
> Bug: 1150810
> Bug: 1154757
> Change-Id: I3341b9824a1ac4cbd6f100355960ad55b01f0753
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2575370
> Commit-Queue: Victor Costan <pwnall@chromium.org>
> Reviewed-by: Victor Costan <pwnall@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#834118}
Bug: 1150810
Bug: 1154757
Change-Id: Ie5cad9a7b2383c89b96e8a7be6cfe75ad2555fa6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2577614
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Auto-Submit: Marijn Kruisselbrink <mek@chromium.org>
Reviewed-by: Victor Costan <pwnall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#834598}
diff --git a/content/browser/native_file_system/native_file_system_directory_handle_impl.cc b/content/browser/native_file_system/native_file_system_directory_handle_impl.cc
index 89ea8eaf06595607b7c54f96318ad0f984690b99..fff61f2a648d9be70c50115a446bea5b14c3b3ce 100644
--- a/content/browser/native_file_system/native_file_system_directory_handle_impl.cc
+++ b/content/browser/native_file_system/native_file_system_directory_handle_impl.cc
@@ -4,6 +4,7 @@
#include "content/browser/native_file_system/native_file_system_directory_handle_impl.h"
+#include "base/i18n/file_util_icu.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -12,6 +13,7 @@
#include "content/browser/native_file_system/native_file_system_transfer_token_impl.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/base/escape.h"
+#include "net/base/filename_util.h"
#include "storage/browser/file_system/file_system_context.h"
#include "storage/browser/file_system/file_system_operation_runner.h"
#include "storage/common/file_system/file_system_util.h"
@@ -28,27 +30,6 @@ using storage::FileSystemOperationRunner;
namespace content {
-namespace {
-
-// Returns true when |name| contains a path separator like "/".
-bool ContainsPathSeparator(const std::string& name) {
- const base::FilePath filepath_name = storage::StringToFilePath(name);
-
- const size_t separator_position =
- filepath_name.value().find_first_of(base::FilePath::kSeparators);
-
- return separator_position != base::FilePath::StringType::npos;
-}
-
-// Returns true when |name| is "." or "..".
-bool IsCurrentOrParentDirectory(const std::string& name) {
- const base::FilePath filepath_name = storage::StringToFilePath(name);
- return filepath_name.value() == base::FilePath::kCurrentDirectory ||
- filepath_name.value() == base::FilePath::kParentDirectory;
-}
-
-} // namespace
-
NativeFileSystemDirectoryHandleImpl::NativeFileSystemDirectoryHandleImpl(
NativeFileSystemManagerImpl* manager,
const BindingContext& context,
@@ -387,9 +368,10 @@ void NativeFileSystemDirectoryHandleImpl::DidReadDirectory(
blink::mojom::NativeFileSystemErrorPtr get_child_url_result =
GetChildURL(basename, &child_url);
- // All entries must exist in this directory as a direct child with a valid
- // |basename|.
- CHECK_EQ(get_child_url_result->status, NativeFileSystemStatus::kOk);
+ // Skip any entries with names that aren't allowed to be accessed by
+ // this API, such as files with disallowed characters in their names.
+ if (get_child_url_result->status != NativeFileSystemStatus::kOk)
+ continue;
entries.push_back(
CreateEntry(basename, child_url,
@@ -418,25 +400,99 @@ void NativeFileSystemDirectoryHandleImpl::RemoveEntryImpl(
url, recurse);
}
+namespace {
+
+// Returns whether the specified extension receives special handling by the
+// Windows shell.
+bool IsShellIntegratedExtension(const base::FilePath::StringType& extension) {
+ base::FilePath::StringType extension_lower = base::ToLowerASCII(extension);
+
+ // .lnk files may be used to execute arbitrary code (see
+ // https://nvd.nist.gov/vuln/detail/CVE-2010-2568).
+ if (extension_lower == FILE_PATH_LITERAL("lnk"))
+ return true;
+
+ // Setting a file's extension to a CLSID may conceal its actual file type on
+ // some Windows versions (see https://nvd.nist.gov/vuln/detail/CVE-2004-0420).
+ if (!extension_lower.empty() &&
+ (extension_lower.front() == FILE_PATH_LITERAL('{')) &&
+ (extension_lower.back() == FILE_PATH_LITERAL('}')))
+ return true;
+ return false;
+}
+
+} // namespace
+
+// static
+bool NativeFileSystemDirectoryHandleImpl::IsSafePathComponent(
+ const std::string& name) {
+ // This method is similar to net::IsSafePortablePathComponent, with a few
+ // notable differences where the net version does not consider names safe
+ // while here we do want to allow them. These cases are:
+ // - Names starting with a '.'. These would be hidden files in most file
+ // managers, but are something we explicitly want to support for the
+ // File System Access API, for names like .git.
+ // - Names that end in '.local'. For downloads writing to such files is
+ // dangerous since it might modify what code is executed when an executable
+ // is ran from the same directory. For the File System Access API this
+ // isn't really a problem though, since if a website can write to a .local
+ // file via a FileSystemDirectoryHandle they can also just modify the
+ // executables in the directory directly.
+ //
+ // TODO(https://crbug.com/1154757): Unify this with
+ // net::IsSafePortablePathComponent, with the result probably ending up in
+ // base/i18n/file_util_icu.h.
+
+ const base::FilePath component = storage::StringToFilePath(name);
+ // Empty names, or names that contain path separators are invalid.
+ if (component.empty() || component != component.BaseName() ||
+ component != component.StripTrailingSeparators()) {
+ return false;
+ }
+
+ base::string16 component16;
+#if defined(OS_WIN)
+ component16.assign(component.value().begin(), component.value().end());
+#else
+ std::string component8 = component.AsUTF8Unsafe();
+ if (!base::UTF8ToUTF16(component8.c_str(), component8.size(), &component16))
+ return false;
+#endif
+ // base::i18n::IsFilenameLegal blocks names that start with '.', so strip out
+ // a leading '.' before passing it to that method.
+ // TODO(mek): Consider making IsFilenameLegal more flexible to support this
+ // use case.
+ if (component16[0] == '.')
+ component16 = component16.substr(1);
+ if (!base::i18n::IsFilenameLegal(component16))
+ return false;
+
+ base::FilePath::StringType extension = component.Extension();
+ if (!extension.empty())
+ extension.erase(extension.begin()); // Erase preceding '.'.
+ if (IsShellIntegratedExtension(extension))
+ return false;
+
+ if (base::TrimString(component.value(), FILE_PATH_LITERAL("."),
+ base::TRIM_TRAILING) != component.value()) {
+ return false;
+ }
+
+ if (net::IsReservedNameOnWindows(component.value()))
+ return false;
+
+ return true;
+}
+
+
blink::mojom::NativeFileSystemErrorPtr
NativeFileSystemDirectoryHandleImpl::GetChildURL(
const std::string& basename,
storage::FileSystemURL* result) {
- // TODO(mek): Rather than doing URL serialization and parsing we should just
- // have a way to get a child FileSystemURL directly from its parent.
-
- if (basename.empty()) {
- return native_file_system_error::FromStatus(
- NativeFileSystemStatus::kInvalidArgument,
- "Name can't be an empty string.");
- }
- if (ContainsPathSeparator(basename) || IsCurrentOrParentDirectory(basename)) {
- // |basename| must refer to a entry that exists in this directory as a
- // direct child.
+ if (!IsSafePathComponent(basename)) {
return native_file_system_error::FromStatus(
- NativeFileSystemStatus::kInvalidArgument,
- "Name contains invalid characters.");
+ NativeFileSystemStatus::kInvalidArgument, "Name is not allowed.");
}
std::string escaped_name =
diff --git a/content/browser/native_file_system/native_file_system_directory_handle_impl.h b/content/browser/native_file_system/native_file_system_directory_handle_impl.h
index 061ffbb26d13966bc1d4da6c31fd17687d31422a..7ff29b706da905dbb30328bfe854cd052f2b84bb 100644
--- a/content/browser/native_file_system/native_file_system_directory_handle_impl.h
+++ b/content/browser/native_file_system/native_file_system_directory_handle_impl.h
@@ -57,6 +57,14 @@ class CONTENT_EXPORT NativeFileSystemDirectoryHandleImpl
mojo::PendingReceiver<blink::mojom::NativeFileSystemTransferToken> token)
override;
+ // The File System Access API should not give access to files that might
+ // trigger special handling from the operating system. This method is used to
+ // validate that all paths passed to GetFileHandle/GetDirectoryHandle are safe
+ // to be exposed to the web.
+ // TODO(https://crbug.com/1154757): Merge this with
+ // net::IsSafePortablePathComponent.
+ static bool IsSafePathComponent(const std::string& name);
+
private:
// This method creates the file if it does not currently exists. I.e. it is
// the implementation for passing create=true to GetFile.
diff --git a/content/browser/native_file_system/native_file_system_directory_handle_impl_unittest.cc b/content/browser/native_file_system/native_file_system_directory_handle_impl_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8f5e109c78cebecca1a9724327ceb1fefa01e6db
--- /dev/null
+++ b/content/browser/native_file_system/native_file_system_directory_handle_impl_unittest.cc
@@ -0,0 +1,196 @@
+// Copyright 2020 The Chromium 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 "content/browser/native_file_system/native_file_system_directory_handle_impl.h"
+
+#include <iterator>
+#include <string>
+
+#include "base/bind.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/macros.h"
+#include "base/run_loop.h"
+#include "base/test/bind.h"
+#include "base/test/task_environment.h"
+#include "build/build_config.h"
+#include "content/browser/native_file_system/fixed_native_file_system_permission_grant.h"
+#include "content/public/test/browser_task_environment.h"
+#include "storage/browser/test/test_file_system_context.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+using storage::FileSystemURL;
+
+class NativeFileSystemDirectoryHandleImplTest : public testing::Test {
+ public:
+ NativeFileSystemDirectoryHandleImplTest()
+ : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}
+
+ void SetUp() override {
+ ASSERT_TRUE(dir_.CreateUniqueTempDir());
+
+ file_system_context_ = storage::CreateFileSystemContextForTesting(
+ /*quota_manager_proxy=*/nullptr, dir_.GetPath());
+
+ chrome_blob_context_ = base::MakeRefCounted<ChromeBlobStorageContext>();
+ chrome_blob_context_->InitializeOnIOThread(base::FilePath(),
+ base::FilePath(), nullptr);
+
+ manager_ = base::MakeRefCounted<NativeFileSystemManagerImpl>(
+ file_system_context_, chrome_blob_context_,
+ /*permission_context=*/nullptr,
+ /*off_the_record=*/false);
+
+ auto url_and_fs = manager_->CreateFileSystemURLFromPath(
+ test_src_origin_, NativeFileSystemEntryFactory::PathType::kLocal,
+ dir_.GetPath());
+
+ handle_ = std::make_unique<NativeFileSystemDirectoryHandleImpl>(
+ manager_.get(),
+ NativeFileSystemManagerImpl::BindingContext(
+ test_src_origin_, test_src_url_, /*worker_process_id=*/1),
+ url_and_fs.url,
+ NativeFileSystemManagerImpl::SharedHandleState(
+ allow_grant_, allow_grant_, std::move(url_and_fs.file_system)));
+ }
+
+ void TearDown() override { task_environment_.RunUntilIdle(); }
+
+ protected:
+ const GURL test_src_url_ = GURL("http://example.com/foo");
+ const url::Origin test_src_origin_ = url::Origin::Create(test_src_url_);
+
+ BrowserTaskEnvironment task_environment_;
+
+ base::ScopedTempDir dir_;
+ scoped_refptr<storage::FileSystemContext> file_system_context_;
+ scoped_refptr<ChromeBlobStorageContext> chrome_blob_context_;
+ scoped_refptr<NativeFileSystemManagerImpl> manager_;
+
+ scoped_refptr<FixedNativeFileSystemPermissionGrant> allow_grant_ =
+ base::MakeRefCounted<FixedNativeFileSystemPermissionGrant>(
+ FixedNativeFileSystemPermissionGrant::PermissionStatus::GRANTED,
+ base::FilePath());
+ std::unique_ptr<NativeFileSystemDirectoryHandleImpl> handle_;
+};
+
+TEST_F(NativeFileSystemDirectoryHandleImplTest, IsSafePathComponent) {
+ constexpr const char* kSafePathComponents[] = {
+ "a", "a.txt", "a b.txt", "My Computer", ".a", "lnk.zip", "lnk", "a.local",
+ };
+
+ constexpr const char* kUnsafePathComponents[] = {
+ "",
+ ".",
+ "..",
+ "...",
+ "con",
+ "con.zip",
+ "NUL",
+ "NUL.zip",
+ "a.",
+ "a\"a",
+ "a<a",
+ "a>a",
+ "a?a",
+ "a/",
+ "a\\",
+ "a ",
+ "a . .",
+ " Computer",
+ "My Computer.{a}",
+ "My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
+ "a\\a",
+ "a.lnk",
+ "a/a",
+ "C:\\",
+ "C:/",
+ "C:",
+ };
+
+ for (const char* component : kSafePathComponents) {
+ EXPECT_TRUE(
+ NativeFileSystemDirectoryHandleImpl::IsSafePathComponent(component))
+ << component;
+ }
+ for (const char* component : kUnsafePathComponents) {
+ EXPECT_FALSE(
+ NativeFileSystemDirectoryHandleImpl::IsSafePathComponent(component))
+ << component;
+ }
+}
+
+namespace {
+class TestNativeFileSystemDirectoryEntriesListener
+ : public blink::mojom::NativeFileSystemDirectoryEntriesListener {
+ public:
+ TestNativeFileSystemDirectoryEntriesListener(
+ std::vector<blink::mojom::NativeFileSystemEntryPtr>* entries,
+ base::OnceClosure done)
+ : entries_(entries), done_(std::move(done)) {}
+
+ void DidReadDirectory(
+ blink::mojom::NativeFileSystemErrorPtr result,
+ std::vector<blink::mojom::NativeFileSystemEntryPtr> entries,
+ bool has_more_entries) override {
+ EXPECT_EQ(result->status, blink::mojom::NativeFileSystemStatus::kOk);
+ entries_->insert(entries_->end(), std::make_move_iterator(entries.begin()),
+ std::make_move_iterator(entries.end()));
+ if (!has_more_entries) {
+ std::move(done_).Run();
+ }
+ }
+
+ private:
+ std::vector<blink::mojom::NativeFileSystemEntryPtr>* entries_;
+ base::OnceClosure done_;
+};
+} // namespace
+
+TEST_F(NativeFileSystemDirectoryHandleImplTest, GetEntries) {
+ constexpr const char* kSafeNames[] = {"a", "a.txt", "My Computer", "lnk.txt",
+ "a.local"};
+ constexpr const char* kUnsafeNames[] = {
+ "con", "con.zip", "NUL", "a.",
+ "a\"a", "a . .", "a.lnk", "My Computer.{a}",
+ };
+ for (const char* name : kSafeNames) {
+ ASSERT_TRUE(base::WriteFile(dir_.GetPath().AppendASCII(name), "data"))
+ << name;
+ }
+ for (const char* name : kUnsafeNames) {
+ base::FilePath file_path = dir_.GetPath().AppendASCII(name);
+ bool success = base::WriteFile(file_path, "data");
+#if !defined(OS_WIN)
+ // Some of the unsafe names are not legal file names on Windows. This is
+ // okay, and doesn't materially effect the outcome of the test, so just
+ // ignore any failures writing these files to disk.
+ EXPECT_TRUE(success) << "Failed to create file " << file_path;
+#else
+ ignore_result(success);
+#endif
+ }
+
+ std::vector<blink::mojom::NativeFileSystemEntryPtr> entries;
+ base::RunLoop loop;
+ mojo::PendingRemote<blink::mojom::NativeFileSystemDirectoryEntriesListener>
+ listener;
+ mojo::MakeSelfOwnedReceiver(
+ std::make_unique<TestNativeFileSystemDirectoryEntriesListener>(
+ &entries, loop.QuitClosure()),
+ listener.InitWithNewPipeAndPassReceiver());
+ handle_->GetEntries(std::move(listener));
+ loop.Run();
+
+ std::vector<std::string> names;
+ for (const auto& entry : entries) {
+ names.push_back(entry->name);
+ }
+ EXPECT_THAT(names, testing::UnorderedElementsAreArray(kSafeNames));
+}
+
+} // namespace content
diff --git a/content/browser/native_file_system/native_file_system_file_handle_impl_unittest.cc b/content/browser/native_file_system/native_file_system_file_handle_impl_unittest.cc
index 2cb03f2ad023f90a5f494492becb615fa7c6ddcf..98a794e3426c0c6df1ea1513fb1dff31f47e4227 100644
--- a/content/browser/native_file_system/native_file_system_file_handle_impl_unittest.cc
+++ b/content/browser/native_file_system/native_file_system_file_handle_impl_unittest.cc
@@ -30,8 +30,6 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
-using storage::FileSystemURL;
-
namespace content {
using blink::mojom::PermissionStatus;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 6ac9a2997b4071333fbb056a4b0f1d680578bf61..ff01656c305107fba856b39b7f0f955a24dc43a1 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1796,6 +1796,7 @@ test("content_unittests") {
"../browser/media/webaudio/audio_context_manager_impl_unittest.cc",
"../browser/memory/swap_metrics_driver_impl_unittest.cc",
"../browser/native_file_system/file_system_chooser_unittest.cc",
+ "../browser/native_file_system/native_file_system_directory_handle_impl_unittest.cc",
"../browser/native_file_system/native_file_system_file_handle_impl_unittest.cc",
"../browser/native_file_system/native_file_system_file_writer_impl_unittest.cc",
"../browser/native_file_system/native_file_system_handle_base_unittest.cc",

View File

@@ -0,0 +1,140 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Min Qin <qinmin@chromium.org>
Date: Fri, 12 Feb 2021 22:45:08 +0000
Subject: Stop using raw WebContents ptr in DragDownloadFile
BUG=1172192
(cherry picked from commit 99dc876a13df19f3512bcfb97e794ab5d1b28905)
Change-Id: Ie029713553ff88c1e271db1c84396e1ddda19286
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2666189
Reviewed-by: Xing Liu <xingliu@chromium.org>
Commit-Queue: Min Qin <qinmin@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#849692}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2692927
Reviewed-by: Shakti Sahu <shaktisahu@chromium.org>
Cr-Commit-Position: refs/branch-heads/4324@{#2200}
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
diff --git a/content/browser/download/drag_download_file.cc b/content/browser/download/drag_download_file.cc
index 05c110adcbdebd67adc58a5e17b46dbd50ccc220..5dc8fe2214f6b5ef16445196e54ccb668c9fb5ef 100644
--- a/content/browser/download/drag_download_file.cc
+++ b/content/browser/download/drag_download_file.cc
@@ -37,15 +37,17 @@ class DragDownloadFile::DragDownloadFileUI
DragDownloadFileUI(const GURL& url,
const Referrer& referrer,
const std::string& referrer_encoding,
- WebContents* web_contents,
+ int render_process_id,
+ int render_frame_id,
OnCompleted on_completed)
: on_completed_(std::move(on_completed)),
url_(url),
referrer_(referrer),
referrer_encoding_(referrer_encoding),
- web_contents_(web_contents) {
+ render_process_id_(render_process_id),
+ render_frame_id_(render_frame_id) {
DCHECK(on_completed_);
- DCHECK(web_contents_);
+ DCHECK_GE(render_frame_id_, 0);
// May be called on any thread.
// Do not call weak_ptr_factory_.GetWeakPtr() outside the UI thread.
}
@@ -54,6 +56,10 @@ class DragDownloadFile::DragDownloadFileUI
const base::FilePath& file_path) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RenderFrameHost* host =
+ RenderFrameHost::FromID(render_process_id_, render_frame_id_);
+ if (!host)
+ return;
// TODO(https://crbug.com/614134) This should use the frame actually
// containing the link being dragged rather than the main frame of the tab.
net::NetworkTrafficAnnotationTag traffic_annotation =
@@ -79,9 +85,9 @@ class DragDownloadFile::DragDownloadFileUI
}
}
})");
- std::unique_ptr<download::DownloadUrlParameters> params(
- DownloadRequestUtils::CreateDownloadForWebContentsMainFrame(
- web_contents_, url_, traffic_annotation));
+ auto params = std::make_unique<download::DownloadUrlParameters>(
+ url_, render_process_id_, host->GetRenderViewHost()->GetRoutingID(),
+ render_frame_id_, traffic_annotation);
params->set_referrer(referrer_.url);
params->set_referrer_policy(
Referrer::ReferrerPolicyForUrlRequest(referrer_.policy));
@@ -91,7 +97,7 @@ class DragDownloadFile::DragDownloadFileUI
params->set_file_path(file_path);
params->set_file(std::move(file)); // Nulls file.
params->set_download_source(download::DownloadSource::DRAG_AND_DROP);
- BrowserContext::GetDownloadManager(web_contents_->GetBrowserContext())
+ BrowserContext::GetDownloadManager(host->GetBrowserContext())
->DownloadUrl(std::move(params));
}
@@ -165,7 +171,8 @@ class DragDownloadFile::DragDownloadFileUI
GURL url_;
Referrer referrer_;
std::string referrer_encoding_;
- WebContents* web_contents_;
+ int render_process_id_;
+ int render_frame_id_;
download::DownloadItem* download_item_ = nullptr;
// Only used in the callback from DownloadManager::DownloadUrl().
@@ -182,8 +189,10 @@ DragDownloadFile::DragDownloadFile(const base::FilePath& file_path,
WebContents* web_contents)
: file_path_(file_path), file_(std::move(file)) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RenderFrameHost* host = web_contents->GetMainFrame();
drag_ui_ = new DragDownloadFileUI(
- url, referrer, referrer_encoding, web_contents,
+ url, referrer, referrer_encoding, host->GetProcess()->GetID(),
+ host->GetRoutingID(),
base::BindOnce(&DragDownloadFile::DownloadCompleted,
weak_ptr_factory_.GetWeakPtr()));
DCHECK(!file_path_.empty());
diff --git a/content/browser/download/drag_download_file_browsertest.cc b/content/browser/download/drag_download_file_browsertest.cc
index 800891a6df4f0d79f1dd0a9cf89b47b882d0f3de..88e248e49898ef55eff694d0979e01bbe69aa2f6 100644
--- a/content/browser/download/drag_download_file_browsertest.cc
+++ b/content/browser/download/drag_download_file_browsertest.cc
@@ -21,6 +21,7 @@
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
+#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_browser_context.h"
#include "content/shell/browser/shell_download_manager_delegate.h"
@@ -129,6 +130,28 @@ IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_Complete) {
RunUntilSucceed();
}
+IN_PROC_BROWSER_TEST_F(DragDownloadFileTest, DragDownloadFileTest_ClosePage) {
+ base::FilePath name(
+ downloads_directory().AppendASCII("DragDownloadFileTest_Complete.txt"));
+ GURL url = embedded_test_server()->GetURL("/download/download-test.lib");
+ Referrer referrer;
+ std::string referrer_encoding;
+ auto file = std::make_unique<DragDownloadFile>(name, base::File(), url,
+ referrer, referrer_encoding,
+ shell()->web_contents());
+ scoped_refptr<MockDownloadFileObserver> observer(
+ new MockDownloadFileObserver());
+ ON_CALL(*observer.get(), OnDownloadAborted())
+ .WillByDefault(InvokeWithoutArgs(this, &DragDownloadFileTest::FailFast));
+ DownloadManager* manager = BrowserContext::GetDownloadManager(
+ shell()->web_contents()->GetBrowserContext());
+ file->Start(observer.get());
+ shell()->web_contents()->Close();
+ RunAllTasksUntilIdle();
+ std::vector<download::DownloadItem*> downloads;
+ manager->GetAllDownloads(&downloads);
+ ASSERT_EQ(0u, downloads.size());
+}
// TODO(benjhayden): Test Stop().
} // namespace content

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

@@ -0,0 +1,951 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jana Grill <janagrill@google.com>
Date: Thu, 15 Apr 2021 19:35:42 +0000
Subject: Use IDType for permission change subscriptions.
(cherry picked from commit ad1489b7c3ed705fc623cdffdc292324be9fcbfa)
Bug: 1025683
Change-Id: I3b44ba7833138e8a657a4192e1a36c978695db32
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2791431
Reviewed-by: Richard Coles <torne@chromium.org>
Reviewed-by: Yuchen Liu <yucliu@chromium.org>
Reviewed-by: Nasko Oskov <nasko@chromium.org>
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Reviewed-by: Fabrice de Gans-Riberi <fdegans@chromium.org>
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
Reviewed-by: Illia Klimov <elklm@google.com>
Auto-Submit: Balazs Engedy <engedy@chromium.org>
Commit-Queue: Balazs Engedy <engedy@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#867999}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2817980
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
Owners-Override: Achuith Bhandarkar <achuith@chromium.org>
Cr-Commit-Position: refs/branch-heads/4240@{#1607}
Cr-Branched-From: f297677702651916bbf65e59c0d4bbd4ce57d1ee-refs/heads/master@{#800218}
diff --git a/android_webview/browser/aw_permission_manager.cc b/android_webview/browser/aw_permission_manager.cc
index bedb16b046d45b257e28e29e410afe43f5c8817c..c020e9668cbd2de9d36d2e160a07e324a2510d6b 100644
--- a/android_webview/browser/aw_permission_manager.cc
+++ b/android_webview/browser/aw_permission_manager.cc
@@ -469,16 +469,17 @@ PermissionStatus AwPermissionManager::GetPermissionStatusForFrame(
.GetOrigin());
}
-int AwPermissionManager::SubscribePermissionStatusChange(
+AwPermissionManager::SubscriptionId
+AwPermissionManager::SubscribePermissionStatusChange(
PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(PermissionStatus)> callback) {
- return content::PermissionController::kNoPendingOperation;
+ return SubscriptionId();
}
void AwPermissionManager::UnsubscribePermissionStatusChange(
- int subscription_id) {}
+ SubscriptionId subscription_id) {}
void AwPermissionManager::CancelPermissionRequest(int request_id) {
PendingRequest* pending_request = pending_requests_.Lookup(request_id);
diff --git a/android_webview/browser/aw_permission_manager.h b/android_webview/browser/aw_permission_manager.h
index d9670cac33b84016568e9693b62e83c5e7ee0969..7439e78199783b8ebe2c303ebebf0e1cf62dc718 100644
--- a/android_webview/browser/aw_permission_manager.h
+++ b/android_webview/browser/aw_permission_manager.h
@@ -49,13 +49,14 @@ class AwPermissionManager : public content::PermissionControllerDelegate {
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin) override;
- int SubscribePermissionStatusChange(
+ SubscriptionId SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
override;
- void UnsubscribePermissionStatusChange(int subscription_id) override;
+ void UnsubscribePermissionStatusChange(
+ SubscriptionId subscription_id) override;
protected:
void CancelPermissionRequest(int request_id);
diff --git a/chrome/browser/permissions/permission_manager_browsertest.cc b/chrome/browser/permissions/permission_manager_browsertest.cc
index 440203ce6eca40070e09eae8bafe2a50bea75060..d48e6d85611b2ea4560f56d5e09fafa3a3453e7a 100644
--- a/chrome/browser/permissions/permission_manager_browsertest.cc
+++ b/chrome/browser/permissions/permission_manager_browsertest.cc
@@ -49,13 +49,13 @@ class SubscriptionInterceptingPermissionManager
callback_ = std::move(callback);
}
- int SubscribePermissionStatusChange(
+ SubscriptionId SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
override {
- int result =
+ SubscriptionId result =
permissions::PermissionManager::SubscribePermissionStatusChange(
permission, render_frame_host, requesting_origin, callback);
std::move(callback_).Run();
diff --git a/chromecast/browser/cast_permission_manager.cc b/chromecast/browser/cast_permission_manager.cc
index b358fc3bdb5c6af93a1e6568a667049574367741..b3a226dabff062e591fee38682409dec5e38a213 100644
--- a/chromecast/browser/cast_permission_manager.cc
+++ b/chromecast/browser/cast_permission_manager.cc
@@ -63,17 +63,17 @@ CastPermissionManager::GetPermissionStatusForFrame(
return blink::mojom::PermissionStatus::GRANTED;
}
-int CastPermissionManager::SubscribePermissionStatusChange(
+CastPermissionManager::SubscriptionId
+CastPermissionManager::SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
- return content::PermissionController::kNoPendingOperation;
+ return SubscriptionId();
}
void CastPermissionManager::UnsubscribePermissionStatusChange(
- int subscription_id) {
-}
+ SubscriptionId subscription_id) {}
} // namespace shell
} // namespace chromecast
diff --git a/chromecast/browser/cast_permission_manager.h b/chromecast/browser/cast_permission_manager.h
index 564ac2b304596027cf7096892dfaf9796500419c..f9da64c6110307cf9912e897f87fcbb2ca123d75 100644
--- a/chromecast/browser/cast_permission_manager.h
+++ b/chromecast/browser/cast_permission_manager.h
@@ -43,13 +43,14 @@ class CastPermissionManager : public content::PermissionControllerDelegate {
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin) override;
- int SubscribePermissionStatusChange(
+ SubscriptionId SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
override;
- void UnsubscribePermissionStatusChange(int subscription_id) override;
+ void UnsubscribePermissionStatusChange(
+ SubscriptionId subscription_id) override;
private:
DISALLOW_COPY_AND_ASSIGN(CastPermissionManager);
diff --git a/components/permissions/permission_manager.cc b/components/permissions/permission_manager.cc
index a9566441647f0e8527a6b9603f663f66e49b2abb..bdf639f49a987eb2d7ae31346dc01b85dac57eaa 100644
--- a/components/permissions/permission_manager.cc
+++ b/components/permissions/permission_manager.cc
@@ -542,14 +542,15 @@ bool PermissionManager::IsPermissionOverridableByDevTools(
origin->GetURL());
}
-int PermissionManager::SubscribePermissionStatusChange(
+PermissionManager::SubscriptionId
+PermissionManager::SubscribePermissionStatusChange(
PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(PermissionStatus)> callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (is_shutting_down_)
- return 0;
+ return SubscriptionId();
if (subscriptions_.IsEmpty())
PermissionsClient::Get()
@@ -586,16 +587,20 @@ int PermissionManager::SubscribePermissionStatusChange(
subscription->callback =
base::BindRepeating(&SubscriptionCallbackWrapper, std::move(callback));
- return subscriptions_.Add(std::move(subscription));
+ auto id = subscription_id_generator_.GenerateNextId();
+ subscriptions_.AddWithID(std::move(subscription), id);
+ return id;
}
-void PermissionManager::UnsubscribePermissionStatusChange(int subscription_id) {
+void PermissionManager::UnsubscribePermissionStatusChange(
+ SubscriptionId subscription_id) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (is_shutting_down_)
return;
- // Whether |subscription_id| is known will be checked by the Remove() call.
- subscriptions_.Remove(subscription_id);
+ if (subscriptions_.Lookup(subscription_id)) {
+ subscriptions_.Remove(subscription_id);
+ }
if (subscriptions_.IsEmpty()) {
PermissionsClient::Get()
diff --git a/components/permissions/permission_manager.h b/components/permissions/permission_manager.h
index d11fb4b2c4a1a360ae01154995091439e13bd9a0..19d29dde0392adff318e82bd1c3091c4e1dcd926 100644
--- a/components/permissions/permission_manager.h
+++ b/components/permissions/permission_manager.h
@@ -114,13 +114,14 @@ class PermissionManager : public KeyedService,
bool IsPermissionOverridableByDevTools(
content::PermissionType permission,
const base::Optional<url::Origin>& origin) override;
- int SubscribePermissionStatusChange(
+ SubscriptionId SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
override;
- void UnsubscribePermissionStatusChange(int subscription_id) override;
+ void UnsubscribePermissionStatusChange(
+ SubscriptionId subscription_id) override;
// TODO(raymes): Rather than exposing this, use the denial reason from
// GetPermissionStatus in callers to determine whether a permission is
@@ -153,7 +154,8 @@ class PermissionManager : public KeyedService,
class PermissionResponseCallback;
struct Subscription;
- using SubscriptionsMap = base::IDMap<std::unique_ptr<Subscription>>;
+ using SubscriptionsMap =
+ base::IDMap<std::unique_ptr<Subscription>, SubscriptionId>;
PermissionContextBase* GetPermissionContext(ContentSettingsType type);
@@ -186,6 +188,7 @@ class PermissionManager : public KeyedService,
content::BrowserContext* browser_context_;
PendingRequestsMap pending_requests_;
SubscriptionsMap subscriptions_;
+ SubscriptionId::Generator subscription_id_generator_;
PermissionContextMap permission_contexts_;
using ContentSettingsTypeOverrides =
diff --git a/components/permissions/permission_manager_unittest.cc b/components/permissions/permission_manager_unittest.cc
index ff5793acc907134fc486fcd5b9c20bf0cf2d960c..0070768b4a41e2890b89aba817fe24f6268272c1 100644
--- a/components/permissions/permission_manager_unittest.cc
+++ b/components/permissions/permission_manager_unittest.cc
@@ -325,7 +325,7 @@ TEST_F(PermissionManagerTest, SubscriptionDestroyedCleanlyWithoutUnsubscribe) {
}
TEST_F(PermissionManagerTest, SubscribeUnsubscribeAfterShutdown) {
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -340,7 +340,7 @@ TEST_F(PermissionManagerTest, SubscribeUnsubscribeAfterShutdown) {
subscription_id);
// Check that subscribe/unsubscribe after shutdown don't crash.
- int subscription2_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription2_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -351,7 +351,7 @@ TEST_F(PermissionManagerTest, SubscribeUnsubscribeAfterShutdown) {
}
TEST_F(PermissionManagerTest, SameTypeChangeNotifies) {
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -369,7 +369,7 @@ TEST_F(PermissionManagerTest, SameTypeChangeNotifies) {
}
TEST_F(PermissionManagerTest, DifferentTypeChangeDoesNotNotify) {
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -386,7 +386,7 @@ TEST_F(PermissionManagerTest, DifferentTypeChangeDoesNotNotify) {
}
TEST_F(PermissionManagerTest, ChangeAfterUnsubscribeDoesNotNotify) {
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -403,7 +403,7 @@ TEST_F(PermissionManagerTest, ChangeAfterUnsubscribeDoesNotNotify) {
}
TEST_F(PermissionManagerTest, DifferentPrimaryUrlDoesNotNotify) {
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -420,7 +420,7 @@ TEST_F(PermissionManagerTest, DifferentPrimaryUrlDoesNotNotify) {
}
TEST_F(PermissionManagerTest, DifferentSecondaryUrlDoesNotNotify) {
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -437,7 +437,7 @@ TEST_F(PermissionManagerTest, DifferentSecondaryUrlDoesNotNotify) {
}
TEST_F(PermissionManagerTest, WildCardPatternNotifies) {
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -458,7 +458,7 @@ TEST_F(PermissionManagerTest, ClearSettingsNotifies) {
url(), url(), ContentSettingsType::GEOLOCATION, std::string(),
CONTENT_SETTING_ALLOW);
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -475,7 +475,7 @@ TEST_F(PermissionManagerTest, ClearSettingsNotifies) {
}
TEST_F(PermissionManagerTest, NewValueCorrectlyPassed) {
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -497,7 +497,7 @@ TEST_F(PermissionManagerTest, ChangeWithoutPermissionChangeDoesNotNotify) {
url(), url(), ContentSettingsType::GEOLOCATION, std::string(),
CONTENT_SETTING_ALLOW);
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -518,7 +518,7 @@ TEST_F(PermissionManagerTest, ChangesBackAndForth) {
url(), url(), ContentSettingsType::GEOLOCATION, std::string(),
CONTENT_SETTING_ASK);
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -549,7 +549,7 @@ TEST_F(PermissionManagerTest, ChangesBackAndForthWorker) {
url(), url(), ContentSettingsType::GEOLOCATION, std::string(),
CONTENT_SETTING_ASK);
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, nullptr, url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -576,7 +576,7 @@ TEST_F(PermissionManagerTest, ChangesBackAndForthWorker) {
}
TEST_F(PermissionManagerTest, SubscribeMIDIPermission) {
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::MIDI, main_rfh(), url(),
base::Bind(&PermissionManagerTest::OnPermissionChange,
@@ -796,7 +796,7 @@ TEST_F(PermissionManagerTest, SubscribeWithPermissionDelegation) {
content::RenderFrameHost* parent = main_rfh();
content::RenderFrameHost* child = AddChildRFH(parent, kOrigin2);
- int subscription_id =
+ content::PermissionControllerDelegate::SubscriptionId subscription_id =
GetPermissionControllerDelegate()->SubscribePermissionStatusChange(
PermissionType::GEOLOCATION, child, GURL(kOrigin2),
base::Bind(&PermissionManagerTest::OnPermissionChange,
diff --git a/content/browser/android/nfc_host.cc b/content/browser/android/nfc_host.cc
index 30517f69b3d790690121bda2f3de50c0e31fadd1..0f077d211a23d05813dafd7dc621915c1fb79ba5 100644
--- a/content/browser/android/nfc_host.cc
+++ b/content/browser/android/nfc_host.cc
@@ -99,8 +99,8 @@ void NFCHost::OnPermissionStatusChange(blink::mojom::PermissionStatus status) {
void NFCHost::Close() {
nfc_provider_.reset();
- if (subscription_id_ != 0)
- permission_controller_->UnsubscribePermissionStatusChange(subscription_id_);
+ permission_controller_->UnsubscribePermissionStatusChange(subscription_id_);
+ subscription_id_ = PermissionController::SubscriptionId();
}
} // namespace content
diff --git a/content/browser/android/nfc_host.h b/content/browser/android/nfc_host.h
index 8df7cbec810ecb535f4ce4b54266c34243341571..6b5f8dde17d0abda6132845018b4a8f81859cd0d 100644
--- a/content/browser/android/nfc_host.h
+++ b/content/browser/android/nfc_host.h
@@ -44,7 +44,7 @@ class NFCHost : public WebContentsObserver {
mojo::Remote<device::mojom::NFCProvider> nfc_provider_;
// Permission change subscription ID provided by |permission_controller_|.
- int subscription_id_ = 0;
+ PermissionController::SubscriptionId subscription_id_;
DISALLOW_COPY_AND_ASSIGN(NFCHost);
};
diff --git a/content/browser/permissions/permission_controller_impl.cc b/content/browser/permissions/permission_controller_impl.cc
index c6edd2ebec0b57808512c3b6c574548431efac7e..4722e9d7b3ed77489fa28f97afa55726f7f727e4 100644
--- a/content/browser/permissions/permission_controller_impl.cc
+++ b/content/browser/permissions/permission_controller_impl.cc
@@ -132,7 +132,8 @@ struct PermissionControllerImpl::Subscription {
int render_frame_id = -1;
int render_process_id = -1;
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback;
- int delegate_subscription_id;
+ // This is default-initialized to an invalid ID.
+ PermissionControllerDelegate::SubscriptionId delegate_subscription_id;
};
PermissionControllerImpl::~PermissionControllerImpl() {
@@ -388,7 +389,8 @@ void PermissionControllerImpl::OnDelegatePermissionStatusChange(
subscription->callback.Run(status);
}
-int PermissionControllerImpl::SubscribePermissionStatusChange(
+PermissionControllerImpl::SubscriptionId
+PermissionControllerImpl::SubscribePermissionStatusChange(
PermissionType permission,
RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
@@ -422,21 +424,21 @@ int PermissionControllerImpl::SubscribePermissionStatusChange(
base::BindRepeating(
&PermissionControllerImpl::OnDelegatePermissionStatusChange,
base::Unretained(this), subscription.get()));
- } else {
- subscription->delegate_subscription_id = kNoPendingOperation;
}
- return subscriptions_.Add(std::move(subscription));
+
+ auto id = subscription_id_generator_.GenerateNextId();
+ subscriptions_.AddWithID(std::move(subscription), id);
+ return id;
}
void PermissionControllerImpl::UnsubscribePermissionStatusChange(
- int subscription_id) {
+ SubscriptionId subscription_id) {
Subscription* subscription = subscriptions_.Lookup(subscription_id);
if (!subscription)
return;
PermissionControllerDelegate* delegate =
browser_context_->GetPermissionControllerDelegate();
- if (delegate &&
- subscription->delegate_subscription_id != kNoPendingOperation) {
+ if (delegate) {
delegate->UnsubscribePermissionStatusChange(
subscription->delegate_subscription_id);
}
diff --git a/content/browser/permissions/permission_controller_impl.h b/content/browser/permissions/permission_controller_impl.h
index 7ebf3c48a0e863d9f4312b37e014ce0f89e5c3c7..d85788867f746547f80405c46660e055631d9208 100644
--- a/content/browser/permissions/permission_controller_impl.h
+++ b/content/browser/permissions/permission_controller_impl.h
@@ -72,18 +72,19 @@ class CONTENT_EXPORT PermissionControllerImpl : public PermissionController {
const GURL& requesting_origin,
const GURL& embedding_origin);
- int SubscribePermissionStatusChange(
+ SubscriptionId SubscribePermissionStatusChange(
PermissionType permission,
RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
const base::RepeatingCallback<void(blink::mojom::PermissionStatus)>&
callback);
- void UnsubscribePermissionStatusChange(int subscription_id);
+ void UnsubscribePermissionStatusChange(SubscriptionId subscription_id);
private:
struct Subscription;
- using SubscriptionsMap = base::IDMap<std::unique_ptr<Subscription>>;
+ using SubscriptionsMap =
+ base::IDMap<std::unique_ptr<Subscription>, SubscriptionId>;
using SubscriptionsStatusMap =
base::flat_map<SubscriptionsMap::KeyType, blink::mojom::PermissionStatus>;
@@ -98,7 +99,13 @@ class CONTENT_EXPORT PermissionControllerImpl : public PermissionController {
const base::Optional<url::Origin>& origin);
DevToolsPermissionOverrides devtools_permission_overrides_;
+
+ // Note that SubscriptionId is distinct from
+ // PermissionControllerDelegate::SubscriptionId, and the concrete ID values
+ // may be different as well.
SubscriptionsMap subscriptions_;
+ SubscriptionId::Generator subscription_id_generator_;
+
BrowserContext* browser_context_;
DISALLOW_COPY_AND_ASSIGN(PermissionControllerImpl);
diff --git a/content/browser/permissions/permission_service_context.cc b/content/browser/permissions/permission_service_context.cc
index c3ab81294edbb297108c3b8f59a35f1cfb8131f9..f15abf265eb690b5dfd66bb1c2d5e13b005ddbd0 100644
--- a/content/browser/permissions/permission_service_context.cc
+++ b/content/browser/permissions/permission_service_context.cc
@@ -11,7 +11,6 @@
#include "content/browser/permissions/permission_service_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_handle.h"
-#include "content/public/browser/permission_controller.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
@@ -32,7 +31,7 @@ class PermissionServiceContext::PermissionSubscription {
PermissionSubscription& operator=(const PermissionSubscription&) = delete;
~PermissionSubscription() {
- DCHECK_NE(id_, 0);
+ DCHECK(id_);
BrowserContext* browser_context = context_->GetBrowserContext();
if (browser_context) {
PermissionControllerImpl::FromBrowserContext(browser_context)
@@ -41,7 +40,7 @@ class PermissionServiceContext::PermissionSubscription {
}
void OnConnectionError() {
- DCHECK_NE(id_, 0);
+ DCHECK(id_);
context_->ObserverHadConnectionError(id_);
}
@@ -49,12 +48,12 @@ class PermissionServiceContext::PermissionSubscription {
observer_->OnPermissionStatusChange(status);
}
- void set_id(int id) { id_ = id; }
+ void set_id(PermissionController::SubscriptionId id) { id_ = id; }
private:
PermissionServiceContext* const context_;
mojo::Remote<blink::mojom::PermissionObserver> observer_;
- int id_ = 0;
+ PermissionController::SubscriptionId id_;
};
PermissionServiceContext::PermissionServiceContext(
@@ -108,7 +107,7 @@ void PermissionServiceContext::CreateSubscription(
}
GURL requesting_origin(origin.Serialize());
- int subscription_id =
+ auto subscription_id =
PermissionControllerImpl::FromBrowserContext(browser_context)
->SubscribePermissionStatusChange(
permission_type, render_frame_host_, requesting_origin,
@@ -119,7 +118,8 @@ void PermissionServiceContext::CreateSubscription(
subscriptions_[subscription_id] = std::move(subscription);
}
-void PermissionServiceContext::ObserverHadConnectionError(int subscription_id) {
+void PermissionServiceContext::ObserverHadConnectionError(
+ PermissionController::SubscriptionId subscription_id) {
size_t erased = subscriptions_.erase(subscription_id);
DCHECK_EQ(1u, erased);
}
diff --git a/content/browser/permissions/permission_service_context.h b/content/browser/permissions/permission_service_context.h
index 4f93be504fd854b50bea96dedbc5d324d25ea6f1..0680c70c8ee4a79bb85c2fd1e3769a29f339816e 100644
--- a/content/browser/permissions/permission_service_context.h
+++ b/content/browser/permissions/permission_service_context.h
@@ -9,6 +9,7 @@
#include <unordered_map>
#include "content/common/content_export.h"
+#include "content/public/browser/permission_controller.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/web_contents_observer.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -52,7 +53,8 @@ class CONTENT_EXPORT PermissionServiceContext : public WebContentsObserver {
mojo::PendingRemote<blink::mojom::PermissionObserver> observer);
// Called when the connection to a PermissionObserver has an error.
- void ObserverHadConnectionError(int subscription_id);
+ void ObserverHadConnectionError(
+ PermissionController::SubscriptionId subscription_id);
// May return nullptr during teardown, or when showing an interstitial.
BrowserContext* GetBrowserContext() const;
@@ -78,7 +80,8 @@ class CONTENT_EXPORT PermissionServiceContext : public WebContentsObserver {
RenderFrameHost* const render_frame_host_;
RenderProcessHost* const render_process_host_;
mojo::UniqueReceiverSet<blink::mojom::PermissionService> services_;
- std::unordered_map<int, std::unique_ptr<PermissionSubscription>>
+ std::unordered_map<PermissionController::SubscriptionId,
+ std::unique_ptr<PermissionSubscription>>
subscriptions_;
};
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h
index 4468b5c906454a8cf4484c8f3f81841c9130721b..677f7a5fe22b55f12c324048972a7200ac8c873b 100644
--- a/content/browser/renderer_host/media/media_stream_manager.h
+++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -50,6 +50,7 @@
#include "content/public/browser/desktop_media_id.h"
#include "content/public/browser/media_request_state.h"
#include "content/public/browser/media_stream_request.h"
+#include "content/public/browser/permission_controller.h"
#include "media/base/video_facing.h"
#include "third_party/blink/public/common/mediastream/media_devices.h"
#include "third_party/blink/public/common/mediastream/media_stream_controls.h"
diff --git a/content/public/browser/permission_controller.h b/content/public/browser/permission_controller.h
index b9b42def49b35d31c22ee0d6c158737bdc0824b6..77fe96a1c33aea5e887e171b92f199acdf7dd6df 100644
--- a/content/public/browser/permission_controller.h
+++ b/content/public/browser/permission_controller.h
@@ -6,6 +6,7 @@
#define CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_H_
#include "base/supports_user_data.h"
+#include "base/util/type_safety/id_type.h"
#include "content/common/content_export.h"
#include "content/public/browser/permission_type.h"
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
@@ -20,8 +21,13 @@ class RenderFrameHost;
class CONTENT_EXPORT PermissionController
: public base::SupportsUserData::Data {
public:
- // Constant retured when registering and subscribing if
- // cancelling/unsubscribing at a later stage would have no effect.
+ // Identifier for an active subscription. This is intentionally a distinct
+ // type from PermissionControllerDelegate::SubscriptionId as the concrete
+ // identifier values may be different.
+ using SubscriptionId = util::IdType64<PermissionController>;
+
+ // Constant returned when requesting a permission if cancelling at a later
+ // stage would have no effect.
static const int kNoPendingOperation = -1;
~PermissionController() override {}
@@ -48,4 +54,17 @@ class CONTENT_EXPORT PermissionController
} // namespace content
+namespace std {
+
+template <>
+struct hash<content::PermissionController::SubscriptionId> {
+ std::size_t operator()(
+ const content::PermissionController::SubscriptionId& v) const {
+ content::PermissionController::SubscriptionId::Hasher hasher;
+ return hasher(v);
+ }
+};
+
+} // namespace std
+
#endif // CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_H_
diff --git a/content/public/browser/permission_controller_delegate.h b/content/public/browser/permission_controller_delegate.h
index e47de2a278e67091442c63bb7130022eae587041..82a1d4f0efd384386d8215f39d735ba488e4bc61 100644
--- a/content/public/browser/permission_controller_delegate.h
+++ b/content/public/browser/permission_controller_delegate.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_DELEGATE_H_
#define CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_DELEGATE_H_
+#include "base/util/type_safety/id_type.h"
#include "content/common/content_export.h"
#include "content/public/browser/devtools_permission_overrides.h"
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
@@ -18,6 +19,10 @@ class RenderFrameHost;
class CONTENT_EXPORT PermissionControllerDelegate {
public:
using PermissionOverrides = DevToolsPermissionOverrides::PermissionOverrides;
+
+ // Identifier for an active subscription.
+ using SubscriptionId = util::IdType64<PermissionControllerDelegate>;
+
virtual ~PermissionControllerDelegate() = default;
// Requests a permission on behalf of a frame identified by
@@ -80,21 +85,21 @@ class CONTENT_EXPORT PermissionControllerDelegate {
// Runs the given |callback| whenever the |permission| associated with the
// given RenderFrameHost changes. A nullptr should be passed if the request
- // is from a worker. Returns the subscription_id to be used to unsubscribe.
- // Can be kNoPendingOperation if the subscribe was not successful.
- virtual int SubscribePermissionStatusChange(
+ // is from a worker. Returns the ID to be used to unsubscribe, which can be
+ // `is_null()` if the subscribe was not successful.
+ virtual SubscriptionId SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)>
callback) = 0;
- // Unregisters from permission status change notifications.
- // The |subscription_id| must match the value returned by the
- // SubscribePermissionStatusChange call. Unsubscribing
- // an already unsubscribed |subscription_id| or providing the
- // |subscription_id| kNoPendingOperation is a no-op.
- virtual void UnsubscribePermissionStatusChange(int subscription_id) = 0;
+ // Unregisters from permission status change notifications. The
+ // |subscription_id| must match the value returned by the
+ // SubscribePermissionStatusChange call. Unsubscribing an already
+ // unsubscribed |subscription_id| or an `is_null()` ID is a no-op.
+ virtual void UnsubscribePermissionStatusChange(
+ SubscriptionId subscription_id) = 0;
// Manually overrides default permission settings of delegate, if overrides
// are tracked by the delegate. This method should only be called by the
@@ -116,4 +121,17 @@ class CONTENT_EXPORT PermissionControllerDelegate {
} // namespace content
+namespace std {
+
+template <>
+struct hash<content::PermissionControllerDelegate::SubscriptionId> {
+ std::size_t operator()(
+ const content::PermissionControllerDelegate::SubscriptionId& v) const {
+ content::PermissionControllerDelegate::SubscriptionId::Hasher hasher;
+ return hasher(v);
+ }
+};
+
+} // namespace std
+
#endif // CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_DELEGATE_H_
diff --git a/content/public/test/mock_permission_manager.h b/content/public/test/mock_permission_manager.h
index a193bd00e23abf2295c8bcf2ed5fb3acae68440f..34e71e23a2dae6d55348d8139480459b36377c0c 100644
--- a/content/public/test/mock_permission_manager.h
+++ b/content/public/test/mock_permission_manager.h
@@ -49,13 +49,13 @@ class MockPermissionManager : public PermissionControllerDelegate {
void ResetPermission(PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) override {}
- int SubscribePermissionStatusChange(
+ SubscriptionId SubscribePermissionStatusChange(
PermissionType permission,
RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
override;
- void UnsubscribePermissionStatusChange(int subscription_id) override {}
+ void UnsubscribePermissionStatusChange(SubscriptionId subscription_id) override {}
private:
DISALLOW_COPY_AND_ASSIGN(MockPermissionManager);
diff --git a/content/shell/browser/shell_permission_manager.cc b/content/shell/browser/shell_permission_manager.cc
index d0396ea346f267a26a8d318d518be59a55b9311a..b302b378960e9cf2445e1e8983d05f6fc2c668b6 100644
--- a/content/shell/browser/shell_permission_manager.cc
+++ b/content/shell/browser/shell_permission_manager.cc
@@ -133,16 +133,16 @@ ShellPermissionManager::GetPermissionStatusForFrame(
.GetOrigin());
}
-int ShellPermissionManager::SubscribePermissionStatusChange(
+ShellPermissionManager::SubscriptionId
+ShellPermissionManager::SubscribePermissionStatusChange(
PermissionType permission,
RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
- return PermissionController::kNoPendingOperation;
+ return SubscriptionId();
}
void ShellPermissionManager::UnsubscribePermissionStatusChange(
- int subscription_id) {
-}
+ SubscriptionId subscription_id) {}
} // namespace content
diff --git a/content/shell/browser/shell_permission_manager.h b/content/shell/browser/shell_permission_manager.h
index 85477665a9dd643f50c4567c1133973bc258a94f..ecda464779c39df4a8b4b1726414cf2763033f53 100644
--- a/content/shell/browser/shell_permission_manager.h
+++ b/content/shell/browser/shell_permission_manager.h
@@ -42,13 +42,14 @@ class ShellPermissionManager : public PermissionControllerDelegate {
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin) override;
- int SubscribePermissionStatusChange(
+ SubscriptionId SubscribePermissionStatusChange(
PermissionType permission,
RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
override;
- void UnsubscribePermissionStatusChange(int subscription_id) override;
+ void UnsubscribePermissionStatusChange(
+ SubscriptionId subscription_id) override;
private:
DISALLOW_COPY_AND_ASSIGN(ShellPermissionManager);
diff --git a/content/shell/browser/web_test/web_test_permission_manager.cc b/content/shell/browser/web_test/web_test_permission_manager.cc
index 67f34deebcbf854692be497b1c31d8da72a5b03d..9c876335c3a2feee4f73d9f6f8e14d67f3988291 100644
--- a/content/shell/browser/web_test/web_test_permission_manager.cc
+++ b/content/shell/browser/web_test/web_test_permission_manager.cc
@@ -147,7 +147,8 @@ WebTestPermissionManager::GetPermissionStatusForFrame(
.GetOrigin());
}
-int WebTestPermissionManager::SubscribePermissionStatusChange(
+WebTestPermissionManager::SubscriptionId
+WebTestPermissionManager::SubscribePermissionStatusChange(
PermissionType permission,
RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
@@ -170,14 +171,18 @@ int WebTestPermissionManager::SubscribePermissionStatusChange(
GetPermissionStatus(permission, subscription->permission.origin,
subscription->permission.embedding_origin);
- return subscriptions_.Add(std::move(subscription));
+ auto id = subscription_id_generator_.GenerateNextId();
+ subscriptions_.AddWithID(std::move(subscription), id);
+ return id;
}
void WebTestPermissionManager::UnsubscribePermissionStatusChange(
- int subscription_id) {
+ SubscriptionId subscription_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // Whether |subscription_id| is known will be checked by the Remove() call.
+ if (!subscriptions_.Lookup(subscription_id))
+ return;
+
subscriptions_.Remove(subscription_id);
}
diff --git a/content/shell/browser/web_test/web_test_permission_manager.h b/content/shell/browser/web_test/web_test_permission_manager.h
index 1d15dbb9c7dda0b1e8642435d8a1e8f48af72e5c..46490c28fb013c2f5c8e75d7e7e24761f4498a58 100644
--- a/content/shell/browser/web_test/web_test_permission_manager.h
+++ b/content/shell/browser/web_test/web_test_permission_manager.h
@@ -52,13 +52,14 @@ class WebTestPermissionManager
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin) override;
- int SubscribePermissionStatusChange(
+ SubscriptionId SubscribePermissionStatusChange(
PermissionType permission,
RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
override;
- void UnsubscribePermissionStatusChange(int subscription_id) override;
+ void UnsubscribePermissionStatusChange(
+ SubscriptionId subscription_id) override;
void SetPermission(PermissionType permission,
blink::mojom::PermissionStatus status,
@@ -98,7 +99,8 @@ class WebTestPermissionManager
};
struct Subscription;
- using SubscriptionsMap = base::IDMap<std::unique_ptr<Subscription>>;
+ using SubscriptionsMap =
+ base::IDMap<std::unique_ptr<Subscription>, SubscriptionId>;
using PermissionsMap = std::unordered_map<PermissionDescription,
blink::mojom::PermissionStatus,
PermissionDescription::Hash>;
@@ -116,6 +118,7 @@ class WebTestPermissionManager
// List of subscribers currently listening to permission changes.
SubscriptionsMap subscriptions_;
+ SubscriptionId::Generator subscription_id_generator_;
mojo::ReceiverSet<blink::test::mojom::PermissionAutomation> receivers_;
diff --git a/fuchsia/engine/browser/web_engine_permission_delegate.cc b/fuchsia/engine/browser/web_engine_permission_delegate.cc
index 98592f05b6d56108119b106a42d839c28131a324..c18b8be7cdf73720cf02afce9ea75ab98d3f1f64 100644
--- a/fuchsia/engine/browser/web_engine_permission_delegate.cc
+++ b/fuchsia/engine/browser/web_engine_permission_delegate.cc
@@ -83,20 +83,21 @@ WebEnginePermissionDelegate::GetPermissionStatusForFrame(
permission, url::Origin::Create(requesting_origin));
}
-int WebEnginePermissionDelegate::SubscribePermissionStatusChange(
+WebEnginePermissionDelegate::SubscriptionId
+WebEnginePermissionDelegate::SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
// TODO(crbug.com/1063094): Implement permission status subscription. It's
// used in blink to emit PermissionStatus.onchange notifications.
- NOTIMPLEMENTED() << ": " << static_cast<int>(permission);
- return content::PermissionController::kNoPendingOperation;
+ NOTIMPLEMENTED_LOG_ONCE() << ": " << static_cast<int>(permission);
+ return SubscriptionId();
}
void WebEnginePermissionDelegate::UnsubscribePermissionStatusChange(
- int subscription_id) {
+ SubscriptionId subscription_id) {
// TODO(crbug.com/1063094): Implement permission status subscription. It's
// used in blink to emit PermissionStatus.onchange notifications.
- NOTREACHED();
+ NOTIMPLEMENTED_LOG_ONCE();
}
diff --git a/fuchsia/engine/browser/web_engine_permission_delegate.h b/fuchsia/engine/browser/web_engine_permission_delegate.h
index 036207b75d33b752981007a41aa51f3e64db4f0e..c39989b471c2a74ee1a9140e12f205866a0b7aff 100644
--- a/fuchsia/engine/browser/web_engine_permission_delegate.h
+++ b/fuchsia/engine/browser/web_engine_permission_delegate.h
@@ -45,13 +45,14 @@ class WebEnginePermissionDelegate
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin) override;
- int SubscribePermissionStatusChange(
+ SubscriptionId SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
override;
- void UnsubscribePermissionStatusChange(int subscription_id) override;
+ void UnsubscribePermissionStatusChange(
+ SubscriptionId subscription_id) override;
};
#endif // FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_PERMISSION_DELEGATE_H_
diff --git a/headless/lib/browser/headless_permission_manager.cc b/headless/lib/browser/headless_permission_manager.cc
index 5d4d609fc0c10e57ef3c6a730340dc409789dcdd..359ecdc4b72d560da830c51f23374150e6b30a2d 100644
--- a/headless/lib/browser/headless_permission_manager.cc
+++ b/headless/lib/browser/headless_permission_manager.cc
@@ -71,15 +71,16 @@ HeadlessPermissionManager::GetPermissionStatusForFrame(
return blink::mojom::PermissionStatus::ASK;
}
-int HeadlessPermissionManager::SubscribePermissionStatusChange(
+HeadlessPermissionManager::SubscriptionId
+HeadlessPermissionManager::SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback) {
- return content::PermissionController::kNoPendingOperation;
+ return SubscriptionId();
}
void HeadlessPermissionManager::UnsubscribePermissionStatusChange(
- int subscription_id) {}
+ SubscriptionId subscription_id) {}
} // namespace headless
diff --git a/headless/lib/browser/headless_permission_manager.h b/headless/lib/browser/headless_permission_manager.h
index 4b83309ab3ada17f7f2ac3323ba5f13ab76b9409..ac30670cb384a79457033a25c13da0c305b8eff2 100644
--- a/headless/lib/browser/headless_permission_manager.h
+++ b/headless/lib/browser/headless_permission_manager.h
@@ -46,13 +46,14 @@ class HeadlessPermissionManager : public content::PermissionControllerDelegate {
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin) override;
- int SubscribePermissionStatusChange(
+ SubscriptionId SubscribePermissionStatusChange(
content::PermissionType permission,
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::RepeatingCallback<void(blink::mojom::PermissionStatus)> callback)
override;
- void UnsubscribePermissionStatusChange(int subscription_id) override;
+ void UnsubscribePermissionStatusChange(
+ SubscriptionId subscription_id) override;
private:
content::BrowserContext* browser_context_;

View File

@@ -0,0 +1,92 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Adam Rice <ricea@chromium.org>
Date: Fri, 12 Feb 2021 10:43:43 +0000
Subject: WebSocket: Don't clear event queue on destruction
It's unnecessary to clear the event queue as it will be garbage
collected anyway. Stop doing it.
Also add a unit test for GC with pending events. This can only happen if
the execution context changes while the events are pending.
BUG=1170657
(cherry picked from commit 2dae20b0b3890af23852345a69158c99b47746aa)
(cherry picked from commit 171d6ee562c3cac850d9705e18745bb1214e5d83)
Change-Id: I01e5a687587f7471e88640c43f0dfe83e5c01bd1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2655089
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
Commit-Queue: Adam Rice <ricea@chromium.org>
Cr-Original-Original-Commit-Position: refs/heads/master@{#848065}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2660955
Reviewed-by: Adam Rice <ricea@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/4389@{#419}
Cr-Original-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2690730
Auto-Submit: Adam Rice <ricea@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4324@{#2191}
Cr-Branched-From: c73b5a651d37a6c4d0b8e3262cc4015a5579c6c8-refs/heads/master@{#827102}
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket.cc b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
index 0e9c87462e3bb2ea343abd3120c073f24e9b2d72..b823debc7d4732f304d8ec89f58e5127b4bc8074 100644
--- a/third_party/blink/renderer/modules/websockets/dom_websocket.cc
+++ b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
@@ -81,9 +81,7 @@ namespace blink {
DOMWebSocket::EventQueue::EventQueue(EventTarget* target)
: state_(kActive), target_(target) {}
-DOMWebSocket::EventQueue::~EventQueue() {
- ContextDestroyed();
-}
+DOMWebSocket::EventQueue::~EventQueue() = default;
void DOMWebSocket::EventQueue::Dispatch(Event* event) {
switch (state_) {
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc b/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
index 4c50ae0990b9a76128ffb59f547eb47789d2d693..370c1944dd6f8a094f2f30fa4f03d573b2f430e3 100644
--- a/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
+++ b/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/impl/thread_state.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -920,6 +921,32 @@ INSTANTIATE_TEST_SUITE_P(
DOMWebSocketInvalidClosingCodeTest,
testing::Values(0, 1, 998, 999, 1001, 2999, 5000, 9999, 65535));
+TEST(DOMWebSocketTest, GCWhileEventsPending) {
+ V8TestingScope scope;
+ {
+ DOMWebSocketTestScope websocket_scope(scope.GetExecutionContext());
+
+ EXPECT_CALL(websocket_scope.Channel(),
+ Connect(KURL("ws://example.com/"), String()))
+ .WillOnce(Return(true));
+ EXPECT_CALL(websocket_scope.Channel(), Disconnect());
+
+ auto& socket = websocket_scope.Socket();
+
+ // Cause events to be queued rather than fired.
+ socket.ContextLifecycleStateChanged(mojom::FrameLifecycleState::kPaused);
+
+ socket.Connect("ws://example.com/", Vector<String>(), ASSERT_NO_EXCEPTION);
+ socket.DidError();
+ socket.DidClose(DOMWebSocket::kClosingHandshakeIncomplete, 1006, "");
+
+ // Stop HasPendingActivity() from keeping the object alive.
+ socket.SetExecutionContext(nullptr);
+ }
+
+ ThreadState::Current()->CollectAllGarbageForTesting();
+}
+
} // namespace
} // namespace blink

View File

@@ -10,8 +10,12 @@
"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/angle": "src/third_party/angle",
"src/electron/patches/skia": "src/third_party/skia",
"src/electron/patches/icu": "src/third_party/icu"
}

1
patches/icu/.patches Normal file
View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -50,3 +50,4 @@ 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,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 =

3
patches/skia/.patches Normal file
View File

@@ -0,0 +1,3 @@
cherry-pick-6763a713f957.patch
cherry-pick-b0d3d3e85fa6.patch
skscalercontext_getimage_less_brittle.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

@@ -0,0 +1,158 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brian Salomon <bsalomon@google.com>
Date: Tue, 19 Jan 2021 10:28:15 -0500
Subject: Fix DrawEdgeAAQuad degenerate issue where 3D points don't correctly
project to 2D points.
Bug: chromium:1162942
Change-Id: Idc1dcb725ff9eae651b84de2fe792b188dcd1c1b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/354671
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
(cherry picked from commit 7656c4b7e89b4ff00480a6d7a8a19e3fd0e5c86e)
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/360376
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/gm/crbug_1162942.cpp b/gm/crbug_1162942.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e5d1f6360f3d68e1d3e353752e2e676928c93aef
--- /dev/null
+++ b/gm/crbug_1162942.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm/gm.h"
+#include "include/core/SkCanvas.h"
+#include "include/core/SkMatrix.h"
+#include "include/core/SkRect.h"
+
+// This tests a scenario where when the 2D projection of a perspective quad is inset we degenerate
+// the inset 2d geometry to a triangle because an inset vertex crosses the opposite edge. When we
+// project back to 3D and try to move the original verts along the original edges so that they
+// project to the 2D points. Whether an edge can be moved along depends on whether the adjacent edge
+// at the vertex is AA. However, in the degenerate triangle case the 2D point may not fall along
+// either of the edges. Thus, if we're constrained to moving along one edge and solve for X or Y the
+// other value may go wildly away from projecting to the 2D value. The current approach is to force
+// AA on at both edges that meet at a vertex whose inset point has been replaced by an off-edge
+// point if either is AA originally. This gives us an additional vector to move along so that we can
+// find a 3D point that projects to the 2D point in both X and Y.
+DEF_SIMPLE_GM(crbug_1162942, canvas, 620, 200) {
+ // Matrix and quad values taken from Chrome repro scenario.
+ SkMatrix ctm = SkMatrix::MakeAll(
+ SkBits2Float(0x3FCC7F75), SkBits2Float(0x3D5784FC), SkBits2Float(0x44C48C99),
+ SkBits2Float(0x3F699F7F), SkBits2Float(0x3E0A0D37), SkBits2Float(0x43908518),
+ SkBits2Float(0x3AA17423), SkBits2Float(0x3A6CCDC3), SkBits2Float(0x3F2EFEEC));
+ ctm.postTranslate(-1500.f, -325.f);
+
+ SkPoint pts[4] = {{SkBits2Float(0x3F39778B), SkBits2Float(0x43FF7FFC)},
+ {SkBits2Float(0x0), SkBits2Float(0x43FF7FFA)},
+ {SkBits2Float(0xB83B055E), SkBits2Float(0x42500003)},
+ {SkBits2Float(0x3F39776F), SkBits2Float(0x4250000D)}};
+ SkRect bounds;
+ bounds.setBounds(pts, 4);
+
+ canvas->clear(SK_ColorWHITE);
+
+ SkCanvas::QuadAAFlags flags[] = {
+ (SkCanvas::QuadAAFlags) (SkCanvas::kTop_QuadAAFlag | SkCanvas::kLeft_QuadAAFlag ),
+ (SkCanvas::QuadAAFlags) (SkCanvas::kBottom_QuadAAFlag | SkCanvas::kRight_QuadAAFlag),
+ (SkCanvas::QuadAAFlags) (SkCanvas::kBottom_QuadAAFlag),
+ (SkCanvas::QuadAAFlags) (SkCanvas::kRight_QuadAAFlag),
+ (SkCanvas::QuadAAFlags) (SkCanvas::kRight_QuadAAFlag | SkCanvas::kLeft_QuadAAFlag),
+ (SkCanvas::QuadAAFlags) (SkCanvas::kTop_QuadAAFlag | SkCanvas::kBottom_QuadAAFlag),
+ };
+
+ SkColor color = SK_ColorGREEN;
+ for (auto aaFlags : flags) {
+ canvas->save();
+ canvas->concat(ctm);
+ canvas->experimental_DrawEdgeAAQuad(bounds, pts, aaFlags, color, SkBlendMode::kSrcOver);
+ SkColor rgb = color & 0x00FFFFFF;
+ color = 0xFF000000 | (rgb << 4) | (rgb >> 20);
+ canvas->restore();
+ canvas->translate(0, 25);
+ }
+}
+
diff --git a/gn/gm.gni b/gn/gm.gni
index 4ae72fb407084cb13d187ea6e4d0493e1dd4ea95..5ff5cd845765777508949ae24634292d0e6c0f67 100644
--- a/gn/gm.gni
+++ b/gn/gm.gni
@@ -107,6 +107,7 @@ gm_sources = [
"$_gm/copy_to_4444.cpp",
"$_gm/crbug_1041204.cpp",
"$_gm/crbug_1073670.cpp",
+ "$_gm/crbug_1162942.cpp",
"$_gm/crbug_224618.cpp",
"$_gm/crbug_691386.cpp",
"$_gm/crbug_788500.cpp",
diff --git a/src/gpu/geometry/GrQuadUtils.cpp b/src/gpu/geometry/GrQuadUtils.cpp
index 9650758a87695bec8df342d7d645bf7e71301e23..95442e3f678df42c3b5584c78985aa0df151668e 100644
--- a/src/gpu/geometry/GrQuadUtils.cpp
+++ b/src/gpu/geometry/GrQuadUtils.cpp
@@ -717,7 +717,10 @@ V4f TessellationHelper::EdgeEquations::estimateCoverage(const V4f& x2d, const V4
}
int TessellationHelper::EdgeEquations::computeDegenerateQuad(const V4f& signedEdgeDistances,
- V4f* x2d, V4f* y2d) const {
+ V4f* x2d, V4f* y2d,
+ M4f* aaMask) const {
+ *aaMask = signedEdgeDistances != 0.f;
+
// Move the edge by the signed edge adjustment.
V4f oc = fC + signedEdgeDistances;
@@ -792,10 +795,19 @@ int TessellationHelper::EdgeEquations::computeDegenerateQuad(const V4f& signedEd
if (SkScalarAbs(eDenom[0]) > kTolerance) {
px = if_then_else(d1v0, V4f(ex[0]), px);
py = if_then_else(d1v0, V4f(ey[0]), py);
+ // If we replace a vertex with an intersection then it will not fall along the
+ // edges that intersect at the original vertex. When we apply AA later to the
+ // original points we move along the original 3d edges to move towards the 2d
+ // points we're computing here. If we have an AA edge and a non-AA edge we
+ // can only move along 1 edge, but now the point we're moving toward isn't
+ // on that edge. Thus, we provide an additional degree of freedom by turning
+ // AA on for both edges if either edge is AA.
+ *aaMask = *aaMask | (d1v0 & skvx::shuffle<2, 0, 3, 1>(*aaMask));
}
if (SkScalarAbs(eDenom[1]) > kTolerance) {
px = if_then_else(d2v0, V4f(ex[1]), px);
py = if_then_else(d2v0, V4f(ey[1]), py);
+ *aaMask = *aaMask | (d2v0 & skvx::shuffle<2, 0, 3, 1>(*aaMask));
}
*x2d = px;
@@ -1156,9 +1168,11 @@ int TessellationHelper::adjustDegenerateVertices(const skvx::Vec<4, float>& sign
// handles perspective).
V4f x2d = fEdgeVectors.fX2D;
V4f y2d = fEdgeVectors.fY2D;
+
+ M4f aaMask;
int vertexCount = this->getEdgeEquations().computeDegenerateQuad(signedEdgeDistances,
- &x2d, &y2d);
- vertices->moveTo(x2d, y2d, signedEdgeDistances != 0.f);
+ &x2d, &y2d, &aaMask);
+ vertices->moveTo(x2d, y2d, aaMask);
return vertexCount;
}
}
diff --git a/src/gpu/geometry/GrQuadUtils.h b/src/gpu/geometry/GrQuadUtils.h
index dbbc4626e5cfb16db0e832e47477132f410ff13b..50b647bdb9c0efbf6faf8002f706b24ad0f0a2e3 100644
--- a/src/gpu/geometry/GrQuadUtils.h
+++ b/src/gpu/geometry/GrQuadUtils.h
@@ -111,7 +111,8 @@ namespace GrQuadUtils {
// small, edges are near parallel, or edges are very short/zero-length. Returns number
// of effective vertices in the degenerate quad.
int computeDegenerateQuad(const skvx::Vec<4, float>& signedEdgeDistances,
- skvx::Vec<4, float>* x2d, skvx::Vec<4, float>* y2d) const;
+ skvx::Vec<4, float>* x2d, skvx::Vec<4, float>* y2d,
+ skvx::Vec<4, int32_t>* aaMask) const;
};
struct OutsetRequest {

View File

@@ -0,0 +1,199 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ben Wagner <bungeman@google.com>
Date: Thu, 1 Apr 2021 15:02:21 -0400
Subject: SkScalerContext::getImage less brittle.
Properly handle edge cases like
* the temporary glyph being a different size than expected
* filters which reduce in size
* filters which return false to indicate no filtering has been done
Bug: chromium:1190525
Change-Id: Ibc53eb1d7014210019e96cd6bae3e256d967be54
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/392156
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Herb Derby <herb@google.com>
(cherry picked from commit 348ee387a96d7d94733d46ad9e82b19cb890dd16)
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/392437
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index a2df87c3ef62790353b8fac8169d83bc657db3d4..d1cb80a631814e995c756dc23764a21b00e97270 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -534,41 +534,39 @@ static void generateMask(const SkMask& mask, const SkPath& path,
}
void SkScalerContext::getImage(const SkGlyph& origGlyph) {
- const SkGlyph* glyph = &origGlyph;
+ const SkGlyph* unfilteredGlyph = &origGlyph;
SkGlyph tmpGlyph{origGlyph.getPackedID()};
// in case we need to call generateImage on a mask-format that is different
// (i.e. larger) than what our caller allocated by looking at origGlyph.
SkAutoMalloc tmpGlyphImageStorage;
- if (fMaskFilter) { // restore the prefilter bounds
-
+ if (fMaskFilter) {
// need the original bounds, sans our maskfilter
sk_sp<SkMaskFilter> mf = std::move(fMaskFilter);
this->getMetrics(&tmpGlyph);
fMaskFilter = std::move(mf);
- // we need the prefilter bounds to be <= filter bounds
- SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth);
- SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight);
-
- if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat) {
+ // Use the origGlyph storage for the temporary unfiltered mask if it will fit.
+ if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat &&
+ tmpGlyph.imageSize() <= origGlyph.imageSize())
+ {
tmpGlyph.fImage = origGlyph.fImage;
} else {
tmpGlyphImageStorage.reset(tmpGlyph.imageSize());
tmpGlyph.fImage = tmpGlyphImageStorage.get();
}
- glyph = &tmpGlyph;
+ unfilteredGlyph = &tmpGlyph;
}
if (!fGenerateImageFromPath) {
- generateImage(*glyph);
+ generateImage(*unfilteredGlyph);
} else {
SkPath devPath;
- SkMask mask = glyph->mask();
+ SkMask mask = unfilteredGlyph->mask();
- if (!this->internalGetPath(glyph->getPackedID(), &devPath)) {
- generateImage(*glyph);
+ if (!this->internalGetPath(unfilteredGlyph->getPackedID(), &devPath)) {
+ generateImage(*unfilteredGlyph);
} else {
SkASSERT(SkMask::kARGB32_Format != origGlyph.fMaskFormat);
SkASSERT(SkMask::kARGB32_Format != mask.fFormat);
@@ -579,39 +577,98 @@ void SkScalerContext::getImage(const SkGlyph& origGlyph) {
}
if (fMaskFilter) {
- // the src glyph image shouldn't be 3D
- SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat);
+ // k3D_Format should not be mask filtered.
+ SkASSERT(SkMask::k3D_Format != unfilteredGlyph->fMaskFormat);
+
+ SkMask filteredMask;
+ SkMask srcMask;
+ SkMatrix m;
+ fRec.getMatrixFrom2x2(&m);
+
+ if (as_MFB(fMaskFilter)->filterMask(&filteredMask, unfilteredGlyph->mask(), m, nullptr)) {
+ // Filter succeeded; filteredMask.fImage was allocated.
+ srcMask = filteredMask;
+ } else if (unfilteredGlyph->fImage == tmpGlyphImageStorage.get()) {
+ // Filter did nothing; unfiltered mask is independent of origGlyph.fImage.
+ srcMask = unfilteredGlyph->mask();
+ } else if (origGlyph.iRect() == unfilteredGlyph->iRect()) {
+ // Filter did nothing; the unfiltered mask is in origGlyph.fImage and matches.
+ return;
+ } else {
+ // Filter did nothing; the unfiltered mask is in origGlyph.fImage and conflicts.
+ srcMask = unfilteredGlyph->mask();
+ size_t imageSize = unfilteredGlyph->imageSize();
+ tmpGlyphImageStorage.reset(imageSize);
+ srcMask.fImage = static_cast<uint8_t*>(tmpGlyphImageStorage.get());
+ memcpy(srcMask.fImage, unfilteredGlyph->fImage, imageSize);
+ }
- SkMask srcM = glyph->mask(),
- dstM;
- SkMatrix matrix;
+ SkASSERT_RELEASE(srcMask.fFormat == origGlyph.fMaskFormat);
+ SkMask dstMask = origGlyph.mask();
+ SkIRect origBounds = dstMask.fBounds;
- fRec.getMatrixFrom2x2(&matrix);
+ // Find the intersection of src and dst while updating the fImages.
+ if (srcMask.fBounds.fTop < dstMask.fBounds.fTop) {
+ int32_t topDiff = dstMask.fBounds.fTop - srcMask.fBounds.fTop;
+ srcMask.fImage += srcMask.fRowBytes * topDiff;
+ srcMask.fBounds.fTop = dstMask.fBounds.fTop;
+ }
+ if (dstMask.fBounds.fTop < srcMask.fBounds.fTop) {
+ int32_t topDiff = srcMask.fBounds.fTop - dstMask.fBounds.fTop;
+ dstMask.fImage += dstMask.fRowBytes * topDiff;
+ dstMask.fBounds.fTop = srcMask.fBounds.fTop;
+ }
- if (as_MFB(fMaskFilter)->filterMask(&dstM, srcM, matrix, nullptr)) {
- int width = std::min<int>(origGlyph.fWidth, dstM.fBounds.width());
- int height = std::min<int>(origGlyph.fHeight, dstM.fBounds.height());
- int dstRB = origGlyph.rowBytes();
- int srcRB = dstM.fRowBytes;
+ if (srcMask.fBounds.fLeft < dstMask.fBounds.fLeft) {
+ int32_t leftDiff = dstMask.fBounds.fLeft - srcMask.fBounds.fLeft;
+ srcMask.fImage += leftDiff;
+ srcMask.fBounds.fLeft = dstMask.fBounds.fLeft;
+ }
+ if (dstMask.fBounds.fLeft < srcMask.fBounds.fLeft) {
+ int32_t leftDiff = srcMask.fBounds.fLeft - dstMask.fBounds.fLeft;
+ dstMask.fImage += leftDiff;
+ dstMask.fBounds.fLeft = srcMask.fBounds.fLeft;
+ }
- const uint8_t* src = (const uint8_t*)dstM.fImage;
- uint8_t* dst = (uint8_t*)origGlyph.fImage;
+ if (srcMask.fBounds.fBottom < dstMask.fBounds.fBottom) {
+ dstMask.fBounds.fBottom = srcMask.fBounds.fBottom;
+ }
+ if (dstMask.fBounds.fBottom < srcMask.fBounds.fBottom) {
+ srcMask.fBounds.fBottom = dstMask.fBounds.fBottom;
+ }
- if (SkMask::k3D_Format == dstM.fFormat) {
- // we have to copy 3 times as much
- height *= 3;
- }
+ if (srcMask.fBounds.fRight < dstMask.fBounds.fRight) {
+ dstMask.fBounds.fRight = srcMask.fBounds.fRight;
+ }
+ if (dstMask.fBounds.fRight < srcMask.fBounds.fRight) {
+ srcMask.fBounds.fRight = dstMask.fBounds.fRight;
+ }
- // clean out our glyph, since it may be larger than dstM
- //sk_bzero(dst, height * dstRB);
+ SkASSERT(srcMask.fBounds == dstMask.fBounds);
+ int width = srcMask.fBounds.width();
+ int height = srcMask.fBounds.height();
+ int dstRB = dstMask.fRowBytes;
+ int srcRB = srcMask.fRowBytes;
- while (--height >= 0) {
- memcpy(dst, src, width);
- src += srcRB;
- dst += dstRB;
- }
- SkMask::FreeImage(dstM.fImage);
+ const uint8_t* src = srcMask.fImage;
+ uint8_t* dst = dstMask.fImage;
+
+ if (SkMask::k3D_Format == filteredMask.fFormat) {
+ // we have to copy 3 times as much
+ height *= 3;
+ }
+
+ // If not filling the full original glyph, clear it out first.
+ if (dstMask.fBounds != origBounds) {
+ sk_bzero(origGlyph.fImage, origGlyph.fHeight * origGlyph.rowBytes());
+ }
+
+ while (--height >= 0) {
+ memcpy(dst, src, width);
+ src += srcRB;
+ dst += dstRB;
}
+ SkMask::FreeImage(filteredMask.fImage);
}
}

View File

@@ -1 +1,4 @@
fix_a_use-after-free_bug_for_the_userland_stack.patch
cherry_picking_improve_the_input_validation_and_processing_of.patch
cherry_picking_clean_up_more_resources_of_an_existing_sctp.patch
cherry_picking_harden_the_handling_of_outgoing_streams.patch

View File

@@ -0,0 +1,104 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Tuexen <tuexen@fh-muenster.de>
Date: Sat, 12 Dec 2020 23:30:59 +0100
Subject: Cherry picking: Clean up more resouces of an existing SCTP
association in case of a restart.
This fixes a use-after-free scenario, which was reported by Felix
Wilhelm from Google in case a peer is able to modify the cookie.
However, this can also be triggered by an assciation restart under
some specific conditions.
diff --git a/usrsctplib/netinet/sctp_input.c b/usrsctplib/netinet/sctp_input.c
index b8e1259d8cf0c90cf2dcb03a1fd853c11a6abbd3..5f16f85add50796a2f28227d89cc397d01ed10d4 100755
--- a/usrsctplib/netinet/sctp_input.c
+++ b/usrsctplib/netinet/sctp_input.c
@@ -34,7 +34,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 366248 2020-09-29 09:36:06Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 368593 2020-12-12 22:23:45Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -1607,6 +1607,11 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
struct sctp_association *asoc;
struct sctp_init_chunk *init_cp, init_buf;
struct sctp_init_ack_chunk *initack_cp, initack_buf;
+ struct sctp_asconf_addr *aparam, *naparam;
+ struct sctp_asconf_ack *aack, *naack;
+ struct sctp_tmit_chunk *chk, *nchk;
+ struct sctp_stream_reset_list *strrst, *nstrrst;
+ struct sctp_queued_to_read *sq, *nsq;
struct sctp_nets *net;
struct mbuf *op_err;
struct timeval old;
@@ -1903,8 +1908,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
* kick us so it COULD still take a timeout
* to move these.. but it can't hurt to mark them.
*/
- struct sctp_tmit_chunk *chk;
- TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
+ TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
if (chk->sent < SCTP_DATAGRAM_RESEND) {
chk->sent = SCTP_DATAGRAM_RESEND;
sctp_flight_size_decrease(chk);
@@ -2096,6 +2100,57 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
stcb->asoc.strmout[i].next_mid_unordered = 0;
stcb->asoc.strmout[i].last_msg_incomplete = 0;
}
+ TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
+ TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
+ SCTP_FREE(strrst, SCTP_M_STRESET);
+ }
+ TAILQ_FOREACH_SAFE(sq, &asoc->pending_reply_queue, next, nsq) {
+ TAILQ_REMOVE(&asoc->pending_reply_queue, sq, next);
+ if (sq->data) {
+ sctp_m_freem(sq->data);
+ sq->data = NULL;
+ }
+ sctp_free_remote_addr(sq->whoFrom);
+ sq->whoFrom = NULL;
+ sq->stcb = NULL;
+ sctp_free_a_readq(stcb, sq);
+ }
+ TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) {
+ TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
+ if (chk->data) {
+ sctp_m_freem(chk->data);
+ chk->data = NULL;
+ }
+ if (chk->holds_key_ref)
+ sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
+ sctp_free_remote_addr(chk->whoTo);
+ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
+ SCTP_DECR_CHK_COUNT();
+ }
+ TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) {
+ TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next);
+ if (chk->data) {
+ sctp_m_freem(chk->data);
+ chk->data = NULL;
+ }
+ if (chk->holds_key_ref)
+ sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
+ sctp_free_remote_addr(chk->whoTo);
+ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
+ SCTP_DECR_CHK_COUNT();
+ }
+ TAILQ_FOREACH_SAFE(aparam, &asoc->asconf_queue, next, naparam) {
+ TAILQ_REMOVE(&asoc->asconf_queue, aparam, next);
+ SCTP_FREE(aparam,SCTP_M_ASC_ADDR);
+ }
+ TAILQ_FOREACH_SAFE(aack, &asoc->asconf_ack_sent, next, naack) {
+ TAILQ_REMOVE(&asoc->asconf_ack_sent, aack, next);
+ if (aack->data != NULL) {
+ sctp_m_freem(aack->data);
+ }
+ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), aack);
+ }
+
/* process the INIT-ACK info (my info) */
asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);

View File

@@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Tuexen <tuexen@fh-muenster.de>
Date: Mon, 14 Dec 2020 00:57:51 +0100
Subject: Cherry picking: Harden the handling of outgoing streams in case of an
restart or INIT collision.
This avouds an out-of-bounce access in case the peer can
break the cookie signature. Thanks to Felix Wilhelm from Google for
reporting the issue.
diff --git a/usrsctplib/netinet/sctp_input.c b/usrsctplib/netinet/sctp_input.c
index 5f16f85add50796a2f28227d89cc397d01ed10d4..d538c347b967b89d99c7cdaf1fef173107319783 100755
--- a/usrsctplib/netinet/sctp_input.c
+++ b/usrsctplib/netinet/sctp_input.c
@@ -34,7 +34,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 368593 2020-12-12 22:23:45Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 368622 2020-12-13 23:51:51Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -1898,7 +1898,9 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
NULL);
}
asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
- asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
+ if (asoc->pre_open_streams < asoc->streamoutcnt) {
+ asoc->pre_open_streams = asoc->streamoutcnt;
+ }
if (ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) {
/* Ok the peer probably discarded our
@@ -2052,8 +2054,9 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* move to OPEN state, if not in SHUTDOWN_SENT */
SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
}
- asoc->pre_open_streams =
- ntohs(initack_cp->init.num_outbound_streams);
+ if (asoc->pre_open_streams < asoc->streamoutcnt) {
+ asoc->pre_open_streams = asoc->streamoutcnt;
+ }
asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
@@ -2373,7 +2376,6 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
/* process the INIT-ACK info (my info) */
asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
- asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;

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